YARN-7286. Add support for docker to have no capabilities. Contributed by Eric Badger

(cherry picked from commit b7dee1f060)
(cherry picked from commit 6ad6882343)
This commit is contained in:
Jason Lowe 2017-11-02 09:50:55 -05:00
parent da6ea5c144
commit cfef479b73
3 changed files with 71 additions and 5 deletions

View File

@ -1618,7 +1618,8 @@
<description>This configuration setting determines the capabilities <description>This configuration setting determines the capabilities
assigned to docker containers when they are launched. While these may not assigned to docker containers when they are launched. While these may not
be case-sensitive from a docker perspective, it is best to keep these be case-sensitive from a docker perspective, it is best to keep these
uppercase.</description> uppercase. To run without any capabilites, set this value to
"none" or "NONE"</description>
<name>yarn.nodemanager.runtime.linux.docker.capabilities</name> <name>yarn.nodemanager.runtime.linux.docker.capabilities</name>
<value>CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE</value> <value>CHOWN,DAC_OVERRIDE,FSETID,FOWNER,MKNOD,NET_RAW,SETGID,SETUID,SETFCAP,SETPCAP,NET_BIND_SERVICE,SYS_CHROOT,KILL,AUDIT_WRITE</value>
</property> </property>

View File

@ -54,6 +54,7 @@ import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -182,6 +183,7 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
private boolean enableUserReMapping; private boolean enableUserReMapping;
private int userRemappingUidThreshold; private int userRemappingUidThreshold;
private int userRemappingGidThreshold; private int userRemappingGidThreshold;
private Set<String> capabilities;
/** /**
* Return whether the given environment variables indicate that the operation * Return whether the given environment variables indicate that the operation
@ -279,6 +281,30 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
userRemappingGidThreshold = conf.getInt( userRemappingGidThreshold = conf.getInt(
YarnConfiguration.NM_DOCKER_USER_REMAPPING_GID_THRESHOLD, YarnConfiguration.NM_DOCKER_USER_REMAPPING_GID_THRESHOLD,
YarnConfiguration.DEFAULT_NM_DOCKER_USER_REMAPPING_GID_THRESHOLD); YarnConfiguration.DEFAULT_NM_DOCKER_USER_REMAPPING_GID_THRESHOLD);
capabilities = getDockerCapabilitiesFromConf();
}
private Set<String> getDockerCapabilitiesFromConf() throws
ContainerExecutionException {
Set<String> caps = new HashSet<>(Arrays.asList(
conf.getTrimmedStrings(
YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
YarnConfiguration.DEFAULT_NM_DOCKER_CONTAINER_CAPABILITIES)));
if(caps.contains("none") || caps.contains("NONE")) {
if(caps.size() > 1) {
String msg = "Mixing capabilities with the none keyword is" +
" not supported";
throw new ContainerExecutionException(msg);
}
caps = Collections.emptySet();
}
return caps;
}
public Set<String> getCapabilities() {
return capabilities;
} }
@Override @Override
@ -551,10 +577,6 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
LOCALIZED_RESOURCES); LOCALIZED_RESOURCES);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<String> userLocalDirs = ctx.getExecutionAttribute(USER_LOCAL_DIRS); List<String> userLocalDirs = ctx.getExecutionAttribute(USER_LOCAL_DIRS);
Set<String> capabilities = new HashSet<>(Arrays.asList(
conf.getTrimmedStrings(
YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
YarnConfiguration.DEFAULT_NM_DOCKER_CONTAINER_CAPABILITIES)));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
DockerRunCommand runCommand = new DockerRunCommand(containerIdStr, DockerRunCommand runCommand = new DockerRunCommand(containerIdStr,

View File

@ -58,6 +58,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -1150,4 +1151,46 @@ public class TestDockerContainerRuntime {
} }
} }
} }
@Test
public void testDockerCapabilities()
throws ContainerExecutionException, PrivilegedOperationException,
IOException {
DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime(
mockExecutor, mockCGroupsHandler);
try {
conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
"none", "CHOWN", "DAC_OVERRIDE");
runtime.initialize(conf);
Assert.fail("Initialize didn't fail with invalid capabilities " +
"'none', 'CHOWN', 'DAC_OVERRIDE'");
} catch (ContainerExecutionException e) {
}
try {
conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
"CHOWN", "DAC_OVERRIDE", "NONE");
runtime.initialize(conf);
Assert.fail("Initialize didn't fail with invalid capabilities " +
"'CHOWN', 'DAC_OVERRIDE', 'NONE'");
} catch (ContainerExecutionException e) {
}
conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
"NONE");
runtime.initialize(conf);
Assert.assertEquals(0, runtime.getCapabilities().size());
conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
"none");
runtime.initialize(conf);
Assert.assertEquals(0, runtime.getCapabilities().size());
conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES,
"CHOWN", "DAC_OVERRIDE");
runtime.initialize(conf);
Iterator<String> it = runtime.getCapabilities().iterator();
Assert.assertEquals("CHOWN", it.next());
Assert.assertEquals("DAC_OVERRIDE", it.next());
}
} }