Search in sources :

Example 1 with PrefixLogger

use of com.yahoo.vespa.hosted.node.admin.util.PrefixLogger in project vespa by vespa-engine.

the class DockerOperationsImpl method startContainer.

@Override
public void startContainer(ContainerName containerName, final ContainerNodeSpec nodeSpec) {
    PrefixLogger logger = PrefixLogger.getNodeAgentLogger(DockerOperationsImpl.class, containerName);
    logger.info("Starting container " + containerName);
    try {
        InetAddress nodeInetAddress = environment.getInetAddressForHost(nodeSpec.hostname);
        boolean isIPv6 = nodeInetAddress instanceof Inet6Address;
        if (isIPv6) {
            if (!docker.networkNPTed()) {
                docker.connectContainerToNetwork(containerName, "bridge");
            }
            docker.startContainer(containerName);
            setupContainerNetworkConnectivity(containerName);
        } else {
            docker.startContainer(containerName);
        }
        directoriesToMount.entrySet().stream().filter(Map.Entry::getValue).map(Map.Entry::getKey).forEach(path -> docker.executeInContainerAsRoot(containerName, "chmod", "-R", "a+w", path.toString()));
    } catch (IOException e) {
        throw new RuntimeException("Failed to start container " + containerName.asString(), e);
    }
}
Also used : Inet6Address(java.net.Inet6Address) IOException(java.io.IOException) InetAddress(java.net.InetAddress) HashMap(java.util.HashMap) Map(java.util.Map) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)

Example 2 with PrefixLogger

use of com.yahoo.vespa.hosted.node.admin.util.PrefixLogger in project vespa by vespa-engine.

the class DockerOperationsImpl method createContainer.

@Override
public void createContainer(ContainerName containerName, final ContainerNodeSpec nodeSpec) {
    PrefixLogger logger = PrefixLogger.getNodeAgentLogger(DockerOperationsImpl.class, containerName);
    logger.info("Creating container " + containerName);
    try {
        InetAddress nodeInetAddress = environment.getInetAddressForHost(nodeSpec.hostname);
        String configServers = environment.getConfigServerUris().stream().map(URI::getHost).collect(Collectors.joining(","));
        Docker.CreateContainerCommand command = docker.createContainerCommand(nodeSpec.wantedDockerImage.get(), ContainerResources.from(nodeSpec.minCpuCores, nodeSpec.minMainMemoryAvailableGb), containerName, nodeSpec.hostname).withManagedBy(MANAGER_NAME).withEnvironment("CONFIG_SERVER_ADDRESS", // TODO: Remove when all images support CONTAINER_ENVIRONMENT_SETTINGS
        configServers).withEnvironment("CONTAINER_ENVIRONMENT_SETTINGS", environment.getContainerEnvironmentResolver().createSettings(environment, nodeSpec)).withUlimit("nofile", 262_144, 262_144).withUlimit("nproc", 32_768, 409_600).withUlimit("core", -1, -1).withAddCapability(// Needed for gcore, pstack etc.
        "SYS_PTRACE").withAddCapability(// Needed for perf
        "SYS_ADMIN");
        if (environment.getNodeType() == NodeType.confighost || environment.getNodeType() == NodeType.proxyhost) {
            command.withVolume("/var/lib/sia", "/var/lib/sia");
        }
        if (environment.getNodeType() == NodeType.proxyhost) {
            command.withVolume("/opt/yahoo/share/ssl/certs/", "/opt/yahoo/share/ssl/certs/");
        }
        if (!docker.networkNPTed()) {
            command.withIpAddress(nodeInetAddress);
            command.withNetworkMode(DockerImpl.DOCKER_CUSTOM_MACVLAN_NETWORK_NAME);
            // TODO This is probably not necessary - review later
            command.withVolume("/etc/hosts", "/etc/hosts");
        } else {
            // IPv6 - Assume always valid
            Inet6Address ipV6Address = this.retriever.getIPv6Address(nodeSpec.hostname).orElseThrow(() -> new RuntimeException("Unable to find a valid IPv6 address. Missing an AAAA DNS entry?"));
            InetAddress ipV6Prefix = InetAddress.getByName(IPV6_NPT_PREFIX);
            InetAddress ipV6Local = IPAddresses.prefixTranslate(ipV6Address, ipV6Prefix, 8);
            command.withIpAddress(ipV6Local);
            // IPv4 - Only present for some containers
            Optional<Inet4Address> ipV4Address = this.retriever.getIPv4Address(nodeSpec.hostname);
            if (ipV4Address.isPresent()) {
                InetAddress ipV4Prefix = InetAddress.getByName(IPV4_NPT_PREFIX);
                InetAddress ipV4Local = IPAddresses.prefixTranslate(ipV4Address.get(), ipV4Prefix, 2);
                command.withIpAddress(ipV4Local);
            }
            command.withNetworkMode(DOCKER_CUSTOM_BRIDGE_NETWORK_NAME);
        }
        for (Path pathInNode : directoriesToMount.keySet()) {
            String pathInHost = environment.pathInHostFromPathInNode(containerName, pathInNode).toString();
            command.withVolume(pathInHost, pathInNode.toString());
        }
        // TODO: Enforce disk constraints
        long minMainMemoryAvailableMb = (long) (nodeSpec.minMainMemoryAvailableGb * 1024);
        if (minMainMemoryAvailableMb > 0) {
            // VESPA_TOTAL_MEMORY_MB is used to make any jdisc container think the machine
            // only has this much physical memory (overrides total memory reported by `free -m`).
            command.withEnvironment("VESPA_TOTAL_MEMORY_MB", Long.toString(minMainMemoryAvailableMb));
        }
        logger.info("Creating new container with args: " + command);
        command.create();
        docker.createContainer(command);
    } catch (IOException e) {
        throw new RuntimeException("Failed to create container " + containerName.asString(), e);
    }
}
Also used : Path(java.nio.file.Path) Inet4Address(java.net.Inet4Address) Docker(com.yahoo.vespa.hosted.dockerapi.Docker) Inet6Address(java.net.Inet6Address) IOException(java.io.IOException) InetAddress(java.net.InetAddress) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)

