Search in sources :

Example 1 with PodInfo

use of io.cdap.cdap.master.environment.k8s.PodInfo in project cdap by caskdata.

the class KubeTwillPreparer method createPodSpec.

/**
 * Creates a {@link V1PodSpec} for specifying pod information for running the given runnable.
 *
 * @param runtimeConfigLocation the {@link Location} containing the runtime config archive
 * @param runtimeSpecs the specification for the {@link TwillRunnable} and its resources requirements
 * @param restartPolicy pod restart policy
 * @param extraMounts volumes to be mounted
 * @return a {@link V1PodSpec}
 */
private V1PodSpec createPodSpec(Location runtimeConfigLocation, Map<String, RuntimeSpecification> runtimeSpecs, String restartPolicy, List<String> args, V1VolumeMount... extraMounts) {
    String workDir = "/workDir-" + twillRunId.getId();
    V1Volume podInfoVolume = createPodInfoVolume(podInfo);
    RuntimeSpecification mainRuntimeSpec = getMainRuntimeSpecification(runtimeSpecs);
    String runnableName = mainRuntimeSpec.getName();
    V1ResourceRequirements initContainerResourceRequirements = createResourceRequirements(mainRuntimeSpec.getResourceSpecification());
    // Add volume mounts to the container. Add those from the current pod for mount cdap and hadoop conf.
    List<V1VolumeMount> volumeMounts = new ArrayList<>(podInfo.getContainerVolumeMounts());
    volumeMounts.add(new V1VolumeMount().name(podInfoVolume.getName()).mountPath(podInfo.getPodInfoDir()).readOnly(true));
    // Add the working directory the file localization by the init container
    volumeMounts.add(new V1VolumeMount().name("workdir").mountPath(workDir));
    volumeMounts.addAll(Arrays.asList(extraMounts));
    // Mount all volumes including cdap-secret for init container as it runs system/trusted code.
    List<V1VolumeMount> initContainerVolumeMounts = new ArrayList<>(volumeMounts);
    // Mount all except cdap-secret for main container by default. If requested, cdap-secret will
    // get mounted later.
    List<V1VolumeMount> containerVolumeMounts = volumeMounts.stream().filter(v -> !v.getName().equals(KubeMasterEnvironment.SECURITY_CONFIG_NAME)).collect(Collectors.toList());
    // Setup the container environment. Inherit everything from the current pod.
    Map<String, String> initContainerEnvirons = podInfo.getContainerEnvironments().stream().collect(Collectors.toMap(V1EnvVar::getName, V1EnvVar::getValue));
    // Add all environments of the the main runnable for the init container.
    if (environments.get(mainRuntimeSpec.getName()) != null) {
        initContainerEnvirons.putAll(environments.get(mainRuntimeSpec.getName()));
    }
    V1PodSpecBuilder podSpecBuilder = new V1PodSpecBuilder();
    if (schedulerQueue != null) {
        podSpecBuilder = podSpecBuilder.withPriorityClassName(schedulerQueue);
    }
    if (serviceAccountName == null) {
        serviceAccountName = podInfo.getServiceAccountName();
    }
    return podSpecBuilder.withServiceAccountName(serviceAccountName).withRuntimeClassName(podInfo.getRuntimeClassName()).addAllToVolumes(podInfo.getVolumes()).addToVolumes(podInfoVolume, new V1Volume().name("workdir").emptyDir(new V1EmptyDirVolumeSource())).withInitContainers(createContainer("file-localizer", podInfo.getContainerImage(), podInfo.getImagePullPolicy(), workDir, initContainerResourceRequirements, initContainerVolumeMounts, initContainerEnvirons, FileLocalizer.class, runtimeConfigLocation.toURI().toString(), mainRuntimeSpec.getName())).withContainers(createContainers(runtimeSpecs, workDir, containerVolumeMounts, args)).withSecurityContext(podInfo.getSecurityContext()).withRestartPolicy(restartPolicy).build();
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Arrays(java.util.Arrays) TypeToken(com.google.gson.reflect.TypeToken) BatchV1Api(io.kubernetes.client.openapi.apis.BatchV1Api) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) SecureStore(org.apache.twill.api.SecureStore) DirectoryStream(java.nio.file.DirectoryStream) V1EnvVar(io.kubernetes.client.openapi.models.V1EnvVar) DefaultLocalFile(org.apache.twill.internal.DefaultLocalFile) Configs(org.apache.twill.api.Configs) Map(java.util.Map) V1VolumeMount(io.kubernetes.client.openapi.models.V1VolumeMount) Path(java.nio.file.Path) V1PersistentVolumeClaimBuilder(io.kubernetes.client.openapi.models.V1PersistentVolumeClaimBuilder) RuntimeSpecification(org.apache.twill.api.RuntimeSpecification) V1Volume(io.kubernetes.client.openapi.models.V1Volume) TwillController(org.apache.twill.api.TwillController) LocalFile(org.apache.twill.api.LocalFile) SecretDisk(io.cdap.cdap.master.spi.twill.SecretDisk) DefaultRuntimeSpecification(org.apache.twill.internal.DefaultRuntimeSpecification) Set(java.util.Set) StandardCharsets(java.nio.charset.StandardCharsets) Stream(java.util.stream.Stream) V1SecurityContextBuilder(io.kubernetes.client.openapi.models.V1SecurityContextBuilder) MasterEnvironmentContext(io.cdap.cdap.master.spi.environment.MasterEnvironmentContext) V1PersistentVolumeClaim(io.kubernetes.client.openapi.models.V1PersistentVolumeClaim) LogHandler(org.apache.twill.api.logging.LogHandler) V1Deployment(io.kubernetes.client.openapi.models.V1Deployment) StatefulDisk(io.cdap.cdap.master.spi.twill.StatefulDisk) Location(org.apache.twill.filesystem.Location) V1Job(io.kubernetes.client.openapi.models.V1Job) Paths(org.apache.twill.internal.utils.Paths) StatefulTwillPreparer(io.cdap.cdap.master.spi.twill.StatefulTwillPreparer) AppsV1Api(io.kubernetes.client.openapi.apis.AppsV1Api) ApiClient(io.kubernetes.client.openapi.ApiClient) BufferedOutputStream(java.io.BufferedOutputStream) ArrayList(java.util.ArrayList) V1EmptyDirVolumeSource(io.kubernetes.client.openapi.models.V1EmptyDirVolumeSource) TwillRuntimeSpecification(org.apache.twill.internal.TwillRuntimeSpecification) V1ObjectMeta(io.kubernetes.client.openapi.models.V1ObjectMeta) TwillRuntimeSpecificationAdapter(org.apache.twill.internal.json.TwillRuntimeSpecificationAdapter) ClassAcceptor(org.apache.twill.api.ClassAcceptor) SecureTwillPreparer(io.cdap.cdap.master.spi.twill.SecureTwillPreparer) Resources(com.google.common.io.Resources) Files(java.nio.file.Files) V1PodSpecBuilder(io.kubernetes.client.openapi.models.V1PodSpecBuilder) IOException(java.io.IOException) V1ResourceRequirementsBuilder(io.kubernetes.client.openapi.models.V1ResourceRequirementsBuilder) LogOnlyEventHandler(org.apache.twill.internal.LogOnlyEventHandler) DefaultTwillSpecification(org.apache.twill.internal.DefaultTwillSpecification) TwillRunnable(org.apache.twill.api.TwillRunnable) V1ObjectMetaBuilder(io.kubernetes.client.openapi.models.V1ObjectMetaBuilder) TwillRunnableSpecification(org.apache.twill.api.TwillRunnableSpecification) JsonObject(com.google.gson.JsonObject) PodInfo(io.cdap.cdap.master.environment.k8s.PodInfo) URL(java.net.URL) TwillPreparer(org.apache.twill.api.TwillPreparer) LoggerFactory(org.slf4j.LoggerFactory) V1DeploymentBuilder(io.kubernetes.client.openapi.models.V1DeploymentBuilder) V1DownwardAPIVolumeSource(io.kubernetes.client.openapi.models.V1DownwardAPIVolumeSource) V1SecurityContext(io.kubernetes.client.openapi.models.V1SecurityContext) Gson(com.google.gson.Gson) V1StatefulSet(io.kubernetes.client.openapi.models.V1StatefulSet) RunId(org.apache.twill.api.RunId) Quantity(io.kubernetes.client.custom.Quantity) URI(java.net.URI) V1ObjectFieldSelector(io.kubernetes.client.openapi.models.V1ObjectFieldSelector) V1StatefulSetBuilder(io.kubernetes.client.openapi.models.V1StatefulSetBuilder) Collection(java.util.Collection) ResourceSpecification(org.apache.twill.api.ResourceSpecification) V1LabelSelector(io.kubernetes.client.openapi.models.V1LabelSelector) Collectors(java.util.stream.Collectors) List(java.util.List) Type(java.lang.reflect.Type) Writer(java.io.Writer) Annotation(java.lang.annotation.Annotation) SecurityContext(io.cdap.cdap.master.spi.twill.SecurityContext) Optional(java.util.Optional) V1JobBuilder(io.kubernetes.client.openapi.models.V1JobBuilder) LogEntry(org.apache.twill.api.logging.LogEntry) Completable(io.cdap.cdap.master.spi.twill.Completable) Hashing(com.google.common.hash.Hashing) HashMap(java.util.HashMap) HashSet(java.util.HashSet) ApiException(io.kubernetes.client.openapi.ApiException) JarEntry(java.util.jar.JarEntry) Constants(org.apache.twill.internal.Constants) V1Container(io.kubernetes.client.openapi.models.V1Container) V1DownwardAPIVolumeFile(io.kubernetes.client.openapi.models.V1DownwardAPIVolumeFile) JarOutputStream(java.util.jar.JarOutputStream) OutputStream(java.io.OutputStream) V1ContainerBuilder(io.kubernetes.client.openapi.models.V1ContainerBuilder) Logger(org.slf4j.Logger) KubeMasterEnvironment(io.cdap.cdap.master.environment.k8s.KubeMasterEnvironment) V1SecretVolumeSource(io.kubernetes.client.openapi.models.V1SecretVolumeSource) TimeUnit(java.util.concurrent.TimeUnit) DependentTwillPreparer(io.cdap.cdap.master.spi.twill.DependentTwillPreparer) V1PodSpec(io.kubernetes.client.openapi.models.V1PodSpec) AbstractMap(java.util.AbstractMap) TwillSpecification(org.apache.twill.api.TwillSpecification) MasterEnvironmentRunnable(io.cdap.cdap.master.spi.environment.MasterEnvironmentRunnable) Collections(java.util.Collections) V1Volume(io.kubernetes.client.openapi.models.V1Volume) ArrayList(java.util.ArrayList) V1EmptyDirVolumeSource(io.kubernetes.client.openapi.models.V1EmptyDirVolumeSource) RuntimeSpecification(org.apache.twill.api.RuntimeSpecification) DefaultRuntimeSpecification(org.apache.twill.internal.DefaultRuntimeSpecification) TwillRuntimeSpecification(org.apache.twill.internal.TwillRuntimeSpecification) V1PodSpecBuilder(io.kubernetes.client.openapi.models.V1PodSpecBuilder) V1ResourceRequirements(io.kubernetes.client.openapi.models.V1ResourceRequirements) V1VolumeMount(io.kubernetes.client.openapi.models.V1VolumeMount)

