Search in sources :

Example 1 with V1ResourceRequirements

use of io.kubernetes.client.openapi.models.V1ResourceRequirements in project heron by twitter.

the class V1Controller method configureContainerResources.

/**
 * Configures the resources in the <code>container</code> with values in the <code>config</code> taking precedence.
 * @param container The <code>container</code> to be configured.
 * @param configuration The <code>Config</code> object to check if a resource request needs to be set.
 * @param resource User defined resources limits from input.
 * @param isExecutor Flag to indicate configuration for an <code>executor</code> or <code>manager</code>.
 */
@VisibleForTesting
protected void configureContainerResources(final V1Container container, final Config configuration, final Resource resource, boolean isExecutor) {
    if (container.getResources() == null) {
        container.setResources(new V1ResourceRequirements());
    }
    final V1ResourceRequirements resourceRequirements = container.getResources();
    // Collect Limits and Requests from CLI.
    final Map<String, Quantity> limitsCLI = createResourcesRequirement(KubernetesContext.getResourceLimits(configuration, isExecutor));
    final Map<String, Quantity> requestsCLI = createResourcesRequirement(KubernetesContext.getResourceRequests(configuration, isExecutor));
    if (resourceRequirements.getLimits() == null) {
        resourceRequirements.setLimits(new HashMap<>());
    }
    // Set Limits and Resources from CLI <if> available, <else> use Configs. Deduplicate on name
    // with precedence [1] CLI, [2] Config.
    final Map<String, Quantity> limits = resourceRequirements.getLimits();
    final Quantity limitCPU = limitsCLI.getOrDefault(KubernetesConstants.CPU, Quantity.fromString(Double.toString(KubernetesUtils.roundDecimal(resource.getCpu(), 3))));
    final Quantity limitMEMORY = limitsCLI.getOrDefault(KubernetesConstants.MEMORY, Quantity.fromString(KubernetesUtils.Megabytes(resource.getRam())));
    limits.put(KubernetesConstants.MEMORY, limitMEMORY);
    limits.put(KubernetesConstants.CPU, limitCPU);
    // Set the Kubernetes container resource request.
    // Order: [1] CLI, [2] EQUAL_TO_LIMIT, [3] NOT_SET
    KubernetesContext.KubernetesResourceRequestMode requestMode = KubernetesContext.getKubernetesRequestMode(configuration);
    if (!requestsCLI.isEmpty()) {
        if (resourceRequirements.getRequests() == null) {
            resourceRequirements.setRequests(new HashMap<>());
        }
        final Map<String, Quantity> requests = resourceRequirements.getRequests();
        if (requestsCLI.containsKey(KubernetesConstants.MEMORY)) {
            requests.put(KubernetesConstants.MEMORY, requestsCLI.get(KubernetesConstants.MEMORY));
        }
        if (requestsCLI.containsKey(KubernetesConstants.CPU)) {
            requests.put(KubernetesConstants.CPU, requestsCLI.get(KubernetesConstants.CPU));
        }
    } else if (requestMode == KubernetesContext.KubernetesResourceRequestMode.EQUAL_TO_LIMIT) {
        LOG.log(Level.CONFIG, "Setting K8s Request equal to Limit");
        resourceRequirements.setRequests(limits);
    } else {
        LOG.log(Level.CONFIG, "Not setting K8s request because config was NOT_SET");
    }
    container.setResources(resourceRequirements);
}
Also used : Quantity(io.kubernetes.client.custom.Quantity) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with V1ResourceRequirements

use of io.kubernetes.client.openapi.models.V1ResourceRequirements in project twister2 by DSC-SPIDAL.

the class RequestObjectBuilder method constructContainer.

/**
 * construct a container
 */