Example 3 with PrefixLogger

use of com.yahoo.vespa.hosted.node.admin.util.PrefixLogger in project vespa by vespa-engine.

the class StorageMaintainer method writeFilebeatConfig.

public void writeFilebeatConfig(ContainerName containerName, ContainerNodeSpec nodeSpec) {
    PrefixLogger logger = PrefixLogger.getNodeAgentLogger(StorageMaintainer.class, containerName);
    try {
        FilebeatConfigProvider filebeatConfigProvider = new FilebeatConfigProvider(environment);
        Optional<String> config = filebeatConfigProvider.getConfig(nodeSpec);
        if (!config.isPresent()) {
            logger.error("Was not able to generate a config for filebeat, ignoring filebeat file creation." + nodeSpec.toString());
            return;
        }
        Path filebeatPath = environment.pathInNodeAdminFromPathInNode(containerName, Paths.get("/etc/filebeat/filebeat.yml"));
        Files.write(filebeatPath, config.get().getBytes());
        logger.info("Wrote filebeat config.");
    } catch (Throwable t) {
        logger.error("Failed writing filebeat config; " + nodeSpec, t);
    }
}
Also used : Path(java.nio.file.Path) FilebeatConfigProvider(com.yahoo.vespa.hosted.node.admin.logging.FilebeatConfigProvider) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)

Example 4 with PrefixLogger

use of com.yahoo.vespa.hosted.node.admin.util.PrefixLogger in project vespa by vespa-engine.

the class DockerOperationsImpl method removeContainer.

@Override
public void removeContainer(final Container existingContainer, ContainerNodeSpec nodeSpec) {
    final ContainerName containerName = existingContainer.name;
    PrefixLogger logger = PrefixLogger.getNodeAgentLogger(DockerOperationsImpl.class, containerName);
    if (existingContainer.state.isRunning()) {
        logger.info("Stopping container " + containerName.asString());
        docker.stopContainer(containerName);
    }
    logger.info("Deleting container " + containerName.asString());
    docker.deleteContainer(containerName);
}
Also used : ContainerName(com.yahoo.vespa.hosted.dockerapi.ContainerName) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)

Example 5 with PrefixLogger

use of com.yahoo.vespa.hosted.node.admin.util.PrefixLogger in project vespa by vespa-engine.

the class DockerOperationsImpl method executeCommandInNetworkNamespace.

