Skip to content

Commit d45a0b7

Browse files
committed
YARN-8141. Removed YARN_CONTAINER_RUNTIME_DOCKER_LOCAL_RESOURCE_MOUNTS flag.
Contributed by Chandni Singh
1 parent 7f083ed commit d45a0b7

File tree

4 files changed

+28
-65
lines changed
  • hadoop-yarn-project/hadoop-yarn

4 files changed

+28
-65
lines changed

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/containerlaunch/AbstractLauncher.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public class AbstractLauncher {
4646
private static final Logger log =
4747
LoggerFactory.getLogger(AbstractLauncher.class);
4848
public static final String CLASSPATH = "CLASSPATH";
49+
public static final String ENV_DOCKER_CONTAINER_MOUNTS =
50+
"YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS";
4951
/**
5052
* Env vars; set up at final launch stage
5153
*/
@@ -153,17 +155,23 @@ public ContainerLaunchContext completeContainerLaunch() throws IOException {
153155
env.put("YARN_CONTAINER_RUNTIME_DOCKER_RUN_PRIVILEGED_CONTAINER",
154156
"true");
155157
}
156-
StringBuilder sb = new StringBuilder();
157-
for (Entry<String,String> mount : mountPaths.entrySet()) {
158-
if (sb.length() > 0) {
159-
sb.append(",");
158+
if (!mountPaths.isEmpty()) {
159+
StringBuilder sb = new StringBuilder();
160+
if (env.get(ENV_DOCKER_CONTAINER_MOUNTS) != null) {
161+
// user specified mounts in the spec
162+
sb.append(env.get(ENV_DOCKER_CONTAINER_MOUNTS));
160163
}
161-
sb.append(mount.getKey());
162-
sb.append(":");
163-
sb.append(mount.getValue());
164+
for (Entry<String, String> mount : mountPaths.entrySet()) {
165+
if (sb.length() > 0) {
166+
sb.append(",");
167+
}
168+
sb.append(mount.getKey()).append(":");
169+
sb.append(mount.getValue()).append(":ro");
170+
}
171+
env.put(ENV_DOCKER_CONTAINER_MOUNTS, sb.toString());
164172
}
165-
env.put("YARN_CONTAINER_RUNTIME_DOCKER_LOCAL_RESOURCE_MOUNTS", sb.toString());
166-
log.info("yarn docker env var has been set {}", containerLaunchContext.getEnvironment().toString());
173+
log.info("yarn docker env var has been set {}",
174+
containerLaunchContext.getEnvironment().toString());
167175
}
168176

169177
return containerLaunchContext;

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

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,6 @@
153153
* setting it to false.
154154
* </li>
155155
* <li>
156-
* {@code YARN_CONTAINER_RUNTIME_DOCKER_LOCAL_RESOURCE_MOUNTS} adds
157-
* additional volume mounts to the Docker container. The value of the
158-
* environment variable should be a comma-separated list of mounts.
159-
* All such mounts must be given as {@code source:dest}, where the
160-
* source is an absolute path that is not a symlink and that points to a
161-
* localized resource.
162-
* </li>
163-
* <li>
164156
* {@code YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS} allows users to specify
165157
+ additional volume mounts for the Docker container. The value of the
166158
* environment variable should be a comma-separated list of mounts.
@@ -227,9 +219,6 @@ public class DockerLinuxContainerRuntime implements LinuxContainerRuntime {
227219
public static final String ENV_DOCKER_CONTAINER_RUN_ENABLE_USER_REMAPPING =
228220
"YARN_CONTAINER_RUNTIME_DOCKER_RUN_ENABLE_USER_REMAPPING";
229221
@InterfaceAudience.Private
230-
public static final String ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS =
231-
"YARN_CONTAINER_RUNTIME_DOCKER_LOCAL_RESOURCE_MOUNTS";
232-
@InterfaceAudience.Private
233222
public static final String ENV_DOCKER_CONTAINER_MOUNTS =
234223
"YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS";
235224
@InterfaceAudience.Private
@@ -680,8 +669,7 @@ private boolean allowPrivilegedContainerExecution(Container container)
680669
return true;
681670
}
682671

683-
@VisibleForTesting
684-
protected String validateMount(String mount,
672+
private String mountReadOnlyPath(String mount,
685673
Map<Path, List<String>> localizedResources)
686674
throws ContainerExecutionException {
687675
for (Entry<Path, List<String>> resource : localizedResources.entrySet()) {
@@ -817,23 +805,6 @@ public void launchContainer(ContainerRuntimeContext ctx)
817805
runCommand.addAllReadOnlyMountLocations(filecacheDirs);
818806
runCommand.addAllReadOnlyMountLocations(userFilecacheDirs);
819807

820-
if (environment.containsKey(ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS)) {
821-
String mounts = environment.get(
822-
ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS);
823-
if (!mounts.isEmpty()) {
824-
for (String mount : StringUtils.split(mounts)) {
825-
String[] dir = StringUtils.split(mount, ':');
826-
if (dir.length != 2) {
827-
throw new ContainerExecutionException("Invalid mount : " +
828-
mount);
829-
}
830-
String src = validateMount(dir[0], localizedResources);
831-
String dst = dir[1];
832-
runCommand.addReadOnlyMountLocation(src, dst, true);
833-
}
834-
}
835-
}
836-
837808
if (environment.containsKey(ENV_DOCKER_CONTAINER_MOUNTS)) {
838809
Matcher parsedMounts = USER_MOUNT_PATTERN.matcher(
839810
environment.get(ENV_DOCKER_CONTAINER_MOUNTS));
@@ -845,6 +816,10 @@ public void launchContainer(ContainerRuntimeContext ctx)
845816
parsedMounts.reset();
846817
while (parsedMounts.find()) {
847818
String src = parsedMounts.group(1);
819+
java.nio.file.Path srcPath = java.nio.file.Paths.get(src);
820+
if (!srcPath.isAbsolute()) {
821+
src = mountReadOnlyPath(src, localizedResources);
822+
}
848823
String dst = parsedMounts.group(2);
849824
String mode = parsedMounts.group(3);
850825
if (!mode.equals("ro") && !mode.equals("rw")) {

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

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.apache.hadoop.fs.Path;
2727
import org.apache.hadoop.io.DataOutputBuffer;
2828
import org.apache.hadoop.registry.client.api.RegistryConstants;
29-
import org.apache.hadoop.registry.client.binding.RegistryPathUtils;
3029
import org.apache.hadoop.security.Credentials;
3130
import org.apache.hadoop.util.Shell;
3231
import org.apache.hadoop.util.StringUtils;
@@ -1098,7 +1097,7 @@ public void testMountSourceOnly() throws ContainerExecutionException {
10981097
runtime.initialize(conf, nmContext);
10991098

11001099
env.put(
1101-
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS,
1100+
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_MOUNTS,
11021101
"source");
11031102

11041103
try {
@@ -1118,8 +1117,8 @@ public void testMountSourceTarget()
11181117
runtime.initialize(conf, nmContext);
11191118

11201119
env.put(
1121-
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS,
1122-
"test_dir/test_resource_file:test_mount");
1120+
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_MOUNTS,
1121+
"test_dir/test_resource_file:test_mount:ro");
11231122

11241123
runtime.launchContainer(builder.build());
11251124
PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs();
@@ -1164,24 +1163,6 @@ public void testMountSourceTarget()
11641163
dockerCommands.get(counter));
11651164
}
11661165

1167-
@Test
1168-
public void testMountInvalid() throws ContainerExecutionException {
1169-
DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime(
1170-
mockExecutor, mockCGroupsHandler);
1171-
runtime.initialize(conf, nmContext);
1172-
1173-
env.put(
1174-
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS,
1175-
"source:target:other");
1176-
1177-
try {
1178-
runtime.launchContainer(builder.build());
1179-
Assert.fail("Expected a launch container failure due to invalid mount.");
1180-
} catch (ContainerExecutionException e) {
1181-
LOG.info("Caught expected exception : " + e);
1182-
}
1183-
}
1184-
11851166
@Test
11861167
public void testMountMultiple()
11871168
throws ContainerExecutionException, PrivilegedOperationException,
@@ -1191,9 +1172,9 @@ public void testMountMultiple()
11911172
runtime.initialize(conf, nmContext);
11921173

11931174
env.put(
1194-
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS,
1195-
"test_dir/test_resource_file:test_mount1," +
1196-
"test_dir/test_resource_file:test_mount2");
1175+
DockerLinuxContainerRuntime.ENV_DOCKER_CONTAINER_MOUNTS,
1176+
"test_dir/test_resource_file:test_mount1:ro," +
1177+
"test_dir/test_resource_file:test_mount2:ro");
11971178

11981179
runtime.launchContainer(builder.build());
11991180
PrivilegedOperation op = capturePrivilegedOperationAndVerifyArgs();

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/DockerContainers.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ environment variables in the application's environment:
303303
| `YARN_CONTAINER_RUNTIME_DOCKER_CONTAINER_NETWORK` | Sets the network type to be used by the Docker container. It must be a valid value as determined by the yarn.nodemanager.runtime.linux.docker.allowed-container-networks property. |
304304
| `YARN_CONTAINER_RUNTIME_DOCKER_CONTAINER_PID_NAMESPACE` | Controls which PID namespace will be used by the Docker container. By default, each Docker container has its own PID namespace. To share the namespace of the host, the yarn.nodemanager.runtime.linux.docker.host-pid-namespace.allowed property must be set to true. If the host PID namespace is allowed and this environment variable is set to host, the Docker container will share the host's PID namespace. No other value is allowed. |
305305
| `YARN_CONTAINER_RUNTIME_DOCKER_RUN_PRIVILEGED_CONTAINER` | Controls whether the Docker container is a privileged container. In order to use privileged containers, the yarn.nodemanager.runtime.linux.docker.privileged-containers.allowed property must be set to true, and the application owner must appear in the value of the yarn.nodemanager.runtime.linux.docker.privileged-containers.acl property. If this environment variable is set to true, a privileged Docker container will be used if allowed. No other value is allowed, so the environment variable should be left unset rather than setting it to false. |
306-
| `YARN_CONTAINER_RUNTIME_DOCKER_LOCAL_RESOURCE_MOUNTS` | Adds additional volume mounts to the Docker container. The value of the environment variable should be a comma-separated list of mounts. All such mounts must be given as "source:dest", where the source is an absolute path that is not a symlink and that points to a localized resource. Note that as of YARN-5298, localized directories are automatically mounted into the container as volumes. |
307306
| `YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS` | Adds additional volume mounts to the Docker container. The value of the environment variable should be a comma-separated list of mounts. All such mounts must be given as "source:dest:mode" and the mode must be "ro" (read-only) or "rw" (read-write) to specify the type of access being requested. The requested mounts will be validated by container-executor based on the values set in container-executor.cfg for docker.allowed.ro-mounts and docker.allowed.rw-mounts. |
308307
| `YARN_CONTAINER_RUNTIME_DOCKER_DELAYED_REMOVAL` | Allows a user to request delayed deletion of the Docker container on a per container basis. If true, Docker containers will not be removed until the duration defined by yarn.nodemanager.delete.debug-delay-sec has elapsed. Administrators can disable this feature through the yarn-site property yarn.nodemanager.runtime.linux.docker.delayed-removal.allowed. This feature is disabled by default. When this feature is disabled or set to false, the container will be removed as soon as it exits. |
309308

0 commit comments

Comments
 (0)