Search in sources :

Example 1 with DockerRunCommand

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());
    }
}
Also used : Path(org.apache.hadoop.fs.Path) DockerRunCommand(org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand) ArrayList(java.util.ArrayList) Container(org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container) ContainerExecutionException(org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException) PrivilegedOperationException(org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationException) AccessControlList(org.apache.hadoop.security.authorize.AccessControlList) ArrayList(java.util.ArrayList) List(java.util.List) PrivilegedOperation(org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation) HashSet(java.util.HashSet)

Example 2 with DockerRunCommand

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);
}
Also used : DockerRunCommand(org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand) Test(org.junit.Test)

Aggregations

DockerRunCommand (org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.runtime.docker.DockerRunCommand)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Path (org.apache.hadoop.fs.Path)1 AccessControlList (org.apache.hadoop.security.authorize.AccessControlList)1 Container (org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container)1 PrivilegedOperation (org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation)1 PrivilegedOperationException (org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationException)1 ContainerExecutionException (org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException)1 Test (org.junit.Test)1