use of org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand in project hadoop by apache.
the class DockerLinuxContainerRuntime method launchContainer.
@Override
public void launchContainer(ContainerRuntimeContext ctx) throws ContainerExecutionException {
Container container = ctx.getContainer();
Map<String, String> environment = container.getLaunchContext().getEnvironment();
String imageName = environment.get(ENV_DOCKER_CONTAINER_IMAGE);
String network = environment.get(ENV_DOCKER_CONTAINER_NETWORK);
if (network == null || network.isEmpty()) {
network = defaultNetwork;
}
validateContainerNetworkType(network);
if (imageName == null) {
throw new ContainerExecutionException(ENV_DOCKER_CONTAINER_IMAGE + " not set!");
}
String containerIdStr = container.getContainerId().toString();
String runAsUser = ctx.getExecutionAttribute(RUN_AS_USER);
Path containerWorkDir = ctx.getExecutionAttribute(CONTAINER_WORK_DIR);
//List<String> -> stored as List -> fetched/converted to List<String>
//we can't do better here thanks to type-erasure
@SuppressWarnings("unchecked") List<String> localDirs = ctx.getExecutionAttribute(LOCAL_DIRS);
@SuppressWarnings("unchecked") List<String> logDirs = ctx.getExecutionAttribute(LOG_DIRS);
@SuppressWarnings("unchecked") List<String> filecacheDirs = ctx.getExecutionAttribute(FILECACHE_DIRS);
@SuppressWarnings("unchecked") List<String> containerLocalDirs = ctx.getExecutionAttribute(CONTAINER_LOCAL_DIRS);
@SuppressWarnings("unchecked") List<String> containerLogDirs = ctx.getExecutionAttribute(CONTAINER_LOG_DIRS);
@SuppressWarnings("unchecked") Map<Path, List<String>> localizedResources = ctx.getExecutionAttribute(LOCALIZED_RESOURCES);
@SuppressWarnings("unchecked") 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") DockerRunCommand runCommand = new DockerRunCommand(containerIdStr, runAsUser, imageName).detachOnRun().setContainerWorkDir(containerWorkDir.toString()).setNetworkType(network).setCapabilities(capabilities).addMountLocation(CGROUPS_ROOT_DIRECTORY, CGROUPS_ROOT_DIRECTORY + ":ro", false);
List<String> allDirs = new ArrayList<>(containerLocalDirs);
allDirs.addAll(filecacheDirs);
allDirs.add(containerWorkDir.toString());
allDirs.addAll(containerLogDirs);
allDirs.addAll(userLocalDirs);
for (String dir : allDirs) {
runCommand.addMountLocation(dir, dir, true);
}
if (environment.containsKey(ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS)) {
String mounts = environment.get(ENV_DOCKER_CONTAINER_LOCAL_RESOURCE_MOUNTS);
if (!mounts.isEmpty()) {
for (String mount : StringUtils.split(mounts)) {
String[] dir = StringUtils.split(mount, ':');
if (dir.length != 2) {
throw new ContainerExecutionException("Invalid mount : " + mount);
}
String src = validateMount(dir[0], localizedResources);
String dst = dir[1];
runCommand.addMountLocation(src, dst + ":ro", true);
}
}
}
if (allowPrivilegedContainerExecution(container)) {
runCommand.setPrivileged();
}
String resourcesOpts = ctx.getExecutionAttribute(RESOURCES_OPTIONS);
addCGroupParentIfRequired(resourcesOpts, containerIdStr, runCommand);
Path nmPrivateContainerScriptPath = ctx.getExecutionAttribute(NM_PRIVATE_CONTAINER_SCRIPT_PATH);
String disableOverride = environment.get(ENV_DOCKER_CONTAINER_RUN_OVERRIDE_DISABLE);
if (disableOverride != null && disableOverride.equals("true")) {
if (LOG.isInfoEnabled()) {
LOG.info("command override disabled");
}
} else {
List<String> overrideCommands = new ArrayList<>();
Path launchDst = new Path(containerWorkDir, ContainerLaunch.CONTAINER_SCRIPT);
overrideCommands.add("bash");
overrideCommands.add(launchDst.toUri().getPath());
runCommand.setOverrideCommandWithArgs(overrideCommands);
}
String commandFile = dockerClient.writeCommandToTempFile(runCommand, containerIdStr);
PrivilegedOperation launchOp = new PrivilegedOperation(PrivilegedOperation.OperationType.LAUNCH_DOCKER_CONTAINER);
launchOp.appendArgs(runAsUser, ctx.getExecutionAttribute(USER), Integer.toString(PrivilegedOperation.RunAsUserCommand.LAUNCH_DOCKER_CONTAINER.getValue()), ctx.getExecutionAttribute(APPID), containerIdStr, containerWorkDir.toString(), nmPrivateContainerScriptPath.toUri().getPath(), ctx.getExecutionAttribute(NM_PRIVATE_TOKENS_PATH).toUri().getPath(), ctx.getExecutionAttribute(PID_FILE_PATH).toString(), StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR, localDirs), StringUtils.join(PrivilegedOperation.LINUX_FILE_PATH_SEPARATOR, logDirs), commandFile, resourcesOpts);
String tcCommandFile = ctx.getExecutionAttribute(TC_COMMAND_FILE);
if (tcCommandFile != null) {
launchOp.appendArgs(tcCommandFile);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Launching container with cmd: " + runCommand.getCommandWithArguments());
}
try {
privilegedOperationExecutor.executePrivilegedOperation(null, launchOp, null, container.getLaunchContext().getEnvironment(), false, false);
} catch (PrivilegedOperationException e) {
LOG.warn("Launch container failed. Exception: ", e);
LOG.info("Docker command used: " + runCommand.getCommandWithArguments());
throw new ContainerExecutionException("Launch container failed", e.getExitCode(), e.getOutput(), e.getErrorOutput());
}
}
use of org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand in project hadoop by apache.
the class TestDockerContainerRuntime method testCGroupParent.
@Test
public void testCGroupParent() throws ContainerExecutionException {
String hierarchy = "hadoop-yarn-test";
conf.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_HIERARCHY, hierarchy);
DockerLinuxContainerRuntime runtime = new DockerLinuxContainerRuntime(mockExecutor, mockCGroupsHandler);
runtime.initialize(conf);
String resourceOptionsNone = "cgroups=none";
DockerRunCommand command = Mockito.mock(DockerRunCommand.class);
Mockito.when(mockCGroupsHandler.getRelativePathForCGroup(containerId)).thenReturn(hierarchy + "/" + containerIdStr);
runtime.addCGroupParentIfRequired(resourceOptionsNone, containerIdStr, command);
//no --cgroup-parent should be added here
Mockito.verifyZeroInteractions(command);
String resourceOptionsCpu = "/sys/fs/cgroup/cpu/" + hierarchy + containerIdStr;
runtime.addCGroupParentIfRequired(resourceOptionsCpu, containerIdStr, command);
//--cgroup-parent should be added for the containerId in question
String expectedPath = "/" + hierarchy + "/" + containerIdStr;
Mockito.verify(command).setCGroupParent(expectedPath);
//create a runtime with a 'null' cgroups handler - i.e no
// cgroup-based resource handlers are in use.
runtime = new DockerLinuxContainerRuntime(mockExecutor, null);
runtime.initialize(conf);
runtime.addCGroupParentIfRequired(resourceOptionsNone, containerIdStr, command);
runtime.addCGroupParentIfRequired(resourceOptionsCpu, containerIdStr, command);
//no --cgroup-parent should be added in either case
Mockito.verifyZeroInteractions(command);
}
Aggregations