You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by eb...@apache.org on 2019/04/15 18:25:52 UTC

[hadoop] branch trunk updated: YARN-9379. Can't specify docker runtime through environment. Contributed by caozhiqiang

This is an automated email from the ASF dual-hosted git repository.

ebadger pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 254efc9  YARN-9379. Can't specify docker runtime through environment. Contributed by caozhiqiang
254efc9 is described below

commit 254efc93588beff6b93fd887ddd43a8e14ea4903
Author: Eric Badger <eb...@verizonmedia.com>
AuthorDate: Mon Apr 15 18:23:49 2019 +0000

    YARN-9379. Can't specify docker runtime through environment. Contributed by caozhiqiang
---
 .../apache/hadoop/yarn/conf/YarnConfiguration.java | 10 +++++
 .../src/main/resources/yarn-default.xml            |  7 +++
 .../linux/runtime/DockerLinuxContainerRuntime.java | 29 +++++++++++++
 .../linux/runtime/TestDockerContainerRuntime.java  | 50 ++++++++++++++++++++++
 4 files changed, 96 insertions(+)

diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
index 34f1e93..860227e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java
@@ -2030,6 +2030,16 @@ public class YarnConfiguration extends Configuration {
   public static final String DEFAULT_NM_DOCKER_DEFAULT_CONTAINER_NETWORK =
       "host";
 
+  /** The set of runtimes allowed when launching containers using the
+   * DockerContainerRuntime. */
+  public static final String NM_DOCKER_ALLOWED_CONTAINER_RUNTIMES =
+          DOCKER_CONTAINER_RUNTIME_PREFIX + "allowed-container-runtimes";
+
+  /** The set of runtimes allowed when launching containers using the
+   * DockerContainerRuntime. */
+  public static final String[] DEFAULT_NM_DOCKER_ALLOWED_CONTAINER_RUNTIMES =
+      {"runc"};
+
   /** Allow host pid namespace for containers. Use with care. */
   public static final String NM_DOCKER_ALLOW_HOST_PID_NAMESPACE =
       DOCKER_CONTAINER_RUNTIME_PREFIX + "host-pid-namespace.allowed";
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
index 004af7c..e865942 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
@@ -1804,6 +1804,13 @@
   </property>
 
   <property>
+    <description>The set of runtimes allowed when launching containers using the
+      DockerContainerRuntime.</description>
+    <name>yarn.nodemanager.runtime.linux.docker.allowed-container-runtimes</name>
+    <value>runc</value>
+  </property>
+
+  <property>
     <description>This configuration setting determines whether the host's PID
       namespace is allowed for docker containers on this cluster.
       Use with care.</description>
diff --git a/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 b/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 384bc5e..85ddca9 100644
--- a/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
+++ b/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
@@ -265,6 +265,9 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
   @InterfaceAudience.Private
   public static final String ENV_DOCKER_CONTAINER_YARN_SYSFS =
       "YARN_CONTAINER_RUNTIME_YARN_SYSFS_ENABLE";
+  @InterfaceAudience.Private
+  public static final String ENV_DOCKER_CONTAINER_DOCKER_RUNTIME =
+      "YARN_CONTAINER_RUNTIME_DOCKER_RUNTIME";
   public static final String YARN_SYSFS_PATH =
       "/hadoop/yarn/sysfs";
   private Configuration conf;
@@ -275,7 +278,9 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
   private String defaultImageName;
   private Boolean defaultImageUpdate;
   private Set<String> allowedNetworks = new HashSet<>();
+  private Set<String> allowedRuntimes = new HashSet<>();
   private String defaultNetwork;
+  private String defaultRuntime;
   private CGroupsHandler cGroupsHandler;
   private AccessControlList privilegedContainersAcl;
   private boolean enableUserReMapping;
@@ -349,6 +354,7 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
     this.conf = conf;
     dockerClient = new DockerClient();
     allowedNetworks.clear();
+    allowedRuntimes.clear();
     defaultROMounts.clear();
     defaultRWMounts.clear();
     defaultTmpfsMounts.clear();
@@ -363,6 +369,10 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
     defaultNetwork = conf.getTrimmed(
         YarnConfiguration.NM_DOCKER_DEFAULT_CONTAINER_NETWORK,
         YarnConfiguration.DEFAULT_NM_DOCKER_DEFAULT_CONTAINER_NETWORK);
+    allowedRuntimes.addAll(Arrays.asList(
+        conf.getTrimmedStrings(
+            YarnConfiguration.NM_DOCKER_ALLOWED_CONTAINER_RUNTIMES,
+            YarnConfiguration.DEFAULT_NM_DOCKER_ALLOWED_CONTAINER_RUNTIMES)));
 
     if(!allowedNetworks.contains(defaultNetwork)) {
       String message = "Default network: " + defaultNetwork
@@ -529,6 +539,19 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
     throw new ContainerExecutionException(msg);
   }
 
+  private void validateContainerRuntimeType(String runtime)
+          throws ContainerExecutionException {
+    if (runtime == null || runtime.isEmpty()
+        || allowedRuntimes.contains(runtime)) {
+      return;
+    }
+
+    String msg = "Disallowed runtime:  '" + runtime
+            + "' specified. Allowed networks: are " + allowedRuntimes
+            .toString();
+    throw new ContainerExecutionException(msg);
+  }
+
   /**
    * Return whether the YARN container is allowed to run using the host's PID
    * namespace for the Docker container. For this to be allowed, the submitting
@@ -801,6 +824,7 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
     String imageName = environment.get(ENV_DOCKER_CONTAINER_IMAGE);
     String network = environment.get(ENV_DOCKER_CONTAINER_NETWORK);
     String hostname = environment.get(ENV_DOCKER_CONTAINER_HOSTNAME);
+    String runtime = environment.get(ENV_DOCKER_CONTAINER_DOCKER_RUNTIME);
     boolean useEntryPoint = checkUseEntryPoint(environment);
 
     if (imageName == null || imageName.isEmpty()) {
@@ -816,6 +840,8 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
 
     validateImageName(imageName);
 
+    validateContainerRuntimeType(runtime);
+
     if (defaultImageUpdate) {
       pullImageFromRemote(containerIdStr, imageName);
     }
@@ -886,6 +912,9 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
     }
 
     runCommand.setCapabilities(capabilities);
+    if (runtime != null && !runtime.isEmpty()) {
+      runCommand.addRuntime(runtime);
+    }
 
     runCommand.addAllReadWriteMountLocations(containerLogDirs);
     runCommand.addAllReadWriteMountLocations(applicationLocalDirs);
diff --git a/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 b/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 6669cac..5d4d22e 100644
--- a/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
+++ b/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
@@ -2481,6 +2481,56 @@ public class TestDockerContainerRuntime {
         dockerCommands.get(counter));
   }
 
+  @Test
+  public void testLaunchContainersWithSpecificDockerRuntime()
+      throws ContainerExecutionException, PrivilegedOperationException,
+      IOException {
+    DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime(
+        mockExecutor, mockCGroupsHandler);
+    runtime.initialize(conf, nmContext);
+
+    env.put(DockerLinuxContainerRuntime
+            .ENV_DOCKER_CONTAINER_DOCKER_RUNTIME, "runc");
+    runtime.launchContainer(builder.build());
+    List<String> dockerCommands = readDockerCommands();
+    Assert.assertEquals(14, dockerCommands.size());
+    Assert.assertEquals("  runtime=runc", dockerCommands.get(11));
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testContainerLaunchWithAllowedRuntimes()
+      throws ContainerExecutionException, IOException,
+      PrivilegedOperationException {
+    DockerLinuxContainerRuntime runtime =
+        new DockerLinuxContainerRuntime(mockExecutor, mockCGroupsHandler);
+    runtime.initialize(conf, nmContext);
+
+    String disallowedRuntime = "runc2";
+
+    try {
+      env.put(DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_DOCKER_RUNTIME,
+          disallowedRuntime);
+      runtime.launchContainer(builder.build());
+      Assert.fail("Runtime was expected to be disallowed: " +
+          disallowedRuntime);
+    } catch (ContainerExecutionException e) {
+      LOG.info("Caught expected exception: " + e);
+    }
+
+    String allowedRuntime = "runc";
+    env.put(DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_DOCKER_RUNTIME,
+        allowedRuntime);
+    //this should cause no failures.
+
+    runtime.launchContainer(builder.build());
+    List<String> dockerCommands = readDockerCommands();
+
+    //This is the expected docker invocation for this case
+    Assert.assertEquals(14, dockerCommands.size());
+    Assert.assertEquals("  runtime=runc", dockerCommands.get(11));
+  }
+
   private static void verifyStopCommand(List<String> dockerCommands,
       String signal) {
     Assert.assertEquals(4, dockerCommands.size());


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org