コード例 #1
0
        public IActionResult Post([FromQuery] string name, string namespaceName)
        {
            var job = new V1Job
            {
                ApiVersion = "batch/v1",
                Kind       = "Job",
                Metadata   = new V1ObjectMeta
                {
                    Name = name
                },
                Spec = new V1JobSpec
                {
                    Template = new V1PodTemplateSpec()
                    {
                        Spec = new V1PodSpec()
                        {
                            Containers = new List <V1Container>()
                            {
                                new V1Container()
                                {
                                    Name  = "container-test",
                                    Image = "hello-world"
                                }
                            },
                            RestartPolicy = "Never"
                        }
                    }
                }
            };

            var result = kubeClient.CreateNamespacedJob(job, namespaceName);

            return(Ok());
        }
コード例 #2
0
        public ActionResult <String> Post()
        {
            // get the namespace the pod is running in
            // this is set with a FieldRef as part of the deployment
            var pod_namespace = Environment.GetEnvironmentVariable("MY_POD_NAMESPACE");
            var task_image    = Environment.GetEnvironmentVariable("RUNNER_IMAGE");

            // get the kube client
            var kube = GetKubernetes();

            // create the job definition
            var job = new V1Job
            {
                Metadata = new V1ObjectMeta {
                    Name = "test-" + Guid.NewGuid()
                },
                Spec = new V1JobSpec {
                    Template = new V1PodTemplateSpec {
                        Metadata = new V1ObjectMeta {
                            Name   = "runner",
                            Labels = new Dictionary <string, string> {
                                { "task", "test-task" }
                            }
                        },
                        Spec = new V1PodSpec {
                            Containers = new List <V1Container> {
                                new V1Container {
                                    Name  = "runner",
                                    Image = task_image,
                                }
                            },
                            RestartPolicy = "Never"
                        }
                    }
                }
            };

            Console.WriteLine(job);

            // schedule the job
            var result = kube.CreateNamespacedJob(job, pod_namespace);

            return(job.Metadata.Name);
        }
コード例 #3
0
        public V1JobStatus CreateK8sJob(dynamic messageBody)
        {
            var job = new V1Job();

            var container = new V1Container();

            container.Image   = kubernetesJob.ImageName;
            container.Name    = kubernetesJob.KubernetesNamespace;
            container.Command = new List <string>();

            // container entry point
            container.Command.Add("dotnet");
            container.Command.Add(kubernetesJob.EntryPoint);

            // job arguments
            container.Command.Add(messageBody);

            job.Kind          = "Job";
            job.ApiVersion    = "batch/v1";
            job.Metadata      = new V1ObjectMeta();
            job.Metadata.Name = $"{kubernetesJob.JobName.ToLower()}-{DateTime.Now.Ticks.ToString()}";
            job.Metadata.NamespaceProperty = kubernetesJob.KubernetesNamespace;
            job.Spec                          = new V1JobSpec();
            job.Spec.Template                 = new V1PodTemplateSpec();
            job.Spec.Template.Spec            = new V1PodSpec();
            job.Spec.Template.Spec.Containers = new List <V1Container>();
            job.Spec.Template.Spec.Containers.Add(container);
            job.Spec.Template.Spec.RestartPolicy = "Never";
            job.Validate();

            var config = KubernetesClientConfiguration.BuildDefaultConfig();

            Console.WriteLine(config);
            IKubernetes client     = new Kubernetes(config);
            var         createdJob = client.CreateNamespacedJob(job, kubernetesJob.KubernetesNamespace);

            return(createdJob.Status);
        }
コード例 #4
0
        public V1Job GetEUConverterJob(int id)
        {
            V1Job job = new V1Job()
            {
                ApiVersion = "batch/v1",
                Kind       = V1Job.KubeKind,
                Metadata   = new V1ObjectMeta()
                {
                    Name = $"eu-converter-sliceid-{id}"
                },
                Spec = new V1JobSpec()
                {
                    TtlSecondsAfterFinished = 0,
                    BackoffLimit            = 3,
                    Template = new V1PodTemplateSpec()
                    {
                        Spec = new V1PodSpec()
                        {
                            Containers = new List <V1Container>()
                            {
                                new V1Container()
                                {
                                    Image = _appConfigService.Image,
                                    Name  = $"eu-converter-sliceid-{id}",
                                    //Command = new List<string>() { "/bin/bash", "-c", "--" },
                                    Env = new List <V1EnvVar>()
                                    {
                                        new V1EnvVar("SliceId", id.ToString()),
                                        new V1EnvVar("RetryCount", _appConfigService.RetryCount.ToString()),
                                        new V1EnvVar("SleepDuration", _appConfigService.DevAttributeContainerLifeDuration.ToString())
                                    },
                                    VolumeMounts = new List <V1VolumeMount>()
                                    {
                                        new V1VolumeMount(
                                            mountPath: "/app/appsettings.json",
                                            name: "config-volume",
                                            subPath: "appsettings.json")
                                    },
                                    ImagePullPolicy = "Always",
                                },
                            },
                            Volumes = new List <V1Volume>()
                            {
                                new V1Volume()
                                {
                                    Name      = "config-volume",
                                    ConfigMap = new V1ConfigMapVolumeSource()
                                    {
                                        Name = "app-config"
                                    }
                                }
                            },
                            RestartPolicy = "OnFailure",
                        },
                    },
                }
            };

            _logger.LogInformation($"Kubernetes job eu-converter-sliceid-{id} started.");
            return(job);
        }
