Support Questions

Find answers, ask questions, and share your expertise
Announcements
Celebrating as our community reaches 100,000 members! Thank you!

How to set user in LinuxContainerExecutor from code

avatar
New Contributor

I have a long running application master that accepts requests (monitors queue). In request i have a field "username" - the user, i want to launch a job on a container from.

As from yarn documentation:

  • The default value set for Apache Hadoop in non-secure clusters is org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor. This class runs all containers as the Yarn user to avoid accidental operations being executed in the NodeManagers by arbitrary users.
  • The alternative value for this property is org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor. This class executes containers with the container-executor binary, which performs a privilege escalation to run containers as the users that submitted the application request.

 

I've changed yarn.nodemanager.container-executor.class to LinuxContainerExecutor. How can i set a user which will be run command on a container? The only method that seems like does authentification is ContainerLaunchContext.setTokens. I have a next code:

 

private def setupTokens(user: String): ByteBuffer = {
        val ugi = UserGroupInformation.createProxyUser(user, UserGroupInformation.getCurrentUser)
        LOG.info(s"Creating proxyuser ${ugi.getUserName} impersonated by ${UserGroupInformation.getCurrentUser}")
        val credentials = ugi.getCredentials
        val dob = new DataOutputBuffer();
        credentials.writeTokenStorageToStream(dob);
        ByteBuffer.wrap(dob.getData(), 0, dob.getLength()).duplicate();
    }
  
    val cCLC = Records.newRecord(classOf[ContainerLaunchContext])
    cCLC.setCommands(List("whoami"))
    cCLC.setTokens(setupTokens(user))

But it doesn't work.

1 ACCEPTED SOLUTION

avatar
Mentor
But it doesn't work.

 

Could you please always clarify on what doesn't work, specifically, along with exact error messages? This statement is vague when you seek help troubleshooting from others.

 

Looking over your code snippet, it seems like you're trying to run a container as a different user than the AM runs as, by trying to influence the token sent along with the ContainerLaunchContext.

 

This isn't gonna work, cause the token the NM looks for (for its true-user-determination) is in the allocated Container object (obtained from the AMRMClient, which you pass onto the NMClient), not from the ContainerLaunchContext (these tokens are for use inside the Container if needed, but not for its launch checks).

 

Since the RM will grant tokens only to the app-ID requesting it (and the true owner thereof), you cannot also run an App with the AM as one user and Containers as another. Is this what you are trying to attempt?

 

If your intention is simpler, i.e. running the containers just as the app (and AM) user, then you only need to configure LinuxContainerExecutor and need no code changes (the framework handles container token handling for NMs). Remember also, if you are using LinuxContainerExecutor without Kerberos auth enabled, then it falls back into a secured state of impersonating only one user 'nobody'. See config 'yarn.nodemanager.linux-container-executor.nonsecure-mode.limit-users' under http://archive.cloudera.com/cdh5/cdh/5/hadoop/hadoop-yarn/hadoop-yarn-common/yarn-default.xml#yarn.n... to switch off this protection.

View solution in original post

3 REPLIES 3

avatar
Mentor
But it doesn't work.

 

Could you please always clarify on what doesn't work, specifically, along with exact error messages? This statement is vague when you seek help troubleshooting from others.

 

Looking over your code snippet, it seems like you're trying to run a container as a different user than the AM runs as, by trying to influence the token sent along with the ContainerLaunchContext.

 

This isn't gonna work, cause the token the NM looks for (for its true-user-determination) is in the allocated Container object (obtained from the AMRMClient, which you pass onto the NMClient), not from the ContainerLaunchContext (these tokens are for use inside the Container if needed, but not for its launch checks).

 

Since the RM will grant tokens only to the app-ID requesting it (and the true owner thereof), you cannot also run an App with the AM as one user and Containers as another. Is this what you are trying to attempt?

 

If your intention is simpler, i.e. running the containers just as the app (and AM) user, then you only need to configure LinuxContainerExecutor and need no code changes (the framework handles container token handling for NMs). Remember also, if you are using LinuxContainerExecutor without Kerberos auth enabled, then it falls back into a secured state of impersonating only one user 'nobody'. See config 'yarn.nodemanager.linux-container-executor.nonsecure-mode.limit-users' under http://archive.cloudera.com/cdh5/cdh/5/hadoop/hadoop-yarn/hadoop-yarn-common/yarn-default.xml#yarn.n... to switch off this protection.

avatar
New Contributor

Yes i would like to run an AM under user that could impersonate other users. When on AM i got a request i want to run a command on a container as a user that sent a request (assuming it could be impersonated). E.g. AM is running as a user1 user. He could impersonate user2. AM got a request:

{"user": "user2",
"command" : "whoami"}

And it should be run as user2.

avatar
Mentor
The only way I can think of to do that is to spawn a whole new application, impersonating the user, from within your AM. That may work, although I've never tried it.