@Override
public void executeCommandInNetworkNamespace(ContainerName containerName, String... command) {
    final PrefixLogger logger = PrefixLogger.getNodeAgentLogger(DockerOperationsImpl.class, containerName);
    final Integer containerPid = docker.getContainer(containerName).filter(container -> container.state.isRunning()).map(container -> container.pid).orElseThrow(() -> new RuntimeException("PID not found for container with name: " + containerName.asString()));
    Path procPath = environment.getPathResolver().getPathToRootOfHost().resolve("proc");
    final String[] wrappedCommand = Stream.concat(Stream.of("sudo", "nsenter", String.format("--net=%s/%d/ns/net", procPath, containerPid), "--"), Stream.of(command)).toArray(String[]::new);
    try {
        Pair<Integer, String> result = processExecuter.exec(wrappedCommand);
        if (result.getFirst() != 0) {
            String msg = String.format("Failed to execute %s in network namespace for %s (PID = %d), exit code: %d, output: %s", Arrays.toString(wrappedCommand), containerName.asString(), containerPid, result.getFirst(), result.getSecond());
            logger.error(msg);
            throw new RuntimeException(msg);
        }
    } catch (IOException e) {
        logger.warning(String.format("IOException while executing %s in network namespace for %s (PID = %d)", Arrays.toString(wrappedCommand), containerName.asString(), containerPid), e);
        throw new RuntimeException(e);
    }
}
Also used : Arrays(java.util.Arrays) ContainerName(com.yahoo.vespa.hosted.dockerapi.ContainerName) Environment(com.yahoo.vespa.hosted.node.admin.component.Environment) ProcessResult(com.yahoo.vespa.hosted.dockerapi.ProcessResult) HashMap(java.util.HashMap) DockerNetworkCreator(com.yahoo.vespa.hosted.dockerapi.DockerNetworkCreator) InetAddress(java.net.InetAddress) ProcessExecuter(com.yahoo.system.ProcessExecuter) IPAddresses(com.yahoo.vespa.hosted.node.admin.task.util.network.IPAddresses) Map(java.util.Map) URI(java.net.URI) Path(java.nio.file.Path) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger) NodeType(com.yahoo.config.provision.NodeType) Container(com.yahoo.vespa.hosted.dockerapi.Container) IOException(java.io.IOException) DockerImpl(com.yahoo.vespa.hosted.dockerapi.DockerImpl) Inet4Address(java.net.Inet4Address) Collectors(java.util.stream.Collectors) Pair(com.yahoo.collections.Pair) Inet6Address(java.net.Inet6Address) List(java.util.List) ContainerNodeSpec(com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec) Stream(java.util.stream.Stream) DockerImage(com.yahoo.vespa.hosted.dockerapi.DockerImage) Docker(com.yahoo.vespa.hosted.dockerapi.Docker) Paths(java.nio.file.Paths) Optional(java.util.Optional) ContainerResources(com.yahoo.vespa.hosted.dockerapi.ContainerResources) Collections(java.util.Collections) Path(java.nio.file.Path) IOException(java.io.IOException) PrefixLogger(com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)

Aggregations

PrefixLogger (com.yahoo.vespa.hosted.node.admin.util.PrefixLogger)5 IOException (java.io.IOException)3 Inet6Address (java.net.Inet6Address)3 InetAddress (java.net.InetAddress)3 Path (java.nio.file.Path)3 ContainerName (com.yahoo.vespa.hosted.dockerapi.ContainerName)2 Docker (com.yahoo.vespa.hosted.dockerapi.Docker)2 Inet4Address (java.net.Inet4Address)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Pair (com.yahoo.collections.Pair)1 NodeType (com.yahoo.config.provision.NodeType)1 ProcessExecuter (com.yahoo.system.ProcessExecuter)1 Container (com.yahoo.vespa.hosted.dockerapi.Container)1 ContainerResources (com.yahoo.vespa.hosted.dockerapi.ContainerResources)1 DockerImage (com.yahoo.vespa.hosted.dockerapi.DockerImage)1 DockerImpl (com.yahoo.vespa.hosted.dockerapi.DockerImpl)1 DockerNetworkCreator (com.yahoo.vespa.hosted.dockerapi.DockerNetworkCreator)1 ProcessResult (com.yahoo.vespa.hosted.dockerapi.ProcessResult)1 ContainerNodeSpec (com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec)1