diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 8d34f4e..50ae33b 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -1120,6 +1120,35 @@ private static void addDeprecatedKeys() { public static final String NM_DEFAULT_DOCKER_CONTAINER_EXECUTOR_EXEC_NAME = "/usr/bin/docker"; + /** Prefix for runtime configuration constants. */ + public static final String LINUX_CONTAINER_RUNTIME_PREFIX = NM_PREFIX + + "runtime.linux."; + public static final String DOCKER_CONTAINER_RUNTIME_PREFIX = + LINUX_CONTAINER_RUNTIME_PREFIX + "docker."; + + /** Capabilities allowed (and added by default) for docker containers. **/ + public static final String NM_DOCKER_CONTAINER_CAPABILITIES = + DOCKER_CONTAINER_RUNTIME_PREFIX + "capabilities"; + + /** These are the default capabilities added by docker. We'll use the same + * set here. + */ + public static final String[] DEFAULT_NM_DOCKER_CONTAINER_CAPABILITIES = + { "CHOWN", + "DAC_OVERRIDE", + "FSETID", + "FOWNER", + "MKNOD", + "NET_RAW", + "SETGID", + "SETUID", + "SETFCAP", + "SETPCAP", + "NET_BIND_SERVICE", + "SYS_CHROOT", + "KILL", + "AUDIT_WRITE" }; + /** The path to the Linux container executor.*/ public static final String NM_LINUX_CONTAINER_EXECUTOR_PATH = NM_PREFIX + "linux-container-executor.path"; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java index 2430a78..2296be3 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/DockerLinuxContainerRuntime.java @@ -27,6 +27,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation; @@ -154,12 +155,16 @@ public void launchContainer(ContainerRuntimeContext ctx) List localDirs = ctx.getExecutionAttribute(LOCAL_DIRS); @SuppressWarnings("unchecked") List logDirs = ctx.getExecutionAttribute(LOG_DIRS); + String[] capabilities = conf.getStrings( + YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES, + YarnConfiguration.DEFAULT_NM_DOCKER_CONTAINER_CAPABILITIES); @SuppressWarnings("unchecked") DockerRunCommand runCommand = new DockerRunCommand(containerIdStr, runAsUser, imageName) .detachOnRun() .setContainerWorkDir(containerWorkDir.toString()) .setNetworkType("host") + .setCapabilities(capabilities) .addMountLocation("/etc/passwd", "/etc/password:ro"); List allDirs = new ArrayList<>(localDirs); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerRunCommand.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerRunCommand.java index f9a890e..2f1351f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerRunCommand.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/docker/DockerRunCommand.java @@ -68,6 +68,17 @@ public DockerRunCommand setCGroupParent(String parentPath) { return this; } + public DockerRunCommand setCapabilities(String[] capabilties) { + //first, drop all capabilities + super.addCommandArguments("--cap-drop=ALL"); + + //now, add the capabilities supplied + for (String capability : capabilties) { + super.addCommandArguments("--cap-add=" + capability); + } + + return this; + } public DockerRunCommand addDevice(String sourceDevice, String destinationDevice) { super.addCommandArguments("--device=" + sourceDevice + ":" + diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java index 31ed496..e7d3fe5 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/runtime/TestDockerContainerRuntime.java @@ -24,6 +24,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerLaunchContext; +import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.nodemanager.LocalDirsHandlerService; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation; @@ -154,6 +155,12 @@ public void testDockerContainerLaunch() .setExecutionAttribute(LOG_DIRS, logDirs) .setExecutionAttribute(RESOURCES_OPTIONS, resourcesOptions); + String [] testCapabilities = {"NET_BIND_SERVICE", "SYS_CHROOT"}; + String expectedCapabilitiesString = + "--cap-drop=ALL --cap-add=NET_BIND_SERVICE --cap-add=SYS_CHROOT "; + conf.setStrings(YarnConfiguration.NM_DOCKER_CONTAINER_CAPABILITIES, + testCapabilities); + runtime.launchContainer(builder.build()); ArgumentCaptor opCaptor = ArgumentCaptor.forClass( @@ -199,7 +206,9 @@ public void testDockerContainerLaunch() StringBuffer expectedCommandTemplate = new StringBuffer("run --name=%1$s ") .append("--user=%2$s -d ") .append("--workdir=%3$s ") - .append("--net=host -v /etc/passwd:/etc/password:ro ") + .append("--net=host ") + .append(expectedCapabilitiesString) + .append("-v /etc/passwd:/etc/password:ro ") .append("-v %4$s:%4$s ") .append("-v %5$s:%5$s ") .append("-v %6$s:%6$s ")