コード例 #5
0
ファイル: Kubernetes.Job.cs プロジェクト: ttak0422/DFrame
        /// <summary>
        /// Generate Kubernetes Job manifest
        /// </summary>
        /// <remarks>
        /// manifest would be equivalant to YAML manifest.
        /// ---
        /// apiVersion: batch/v1
        /// kind: Job
        /// metadata:
        ///   name: {name}
        ///   labels:
        ///     app: {name}
        /// spec:
        ///   parallelism: {parallelism}
        ///   completions: {parallelism}
        ///   backoffLimit: 0
        ///   template:
        ///     metadata:
        ///       labels:
        ///         app: {name}
        ///     spec:
        ///       restartPolicy: Never
        ///       containers:
        ///         - name: {name}
        ///           image: {image}:{imageTag}
        ///           imagePullPolicy: {imagePullPolicy}
        ///           args: [""--worker-flag""]
        ///           env:
        ///             - name: DFRAME_MASTER_CONNECT_TO_HOST
        ///               value: ""{host}""
        ///             - name: DFRAME_MASTER_CONNECT_TO_PORT
        ///               value: ""{port}""
        ///           resources:
        ///             requests:
        ///               cpu: 100m
        ///               memory: 100Mi
        ///             limits:
        ///               cpu: 2000m
        ///               memory: 1000Mi
        ///       imagePullSecrets:
        ///         - name: {imagePullSecret}
        /// ---
        /// </remarks>
        /// <param name="name"></param>
        /// <param name="image"></param>
        /// <param name="imageTag"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="imagePullPolicy"></param>
        /// <param name="imagePullSecret"></param>
        /// <param name="parallelism"></param>
        /// <returns></returns>
        public V1Job CreateJobDefinition(string name, string image, string imageTag, string host, int port, string imagePullPolicy = "IfNotPresent", string imagePullSecret = "", int parallelism = 1)
        {
            var labels = new Dictionary <string, string>
            {
                { "app", name },
            };
            var definition = new V1Job
            {
                ApiVersion = "batch/v1",
                Kind       = "Job",
                Metadata   = new V1ObjectMeta
                {
                    Name   = name,
                    Labels = labels
                },
                Spec = new V1JobSpec
                {
                    Parallelism = parallelism,
                    Completions = parallelism,
                    // note: must be 0 to prevent pod restart during load testing.
                    BackoffLimit = 0,
                    Template     = new V1PodTemplateSpec
                    {
                        Metadata = new V1ObjectMeta
                        {
                            Labels = labels,
                        },
                        Spec = new V1PodSpec
                        {
                            // note: must be Never to prevent pod restart during load testing.
                            RestartPolicy = "Never",
                            Containers    = new[] {
                                new V1Container
                                {
                                    Name  = name,
                                    Image = $"{image}:{imageTag}",
                                    // "IfNotPresent" to reuse existing, "Never" to always use latest image for same tag.
                                    ImagePullPolicy = imagePullPolicy,
                                    Args            = new [] { "--worker-flag" },
                                    Env             = new []
                                    {
                                        new V1EnvVar
                                        {
                                            Name  = "DFRAME_MASTER_CONNECT_TO_HOST",
                                            Value = host,
                                        },
                                        new V1EnvVar
                                        {
                                            Name  = "DFRAME_MASTER_CONNECT_TO_PORT",
                                            Value = port.ToString(),
                                        }
                                    },
                                    Resources = new V1ResourceRequirements
                                    {
                                        // todo: should be configuable
                                        Limits = new Dictionary <string, ResourceQuantity>
                                        {
                                            { "cpu", new ResourceQuantity {
                                                  Value = "2000m"
                                              } },
                                            { "memory", new ResourceQuantity {
                                                  Value = "1000Mi"
                                              } },
                                        },
                                        Requests = new Dictionary <string, ResourceQuantity>
                                        {
                                            { "cpu", new ResourceQuantity {
                                                  Value = "100m"
                                              } },
                                            { "memory", new ResourceQuantity {
                                                  Value = "100Mi"
                                              } },
                                        }
                                    },
                                },
                            },
                        },
                    }
                }
            };

            if (!string.IsNullOrEmpty(imagePullSecret))
            {
                definition.Spec.Template.Spec.ImagePullSecrets = new[]
                {
                    new V1LocalObjectReference
                    {
                        Name = imagePullSecret,
                    },
                };
            }
            return(definition);
        }