Example 2 with PodInfo

use of io.cdap.cdap.master.environment.k8s.PodInfo in project cdap by caskdata.

the class KubeTwillLauncher method run.

@Override
public void run(String[] args) throws Exception {
    if (args.length < 1) {
        throw new IllegalArgumentException("Requires runnable name in the argument");
    }
    String runnableName = args[0];
    Path runtimeConfigDir = Paths.get(Constants.Files.RUNTIME_CONFIG_JAR);
    Path argumentsPath = runtimeConfigDir.resolve(Constants.Files.ARGUMENTS);
    // Deserialize the arguments
    List<String> appArgs;
    List<String> runnableArgs;
    try (Reader reader = Files.newBufferedReader(argumentsPath, StandardCharsets.UTF_8)) {
        JsonObject jsonObj = GSON.fromJson(reader, JsonObject.class);
        appArgs = GSON.fromJson(jsonObj.get("arguments"), new TypeToken<List<String>>() {
        }.getType());
        Map<String, List<String>> map = GSON.fromJson(jsonObj.get("runnableArguments"), new TypeToken<Map<String, List<String>>>() {
        }.getType());
        runnableArgs = map.getOrDefault(runnableName, Collections.emptyList());
    }
    PodInfo podInfo = masterEnv.getPodInfo();
    try {
        TwillRuntimeSpecification twillRuntimeSpec = TwillRuntimeSpecificationAdapter.create().fromJson(runtimeConfigDir.resolve(Constants.Files.TWILL_SPEC).toFile());
        RuntimeSpecification runtimeSpec = twillRuntimeSpec.getTwillSpecification().getRunnables().get(runnableName);
        RunId runId = twillRuntimeSpec.getTwillAppRunId();
        String runnableClassName = runtimeSpec.getRunnableSpecification().getClassName();
        Class<?> runnableClass = context.getClass().getClassLoader().loadClass(runnableClassName);
        if (!TwillRunnable.class.isAssignableFrom(runnableClass)) {
            throw new IllegalArgumentException("Class " + runnableClass + " is not an instance of " + TwillRunnable.class);
        }
        twillRunnable = (TwillRunnable) Instances.newInstance(runnableClass);
        try (KubeTwillContext twillContext = new KubeTwillContext(runtimeSpec, runId, RunIds.fromString(runId.getId() + "-0"), appArgs.toArray(new String[0]), runnableArgs.toArray(new String[0]), masterEnv)) {
            twillRunnable.initialize(twillContext);
            if (!stopped) {
                twillRunnable.run();
            }
        }
    } finally {
        try {
            TwillRunnable runnable = twillRunnable;
            if (runnable != null) {
                runnable.destroy();
            }
        } finally {
            if (Arrays.stream(args).noneMatch(str -> str.equalsIgnoreCase(KubeMasterEnvironment.DISABLE_POD_DELETION))) {
                // Delete the pod itself to avoid pod goes into CrashLoopBackoff. This is added for preview pods.
                // When pod is exited, exponential backoff happens. So pod restart time keep increasing.
                // Deleting pod does not trigger exponential backoff.
                // See https://github.com/kubernetes/kubernetes/issues/57291
                deletePod(podInfo);
            }
        }
    }
}
Also used : Path(java.nio.file.Path) TwillRunnable(org.apache.twill.api.TwillRunnable) Reader(java.io.Reader) JsonObject(com.google.gson.JsonObject) TwillRuntimeSpecification(org.apache.twill.internal.TwillRuntimeSpecification) RuntimeSpecification(org.apache.twill.api.RuntimeSpecification) PodInfo(io.cdap.cdap.master.environment.k8s.PodInfo) TwillRuntimeSpecification(org.apache.twill.internal.TwillRuntimeSpecification) TypeToken(com.google.gson.reflect.TypeToken) List(java.util.List) RunId(org.apache.twill.api.RunId)

