ソースを参照

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

(cherry picked from commit d00b6f7c1ff2d7569ae9efdc6823ebcfb86ef2d4)

Conflicts:
	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
Jason Lowe 7 年 前
コミット
b7dee1f060

+ 2 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml

@@ -1607,7 +1607,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>

+ 26 - 4
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

@@ -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,

+ 43 - 0
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

@@ -57,6 +57,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;
@@ -1148,4 +1149,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());
+  }
 }
 }