コード例 #6
0
ファイル: Kubernetes.Job.cs プロジェクト: ttak0422/DFrame
        public async ValueTask <V1Job> CreateJobAsync(string ns, V1Job job, CancellationToken ct = default)
        {
            using var res = await CreateJobHttpAsync(ns, JsonConvert.Serialize(job), ct).ConfigureAwait(false);

            return(res.Body);
        }
コード例 #7
0
        async Task StartJobFor(IPerformerLog log, Context context, Read.Configuration.Build build)
        {
            var @namespace = "dolittle";

            var metadata = new V1ObjectMeta
            {
                Name = Guid.NewGuid().ToString() //,
                       //Labels = { { "type", "build" } }
            };

            log.Information($"---");
            log.Information($"Type : {build.Type}");
            log.Information($"BasePath : {build.BasePath}");
            log.Information($"Package : {build.Package}");
            log.Information($"Publish : {build.Publish}");
            log.Information($"Folder with project to publish : {build.FolderWithProjectToPublish}");
            log.Information($"---");

            var job = new V1Job
            {
                Metadata = metadata,
                Spec     = new V1JobSpec
                {
                    Completions = 1,

                    Template = new V1PodTemplateSpec
                    {
                        Metadata = metadata,
                        Spec     = new V1PodSpec
                        {
                            Containers = new [] {
                                new V1Container {
                                    Name            = "build",
                                    Image           = $"dolittlebuild/{build.Type}",
                                    ImagePullPolicy = "Always",
                                    Env             = new [] {
                                        new V1EnvVar("REPOSITORY", context.Project.Repository.ToString()),
                                        new V1EnvVar("COMMIT", context.SourceControl.Commit),
                                        new V1EnvVar("PULL_REQUEST", context.IsPullRequest.ToString()),
                                        new V1EnvVar("VERSION", context.Version),
                                        new V1EnvVar("BASE_PATH", build.BasePath),
                                        new V1EnvVar("PACKAGE", build.Package.ToString()),
                                        new V1EnvVar("PUBLISH", build.Publish.ToString()),
                                        new V1EnvVar("FOLDER_WITH_PROJECT_TO_PUBLISH", build.FolderWithProjectToPublish),
                                        new V1EnvVar("CALLBACK", $"http://continuousimprovement/buildJobDone?jobName={metadata.Name}")
                                    },
                                    VolumeMounts = new[] {
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/repository",
                                            SubPath   = context.Volumes.SourcePath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/packages",
                                            SubPath   = context.Volumes.PackagePath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/output",
                                            SubPath   = context.Volumes.OutputPath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/publish",
                                            SubPath   = context.Volumes.PublishPath
                                        },
                                        new V1VolumeMount {
                                            Name      = "azure",
                                            MountPath = "/testresults",
                                            SubPath   = context.Volumes.TestResultsPath
                                        }
                                    }
                                }
                            },
                            Volumes = new[] {
                                new V1Volume {
                                    Name      = "azure",
                                    AzureFile = new V1AzureFileVolumeSource {
                                        SecretName       = "azure-storage-secret",
                                        ShareName        = "continuousimprovement",
                                        ReadOnlyProperty = false
                                    }
                                }
                            },
                            RestartPolicy = "Never",
                        }
                    }
                }
            };

            await _kubernetes.CreateNamespacedJobAsync(job, @namespace);
        }