Aggregations

JsonObject (com.google.gson.JsonObject)2 TypeToken (com.google.gson.reflect.TypeToken)2 PodInfo (io.cdap.cdap.master.environment.k8s.PodInfo)2 Path (java.nio.file.Path)2 List (java.util.List)2 RunId (org.apache.twill.api.RunId)2 RuntimeSpecification (org.apache.twill.api.RuntimeSpecification)2 TwillRunnable (org.apache.twill.api.TwillRunnable)2 TwillRuntimeSpecification (org.apache.twill.internal.TwillRuntimeSpecification)2 Hashing (com.google.common.hash.Hashing)1 Resources (com.google.common.io.Resources)1 Gson (com.google.gson.Gson)1 KubeMasterEnvironment (io.cdap.cdap.master.environment.k8s.KubeMasterEnvironment)1 MasterEnvironmentContext (io.cdap.cdap.master.spi.environment.MasterEnvironmentContext)1 MasterEnvironmentRunnable (io.cdap.cdap.master.spi.environment.MasterEnvironmentRunnable)1 Completable (io.cdap.cdap.master.spi.twill.Completable)1 DependentTwillPreparer (io.cdap.cdap.master.spi.twill.DependentTwillPreparer)1 SecretDisk (io.cdap.cdap.master.spi.twill.SecretDisk)1 SecureTwillPreparer (io.cdap.cdap.master.spi.twill.SecureTwillPreparer)1 SecurityContext (io.cdap.cdap.master.spi.twill.SecurityContext)1