public static V1Container constructContainer(ComputeResource computeResource, int containerIndex) {
    // construct container and add it to podSpec
    V1Container container = new V1Container();
    String containerName = KubernetesUtils.createContainerName(containerIndex);
    container.setName(containerName);
    String containerImage = KubernetesContext.twister2DockerImageForK8s(config);
    if (containerImage == null) {
        throw new RuntimeException("Container Image name is null. Config parameter: " + "twister2.resource.kubernetes.docker.image can not be null");
    }
    container.setImage(containerImage);
    container.setImagePullPolicy(KubernetesContext.imagePullPolicy(config));
    String startScript = null;
    double cpuPerContainer = computeResource.getCpu();
    int ramPerContainer = computeResource.getRamMegaBytes();
    if (SchedulerContext.usingOpenMPI(config)) {
        startScript = "./init_openmpi.sh";
        cpuPerContainer = cpuPerContainer * computeResource.getWorkersPerPod();
        ramPerContainer = ramPerContainer * computeResource.getWorkersPerPod();
    } else {
        startScript = "./init.sh";
    }
    container.setCommand(Arrays.asList("/bin/bash"));
    container.setArgs(Arrays.asList("-c", startScript));
    V1ResourceRequirements resReq = new V1ResourceRequirements();
    if (KubernetesContext.bindWorkerToCPU(config)) {
        resReq.putLimitsItem("cpu", new Quantity(String.format("%.2f", cpuPerContainer)));
        resReq.putLimitsItem("memory", new Quantity(ramPerContainer + "Mi"));
    } else {
        resReq.putRequestsItem("cpu", new Quantity(String.format("%.2f", cpuPerContainer)));
        resReq.putRequestsItem("memory", new Quantity(ramPerContainer + "Mi"));
    }
    container.setResources(resReq);
    ArrayList<V1VolumeMount> volumeMounts = new ArrayList<>();
    V1VolumeMount memoryVolumeMount = new V1VolumeMount();
    memoryVolumeMount.setName(KubernetesConstants.POD_MEMORY_VOLUME_NAME);
    memoryVolumeMount.setMountPath(KubernetesConstants.POD_MEMORY_VOLUME);
    volumeMounts.add(memoryVolumeMount);
    if (computeResource.getDiskGigaBytes() > 0) {
        V1VolumeMount volatileVolumeMount = new V1VolumeMount();
        volatileVolumeMount.setName(KubernetesConstants.POD_VOLATILE_VOLUME_NAME);
        volatileVolumeMount.setMountPath(KubernetesConstants.POD_VOLATILE_VOLUME);
        volumeMounts.add(volatileVolumeMount);
    }
    if (SchedulerContext.persistentVolumeRequested(config)) {
        V1VolumeMount persVolumeMount = new V1VolumeMount();
        persVolumeMount.setName(KubernetesConstants.PERSISTENT_VOLUME_NAME);
        persVolumeMount.setMountPath(KubernetesConstants.PERSISTENT_VOLUME_MOUNT);
        volumeMounts.add(persVolumeMount);
    }
    // mount Secret object as a volume
    if (SchedulerContext.usingOpenMPI(config)) {
        V1VolumeMount persVolumeMount = new V1VolumeMount();
        persVolumeMount.setName(KubernetesConstants.SECRET_VOLUME_NAME);
        persVolumeMount.setMountPath(KubernetesConstants.SECRET_VOLUME_MOUNT);
        volumeMounts.add(persVolumeMount);
    }
    container.setVolumeMounts(volumeMounts);
    int containerPort = KubernetesContext.workerBasePort(config) + containerIndex * (SchedulerContext.numberOfAdditionalPorts(config) + 1);
    V1ContainerPort port = new V1ContainerPort();
    // currently not used
    port.name("port11");
    port.containerPort(containerPort);
    port.setProtocol(KubernetesContext.workerTransportProtocol(config));
    container.setPorts(Arrays.asList(port));
    int jvmMemory = (int) (computeResource.getRamMegaBytes() * KubernetesContext.jvmMemoryFraction(config));
    container.setEnv(constructEnvironmentVariables(containerName, containerPort, jvmMemory));
    return container;
}
Also used : V1Container(io.kubernetes.client.openapi.models.V1Container) V1ContainerPort(io.kubernetes.client.openapi.models.V1ContainerPort) ArrayList(java.util.ArrayList) Quantity(io.kubernetes.client.custom.Quantity) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) V1VolumeMount(io.kubernetes.client.openapi.models.V1VolumeMount)