コード例 #8
0
        public async Task <V1Job> CreateJobAsync(string jobName,
                                                 int parallelism,
                                                 int completions,
                                                 string containerName,
                                                 string containerImage,
                                                 string imagePullSecret,
                                                 string label,
                                                 IDictionary <string, string> environmentVariables,
                                                 string _namespace = "default",
                                                 string cpuRequest = "250m",
                                                 string memRequest = "50Mi",
                                                 string cpuLimit   = "500m",
                                                 string memLimit   = "100Mi")
        {
            if (string.IsNullOrEmpty(jobName))
            {
                throw new ArgumentNullException(nameof(jobName));
            }
            if (string.IsNullOrEmpty(containerName))
            {
                throw new ArgumentNullException(nameof(containerName));
            }
            if (string.IsNullOrEmpty(containerImage))
            {
                throw new ArgumentNullException(nameof(containerImage));
            }
            if (string.IsNullOrEmpty(imagePullSecret))
            {
                throw new ArgumentNullException(nameof(imagePullSecret));
            }
            if (parallelism < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(parallelism));
            }
            if (completions < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(completions));
            }
            if (environmentVariables == null || environmentVariables.Count == 0)
            {
                throw new ApplicationException("No Environment variable provided!");
            }

            var labels = new Dictionary <string, string>();

            labels.Add("nanny", label);

            var job = new V1Job();

            job.Metadata = new V1ObjectMeta()
            {
                Name = jobName
            };

            var podLimits = new Dictionary <string, ResourceQuantity>();

            podLimits.Add("cpu", new ResourceQuantity(cpuLimit));
            podLimits.Add("memory", new ResourceQuantity(memLimit));

            var podRequest = new Dictionary <string, ResourceQuantity>();

            podRequest.Add("cpu", new ResourceQuantity(cpuRequest));
            podRequest.Add("memory", new ResourceQuantity(memRequest));

            List <V1EnvVar> envVars = environmentVariables.Select(e => new V1EnvVar(e.Key, e.Value)).ToList <V1EnvVar>();

            job.Spec = new V1JobSpec()
            {
                Parallelism = parallelism,
                Completions = completions,
                Template    = new V1PodTemplateSpec()
                {
                    Metadata = new V1ObjectMeta()
                    {
                        Labels = labels
                    },
                    Spec = new V1PodSpec()
                    {
                        Containers = new List <V1Container>()
                        {
                            new V1Container()
                            {
                                Name            = containerName,
                                Image           = containerImage,
                                ImagePullPolicy = "Always",
                                Resources       = new V1ResourceRequirements()
                                {
                                    Limits   = podLimits,
                                    Requests = podRequest
                                },
                                Env = envVars
                            }
                        },
                        RestartPolicy    = "Never",
                        ImagePullSecrets = new List <V1LocalObjectReference>()
                        {
                            new V1LocalObjectReference()
                            {
                                Name = imagePullSecret
                            }
                        }
                    }
                }
            };

            return(await _k8client.CreateNamespacedJobAsync(job, _namespace));
        }
コード例 #9
0
ファイル: KubeClient.cs プロジェクト: lulzzz/ContainerNanny
        public async Task <V1Job> CreateJobAsync(string jobName, int parallelism, int completions, string containerName, string containerImage, string imagePullSecret, string _namespace = "default")
        {
            if (string.IsNullOrEmpty(jobName))
            {
                throw new ArgumentNullException(nameof(jobName));
            }
            if (string.IsNullOrEmpty(containerName))
            {
                throw new ArgumentNullException(nameof(containerName));
            }
            if (string.IsNullOrEmpty(containerImage))
            {
                throw new ArgumentNullException(nameof(containerImage));
            }
            if (string.IsNullOrEmpty(imagePullSecret))
            {
                throw new ArgumentNullException(nameof(imagePullSecret));
            }
            if (parallelism < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(parallelism));
            }
            if (completions < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(completions));
            }


            var job = new V1Job();

            job.Metadata = new V1ObjectMeta()
            {
                Name = jobName
            };

            job.Spec = new V1JobSpec()
            {
                Parallelism = parallelism,
                Completions = completions,
                Template    = new V1PodTemplateSpec()
                {
                    Spec = new V1PodSpec()
                    {
                        Containers = new List <V1Container>()
                        {
                            new V1Container()
                            {
                                Name            = containerName,
                                Image           = containerImage,
                                ImagePullPolicy = "Always"
                            }
                        },
                        RestartPolicy    = "Never",
                        ImagePullSecrets = new List <V1LocalObjectReference>()
                        {
                            new V1LocalObjectReference()
                            {
                                Name = imagePullSecret
                            }
                        }
                    }
                }
            };

            return(await _k8client.CreateNamespacedJobAsync(job, _namespace));
        }
