【问题标题】:How to run containers sequentially as a Kubernetes job?如何将容器作为 Kubernetes 作业顺序运行?
【发布时间】:2017-04-04 11:00:30
【问题描述】:

我正在尝试用 Kubernetes 作业替换我的旧作业调度程序,并且想知道如何将顺序作业编写为 Kubernetes 作业。

首先,我编写了以下脚本以按书面顺序执行job1job2,但它没有按我的预期工作。

apiVersion: batch/v1
kind: Job
metadata:
  name: sequential
spec:
  activeDeadlineSeconds: 100
  template:
    metadata:
      name: sequential_jobs
    spec:
      containers:
      - name: job1
        image: image1
      - name: job2
        image: image2
      restartPolicy: Never

上述作业似乎是并行运行job1job2。 有没有什么好办法可以按书面顺序运行job1job2

附加。

我最近发现 https://github.com/argoproj/argo 非常适合我的用例。

【问题讨论】:

    标签: kubernetes kubernetes-jobs argoproj


    【解决方案1】:

    一般来说,在 Kubernetes 设置中没有序列和捕获跨容器/pod 的依赖关系的概念。

    在您的情况下,如果您在作业规范(甚至是 pod 规范)中有 2 个容器,则这 2 个容器没有排序。同样,如果您一个接一个地解雇 2 个工作,那么这些工作也没有排序的概念。

    理想情况下,如果有任何东西需要排序,您应该将其捕获在单个单元(容器)中。


    与您的问题略有相干,这是我见过的另一种常见模式 当一个 Job 依赖于另一个存在的服务时(比如一个 k8s 服务的部署):

    作业中的容器向 k8s 服务发出请求,如果服务没有按预期响应则失败。这样,作业会不断重启,最终当服务启动时,作业会成功执行并完成。

    【讨论】:

    • Pod 可以有“init 容器”,它们在“main”容器启动之前运行。但我不知道这是否也适用于乔布斯。如果是这样,job1 可以作为 init 容器运行,job2 作为主容器运行。见kubernetes.io/docs/user-guide/production-pods/…
    • 我还没有尝试过,但它似乎是不错的选择。谢谢@MarcSluiter
    • InitContainers 将按照初始化容器列表定义的顺序运行到完成。如果有任何失败,则作业将失败。
    【解决方案2】:

    刚刚遇到这个。如上所述,据我所知,Kubernetes 中没有工作依赖的概念,但我一直在与一个商业实体 (Univa) 合作,该实体具有提供此(和其他)功能的附加组件。

    该产品称为 Navops Command,它允许您使用简单的依赖表示法来注释 Kubernetes 作业。有一个博客有一个简短的解释和例子here。基本上,Navops 作为一组容器安装在 Kubernetes 上,公开它自己的 UI 和 CLI,并为 Kubernetes 调度程序补充额外的功能。你可以在http://navops.io下载。

    该技术来自 HPC 中使用的 Grid Engine 调度程序,其中复杂的工作流、阵列作业等很常见。

    【讨论】:

      【解决方案3】:

      经过几次尝试,我这样做并解决了基本问题(类似于 OP 发布的内容)。此配置确保job-1job-2 开始之前完成。如果job-1 失败,则job-2 容器不会启动。我仍然需要处理重试和故障处理,但基础工作。希望这对其他人有所帮助:

      apiVersion: v1
      kind: Pod
      metadata:
        name: sequential-job
      spec:
        initContainers:
        - name: job-1
          image: busybox
          # runs for 15 seconds; echoes job name and timestamp
          command: ['sh', '-c', 'for i in 1 2 3; do echo "job-1 `date`" && sleep 5s; done;']
        - name: job-2
          image: busybox
          # runs for 15 seconds; echoes job name and timestamp
          command: ['sh', '-c', 'for i in 1 2 3; do echo "job-2 `date`" && sleep 5s; done;']
        # I don't really need the 'containers', but syntax requires 
        # it so, I'm using it as a place where I can report the 
        # completion status
        containers:
        - name: job-done
          image: busybox
          command: ['sh', '-c', 'echo "job-1 and job-2 completed"']
        restartPolicy: Never
      

      更新

      与上述相同的配置也适用于 Job spec:

      apiVersion: batch/v1
      kind: Job
      metadata:
        name: sequential-jobs
      spec:
        template:
          metadata:
            name: sequential-job
          spec:
            initContainers:
            - name: job-1
              image: busybox
              command: ['sh', '-c', 'for i in 1 2 3; do echo "job-1 `date`" && sleep 5s; done;']
            - name: job-2
              image: busybox
              command: ['sh', '-c', 'for i in 1 2 3; do echo "job-2 `date`" && sleep 5s; done;']
            containers:
            - name: job-done
              image: busybox
              command: ['sh', '-c', 'echo "job-1 and job-2 completed"']
            restartPolicy: Never
      

      【讨论】:

      • 这回答了这个问题。需要考虑的一个缺点是所有容器都将共享 Pod 服务帐户的“大多数”权限。
      • P.S.对于那些担心restartPolicy=Never 是否会让工作如果失败永不重启的人(例如愚蠢的我)——答案是否定的,如果失败它会重启。 see this
      • 请记住,如果要显示 init 容器的日志,则需要使用 -c 标志提供 init 容器名称,例如kubectl logs -f <podName> -c job-1
      【解决方案4】:

      你看过 Brigade - https://brigade.sh 。 使用 JavaScript 编写简单和复杂的工作流程。将容器链接在一起,并行或串行运行它们。根据时间、GitHub 事件、Docker 推送或任何其他触发器触发脚本。 Brigade 是为 Kubernetes 创建管道的工具。

      【讨论】:

        【解决方案5】:

        Argo 工作流程适合您的用例。 Argo 将支持顺序、并行、DAG 作业处理。

        # This template demonstrates a steps template and how to control sequential vs. parallel steps.
        # In this example, the hello1 completes before the hello2a, and hello2b steps, which run in parallel.
        apiVersion: argoproj.io/v1alpha1
        kind: Workflow
        metadata:
          generateName: steps-
        spec:
          entrypoint: hello-hello-hello
        
          templates:
          - name: hello-hello-hello
            steps:
            - - name: hello1
                template: whalesay
                arguments:
                  parameters: [{name: message, value: "hello1"}]
            - - name: hello2a
                template: whalesay
                arguments:
                  parameters: [{name: message, value: "hello2a"}]
              - name: hello2b
                template: whalesay
                arguments:
                  parameters: [{name: message, value: "hello2b"}]
        
          - name: whalesay
            inputs:
              parameters:
              - name: message
            container:
              image: docker/whalesay
              command: [cowsay]
              args: ["{{inputs.parameters.message}}"]
        
        

        【讨论】:

          【解决方案6】:

          Kubernetes 提供此功能以使用字段 Parallelism 并行或顺序运行作业,它还有助于限制一次运行的作业数量

          这是文档:Kubernetes documentation

          apiVersion: batch/v1
          kind: Job
          metadata:
           name: job-wq-2
          spec:
           parallelism: 1
           template:
            metadata:
             name: job-wq-2
          spec:
            containers:
            - name: c
              image: gcr.io/myproject/job-wq-2
            restartPolicy: OnFailure
          

          【讨论】:

            猜你喜欢
            • 2019-09-28
            • 2019-03-27
            • 1970-01-01
            • 2020-01-02
            • 2021-05-23
            • 2019-03-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多