Example 3 with V1ResourceRequirements

use of io.kubernetes.client.openapi.models.V1ResourceRequirements in project heron by twitter.

the class V1Controller method createPersistentVolumeClaims.

/**
 * Generates <code>Persistent Volume Claims Templates</code> from a mapping of <code>Volumes</code>
 * to <code>key-value</code> pairs of configuration options and values.
 * @param mapOfOpts <code>Volume</code> to configuration <code>key-value</code> mappings.
 * @return Fully populated list of only dynamically backed <code>Persistent Volume Claims</code>.
 */
@VisibleForTesting
protected List<V1PersistentVolumeClaim> createPersistentVolumeClaims(final Map<String, Map<KubernetesConstants.VolumeConfigKeys, String>> mapOfOpts) {
    List<V1PersistentVolumeClaim> listOfPVCs = new LinkedList<>();
    // Iterate over all the PVC Volumes.
    for (Map.Entry<String, Map<KubernetesConstants.VolumeConfigKeys, String>> pvc : mapOfOpts.entrySet()) {
        // Only create claims for `OnDemand` volumes.
        final String claimName = pvc.getValue().get(KubernetesConstants.VolumeConfigKeys.claimName);
        if (claimName != null && !KubernetesConstants.LABEL_ON_DEMAND.equalsIgnoreCase(claimName)) {
            continue;
        }
        V1PersistentVolumeClaim claim = new V1PersistentVolumeClaimBuilder().withNewMetadata().withName(pvc.getKey()).withLabels(getPersistentVolumeClaimLabels(getTopologyName())).endMetadata().withNewSpec().withStorageClassName("").endSpec().build();
        // Populate PVC options.
        for (Map.Entry<KubernetesConstants.VolumeConfigKeys, String> option : pvc.getValue().entrySet()) {
            String optionValue = option.getValue();
            switch(option.getKey()) {
                case storageClassName:
                    claim.getSpec().setStorageClassName(optionValue);
                    break;
                case sizeLimit:
                    claim.getSpec().setResources(new V1ResourceRequirements().putRequestsItem("storage", new Quantity(optionValue)));
                    break;
                case accessModes:
                    claim.getSpec().setAccessModes(Arrays.asList(optionValue.split(",")));
                    break;
                case volumeMode:
                    claim.getSpec().setVolumeMode(optionValue);
                    break;
                // Valid ignored options not used in a PVC.
                default:
                    break;
            }
        }
        listOfPVCs.add(claim);
    }
    return listOfPVCs;
}
Also used : V1PersistentVolumeClaim(io.kubernetes.client.openapi.models.V1PersistentVolumeClaim) Quantity(io.kubernetes.client.custom.Quantity) Map(java.util.Map) HashMap(java.util.HashMap) V1ConfigMap(io.kubernetes.client.openapi.models.V1ConfigMap) LinkedList(java.util.LinkedList) V1PersistentVolumeClaimBuilder(io.kubernetes.client.openapi.models.V1PersistentVolumeClaimBuilder) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 4 with V1ResourceRequirements

use of io.kubernetes.client.openapi.models.V1ResourceRequirements in project heron by twitter.

the class V1ControllerTest method testConfigureContainerResources.