コード例 #10
0
        private async Task <string> DescribeObject(Kubernetes client, V1Namespace ns, V1Job o, StringBuilder buffer)
        {
            var fetched = await client.ReadNamespacedJobAsync(o.Metadata.Name, ns.Metadata.Name).ConfigureAwait(false);

            buffer.AppendLine($"API Veresion: {fetched.ApiVersion}");
            buffer.AppendLine($"Kind: {fetched.Kind}");
            buffer.AppendLine(DescribeMetadata(fetched.Metadata));
            return($"Job - {fetched.Metadata.Name}");
        }
コード例 #11
0
ファイル: KubernetesProcessor.cs プロジェクト: tiffstorm/pi
        public async Task <Job> SubmitJob(Job job)
        {
            var resources = new V1ResourceRequirements
            {
                Requests = new Dictionary <string, ResourceQuantity>()
                {
                    { "cpu", new ResourceQuantity("1") },
                    { "memory", new ResourceQuantity($"1Gi") }
                }
            };

            var podSpec = new V1PodSpec
            {
                Containers = new[]
                {
                    new V1Container
                    {
                        Name    = job.Id,
                        Image   = _config["Pi:Docker:Image"],
                        Command = new []
                        {
                            "/app/Pi.Runtime.NetFx",
                            "-dp",
                            job.DecimalPlaces.ToString()
                        },
                        Resources = resources
                    }
                },
                RestartPolicy = "Never"
            };

            //for running in AKS with ACI integration:
            if (_config.GetValue <bool>("Pi:Processors:Kubernetes:UseAci"))
            {
                AddAciConfiguration(podSpec);
            }

            var jobSpec = new V1JobSpec()
            {
                Template = new V1PodTemplateSpec(spec: podSpec)
            };

            var jobMetadata = new V1ObjectMeta(name: job.Id)
            {
                Labels = new Dictionary <string, string>()
                {
                    { "com.pi", "1" }
                }
            };

            var k8sJob = new V1Job(metadata: jobMetadata, spec: jobSpec);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("*** Generated YAML: ***");
                var yaml = Yaml.SaveToString(k8sJob);
                _logger.LogDebug(yaml);
                _logger.LogDebug("---");
            }

            await _kubernetes.CreateNamespacedJobAsync(k8sJob, _namespace);

            job.ProcessingId = k8sJob.Metadata.Name;
            return(job);
        }
コード例 #12
0
        private async Task <bool> CreateJobAsync(WebPingerArchive archive)
        {
            // check a pinger exists to archive:
            var services = await _kubernetes.ListNamespacedServiceAsync(
                Program.NamespaceName,
                labelSelector : $"app=web-ping,target={archive.Spec.Target}");

            if (!services.Items.Any())
            {
                Console.WriteLine($"** No WebPinger Service exists for target: {archive.Spec.Target}, in namespace: {Program.NamespaceName}");
                return(false);
            }

            var pingerServiceName = services.Items.First().Metadata.Name;
            var name = $"wpa-{archive.Metadata.Name}-{archive.Metadata.CreationTimestamp:yyMMdd-HHmm}";
            var jobs = await _kubernetes.ListNamespacedJobAsync(
                Program.NamespaceName,
                fieldSelector : $"metadata.name={name}");

            if (!jobs.Items.Any())
            {
                var job = new V1Job
                {
                    Metadata = new V1ObjectMeta
                    {
                        Name   = name,
                        Labels = new Dictionary <string, string>()
                        {
                            { "kiamol", "ch20" },
                        }
                    },
                    Spec = new V1JobSpec
                    {
                        Completions = 1,
                        Template    = new V1PodTemplateSpec
                        {
                            Metadata = new V1ObjectMeta
                            {
                                Labels = new Dictionary <string, string>()
                                {
                                    { "app", "web-ping-archive" },
                                    { "target", archive.Spec.Target }
                                }
                            },
                            Spec = new V1PodSpec
                            {
                                AutomountServiceAccountToken = false,
                                RestartPolicy = "Never",
                                Containers    = new List <V1Container>
                                {
                                    new V1Container
                                    {
                                        Name  = "archiver",
                                        Image = "kiamol/ch20-web-ping-archiver",
                                        Env   = new List <V1EnvVar>
                                        {
                                            new V1EnvVar
                                            {
                                                Name  = "WEB_PING_URL",
                                                Value = $"http://{pingerServiceName}:8080/archive"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                };

                await _kubernetes.CreateNamespacedJobAsync(job, Program.NamespaceName);

                Console.WriteLine($"** Created Job: {name}, in namespace: {Program.NamespaceName}");
                return(true);
            }
            else
            {
                Console.WriteLine($"** Job exists: {name}, in namespace: {Program.NamespaceName}");
                return(false);
            }
        }