@Test
public void testConfigureContainerResources() {
    final boolean isExecutor = true;
    final Resource resourceDefault = new Resource(9, ByteAmount.fromMegabytes(19000), ByteAmount.fromMegabytes(99000));
    final Resource resourceCustom = new Resource(4, ByteAmount.fromMegabytes(34000), ByteAmount.fromMegabytes(400000));
    final Quantity defaultRAM = Quantity.fromString(KubernetesUtils.Megabytes(resourceDefault.getRam()));
    final Quantity defaultCPU = Quantity.fromString(Double.toString(KubernetesUtils.roundDecimal(resourceDefault.getCpu(), 3)));
    final Quantity customRAM = Quantity.fromString(KubernetesUtils.Megabytes(resourceCustom.getRam()));
    final Quantity customCPU = Quantity.fromString(Double.toString(KubernetesUtils.roundDecimal(resourceCustom.getCpu(), 3)));
    final Quantity customDisk = Quantity.fromString(KubernetesUtils.Megabytes(resourceCustom.getDisk()));
    final Config configNoLimit = Config.newBuilder().put(KubernetesContext.KUBERNETES_RESOURCE_REQUEST_MODE, "NOT_SET").build();
    final Config configWithLimit = Config.newBuilder().put(KubernetesContext.KUBERNETES_RESOURCE_REQUEST_MODE, "EQUAL_TO_LIMIT").build();
    final V1ResourceRequirements expectDefaultRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, defaultRAM).putLimitsItem(KubernetesConstants.CPU, defaultCPU);
    final V1ResourceRequirements expectCustomRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, defaultRAM).putLimitsItem(KubernetesConstants.CPU, defaultCPU).putLimitsItem("disk", customDisk);
    final V1ResourceRequirements customRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, customRAM).putLimitsItem(KubernetesConstants.CPU, customCPU).putLimitsItem("disk", customDisk);
    // Default. Null resources.
    V1Container containerNull = new V1ContainerBuilder().build();
    v1ControllerWithPodTemplate.configureContainerResources(containerNull, configNoLimit, resourceDefault, isExecutor);
    Assert.assertTrue("Default LIMITS should be set in container with null LIMITS", containerNull.getResources().getLimits().entrySet().containsAll(expectDefaultRequirements.getLimits().entrySet()));
    // Empty resources.
    V1Container containerEmpty = new V1ContainerBuilder().withNewResources().endResources().build();
    v1ControllerWithPodTemplate.configureContainerResources(containerEmpty, configNoLimit, resourceDefault, isExecutor);
    Assert.assertTrue("Default LIMITS should be set in container with empty LIMITS", containerNull.getResources().getLimits().entrySet().containsAll(expectDefaultRequirements.getLimits().entrySet()));
    // Custom resources.
    V1Container containerCustom = new V1ContainerBuilder().withResources(customRequirements).build();
    v1ControllerWithPodTemplate.configureContainerResources(containerCustom, configNoLimit, resourceDefault, isExecutor);
    Assert.assertTrue("Custom LIMITS should be set in container with custom LIMITS", containerCustom.getResources().getLimits().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
    // Custom resources with request.
    V1Container containerRequests = new V1ContainerBuilder().withResources(customRequirements).build();
    v1ControllerWithPodTemplate.configureContainerResources(containerRequests, configWithLimit, resourceDefault, isExecutor);
    Assert.assertTrue("Custom LIMITS should be set in container with custom LIMITS and REQUEST", containerRequests.getResources().getLimits().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
    Assert.assertTrue("Custom REQUEST should be set in container with custom LIMITS and REQUEST", containerRequests.getResources().getRequests().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
}
Also used : V1Container(io.kubernetes.client.openapi.models.V1Container) Config(org.apache.heron.spi.common.Config) Resource(org.apache.heron.spi.packing.Resource) Quantity(io.kubernetes.client.custom.Quantity) V1ContainerBuilder(io.kubernetes.client.openapi.models.V1ContainerBuilder) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) Test(org.junit.Test)

Example 5 with V1ResourceRequirements

use of io.kubernetes.client.openapi.models.V1ResourceRequirements in project twister2 by DSC-SPIDAL.

the class JobMasterRequestObject method constructContainer.

/**
 * construct a container
 */
public static V1Container constructContainer() {
    // construct container and add it to podSpec
    V1Container container = new V1Container();
    container.setName("twister2-job-master-0");
    String containerImage = KubernetesContext.twister2DockerImageForK8s(config);
    if (containerImage == null) {
        throw new RuntimeException("Container Image name is null. Config parameter: " + "twister2.resource.kubernetes.docker.image can not be null");
    }
    container.setImage(containerImage);
    container.setImagePullPolicy(KubernetesContext.imagePullPolicy(config));
    container.setCommand(Arrays.asList("/bin/bash"));
    container.setArgs(Arrays.asList("-c", "./init.sh"));
    int jmRam = JobMasterContext.jobMasterRAM(config) + 128;
    V1ResourceRequirements resReq = new V1ResourceRequirements();
    resReq.putRequestsItem("cpu", new Quantity(JobMasterContext.jobMasterCpu(config) + ""));
    resReq.putRequestsItem("memory", new Quantity(jmRam + "Mi"));
    container.setResources(resReq);
    ArrayList<V1VolumeMount> volumeMounts = new ArrayList<>();
    V1VolumeMount memoryVolumeMount = new V1VolumeMount();
    memoryVolumeMount.setName(KubernetesConstants.POD_MEMORY_VOLUME_NAME);
    memoryVolumeMount.setMountPath(KubernetesConstants.POD_MEMORY_VOLUME);
    volumeMounts.add(memoryVolumeMount);
    if (JobMasterContext.volatileVolumeRequested(config)) {
        V1VolumeMount volatileVolumeMount = new V1VolumeMount();
        volatileVolumeMount.setName(KubernetesConstants.POD_VOLATILE_VOLUME_NAME);
        volatileVolumeMount.setMountPath(KubernetesConstants.POD_VOLATILE_VOLUME);
        volumeMounts.add(volatileVolumeMount);
    }
    if (JobMasterContext.persistentVolumeRequested(config)) {
        V1VolumeMount persVolumeMount = new V1VolumeMount();
        persVolumeMount.setName(KubernetesConstants.PERSISTENT_VOLUME_NAME);
        persVolumeMount.setMountPath(KubernetesConstants.PERSISTENT_VOLUME_MOUNT);
        volumeMounts.add(persVolumeMount);
    }
    container.setVolumeMounts(volumeMounts);
    V1ContainerPort port = new V1ContainerPort();
    port.name("job-master-port");
    port.containerPort(JobMasterContext.jobMasterPort(config));
    port.setProtocol("TCP");
    container.setPorts(Arrays.asList(port));
    container.setEnv(constructEnvironmentVariables(JobMasterContext.jobMasterRAM(config)));
    return container;
}
Also used : V1Container(io.kubernetes.client.openapi.models.V1Container) V1ContainerPort(io.kubernetes.client.openapi.models.V1ContainerPort) ArrayList(java.util.ArrayList) Quantity(io.kubernetes.client.custom.Quantity) IntOrString(io.kubernetes.client.custom.IntOrString) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) V1VolumeMount(io.kubernetes.client.openapi.models.V1VolumeMount)

Aggregations

Quantity (io.kubernetes.client.custom.Quantity)6 V1ResourceRequirements (io.kubernetes.client.openapi.models.V1ResourceRequirements)6 V1Container (io.kubernetes.client.openapi.models.V1Container)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 V1ContainerPort (io.kubernetes.client.openapi.models.V1ContainerPort)2 V1PersistentVolumeClaim (io.kubernetes.client.openapi.models.V1PersistentVolumeClaim)2 V1PersistentVolumeClaimBuilder (io.kubernetes.client.openapi.models.V1PersistentVolumeClaimBuilder)2 V1VolumeMount (io.kubernetes.client.openapi.models.V1VolumeMount)2 ArrayList (java.util.ArrayList)2 IntOrString (io.kubernetes.client.custom.IntOrString)1 V1ConfigMap (io.kubernetes.client.openapi.models.V1ConfigMap)1 V1ContainerBuilder (io.kubernetes.client.openapi.models.V1ContainerBuilder)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 Config (org.apache.heron.spi.common.Config)1 Resource (org.apache.heron.spi.packing.Resource)1 Test (org.junit.Test)1