Tekton Pipelines--Task

前言

Tekton Pipelines是一个开源实现,可为您的Kubernetes应用程序配置和运行CI / CD风格的管道。

Pipelines创建自定义资源作为构建块去声明Pipelines。

自定义资源是Kubernetes API的扩展,可以创建自定义Kubernetes对象。安装自定义资源后,用户可以使用kubectl创建和访问其对​​象,就像对pod,部署等内置资源一样。这些资源在集群上运行,并由Kubernetes自定义资源定义(CRD)实施。

关于此设计的高级细节:

  • Pipelines不知道什么会触发它们,它们可以由事件或手动创建PipelineRun触发。
  • Tasks可以单独存在,并且可以完全独立于Pipelines调用。它们具有高内聚低耦合特点。
  • Tasks可以取决于其他Tasks创建的工件和参数。
  • Tasks可以被TaskRuns调用。
  • PipelineResources是用作Tasks输入和输出的工件。

接下来我们将逐一介绍如下构建组件:

与特定组件无关的其他参考主题:

该篇主要介绍Task。

Task

Task(或ClusterTask)是您希望在连续集成流程中运行的顺序步骤的集合。任务将在集群上的pod内运行。

一个 Task 声明包括:

  • Inputs
  • Outputs
  • Steps

Task的作用范围是一个namespace,而ClusterTask的作用范围是整个kubernetes 集群。

ClusterTask

与Task类似,但是作用域是整个集群。

如果使用ClusterTask,则应添加TaskRef类型。默认类型是Task,它代表命名空间的Task。

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: demo-pipeline
  namespace: default
spec:
  tasks:
    - name: build-skaffold-web
      taskRef:
        name: build-push
        kind: ClusterTask
      params: ....

ask的功能与ClusterTask完全相同,因此下面对Task的所有引用也描述了ClusterTask.

语法

要为Task资源定义配置文件,可以指定以下字段:

  • 必写:

    • apiVersion- 指定 API 版本, 例如tekton.dev/v1alpha1.
    • kind- 指定 Task 资源对象.
    • metadata- 指定数据以唯一标识Task资源对象, 例如name.
    • spec- 为Task资源对象指定配置信息。必须通过以下任一字段定义Task steps:

      • steps - 指定要在Task中运行的一个或多个容器镜像。
  • 可选:

    • inputs- 指定你Task需要用到的参数和 PipelineResources
    • outputs- 指定你Task 产生的 PipelineResources
    • volumes- 指定一个或多个要用于Tasksteps的 挂载卷.
    • stepTemplate- 指定容器 step 定义,以用作“Task”中所有step的基础。.
    • sidecars- 指定sidercar容器与steps一起运行.

以下示例是一个无效示例,其中使用了大多数可能的配置字段:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: example-task-name
spec:
  inputs:
    resources:
      - name: workspace
        type: git
    params:
      - name: pathToDockerFile
        type: string
        description: The path to the dockerfile to build
        default: /workspace/workspace/Dockerfile
  outputs:
    resources:
      - name: builtImage
        type: image
  steps:
    - name: ubuntu-example
      image: ubuntu
      args: ["ubuntu-build-example", "SECRETS-example.md"]
    - image: gcr.io/example-builders/build-example
      command: ["echo"]
      args: ["$(inputs.params.pathToDockerFile)"]
    - name: dockerfile-pushexample
      image: gcr.io/example-builders/push-example
      args: ["push", "$(outputs.resources.builtImage.url)"]
      volumeMounts:
        - name: docker-socket-example
          mountPath: /var/run/docker.sock
  volumes:
    - name: example-volume
      emptyDir: {}

Steps

Steps字段是必填字段。您定义一个或多个Step字段以定义Task主体。

如果定义了多个Step,则由TaskRun调用任务时,将按照定义的顺序执行它们。

Task中的每个Step都必须指定一个遵守容器规约的容器镜像。对于您定义的每个Step字段或容器镜像:

  • 按照配置文件,依次运行和评估容器镜像。
  • 个容器镜像一直运行到完成或检测到第一个故障为止。
  • 如果容器镜像在“Task”中的所有容器镜像中没有最大的资源请求,则CPU,内存和临时存储资源请求将设置为零。这样可以确保执行任务的Pod仅请求执行任务中任何单个容器镜像所需的资源,而不是请求所有容器镜像资源请求的总和。

Inputs

一个Task可以声明其所需的inputs,可以是以下之一或全部:

  • 参数
  • 输入资源

参数

Task可以声明在TaskRun期间必须提供给任务的输入参数。此的一些示例用例包括:

  • 需要知道一个Task构建应用程序时使用什么编译标志。
  • 需要知道如何命名已构建工件的Task。

参数名称仅限于字母数字字符-和_,并且只能以字母字符和_开头。例如,fooIs-Bar_是有效的参数名称,barIsBa $或0banana不是。

每个声明的参数都有一个类型字段,如果用户未提供,则假定为字符串。另一个可能的类型是数组-例如,当需要向构建应用程序的任务提供动态数量的编译标志时,此数组很有用。提供实际参数值时,将根据类型字段验证其解析的类型。

用法

以下示例显示如何对Tasks进行参数化,以及如何将这些参数从TaskRun传递给Task。
$(inputs.params.foo)形式的输入参数在步骤内被替换(另请参见变量替换)。
以下Task声明一个名为“ flags”的输入参数,并在steps.args列表中使用它。

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: task-with-parameters
spec:
  inputs:
    params:
      - name: flags
        type: array
      - name: someURL
        type: string
  steps:
    - name: build
      image: my-builder
      args: ["build", "$(inputs.params.flags)", "url=$(inputs.params.someURL)"]

以下TaskRun在flags参数中提供了动态数目的字符串:

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  name: run-with-parameters
spec:
  taskRef:
    name: task-with-parameters
  inputs:
    params:
      - name: flags
        value: 
          - "--set"
          - "arg1=foo"
          - "--randomflag"
          - "--someotherflag"
      - name: someURL
        value: "http://google.com"

Input resources

使用输入的PipelineResources字段为您的任务提供任务所需的数据或上下文。

Outputs

Task定义可以包括输入和输出PipelineResource声明。如果仅在输出中声明了特定的资源集,则预期在下一个任务上载或共享的资源副本位于路径/ workspace / output / resource_name /下。

resources:
  outputs:
    name: storage-gcs
    type: gcs
steps:
  - image: objectuser/run-java-jar #https://hub.docker.com/r/objectuser/run-java-jar/
    command: [jar]
    args:
      ["-cvf", "-o", "/workspace/output/storage-gcs/", "projectname.war", "*"]
    env:
      - name: "FOO"
        value: "world"

注意:如果任务依赖于输出资源功能,则“任务步骤”字段中的容器无法在路径/ workspace / output中装入任何内容。

在以下示例中,Task tar-artifact资源同时用作输入和输出,因此将输入资源下载到目录customworkspace(在targetPath中指定)。Step untar将tar文件提取到tar-scratch-space目录中,edit-tar添加一个新文件,最后一个步骤tar-it-up创建一个新的tar文件并将其放置在/ workspace / customworkspace /目录中。执行完任务步骤后,目录/ workspace / customworkspace中的(新)tar文件将被上传到tar-artifact资源定义中定义的存储桶中.

resources:
  inputs:
    name: tar-artifact
    targetPath: customworkspace
  outputs:
    name: tar-artifact
steps:
 - name: untar
    image: ubuntu
    command: ["/bin/bash"]
    args: ['-c', 'mkdir -p /workspace/tar-scratch-space/ && tar -xvf /workspace/customworkspace/rules_docker-master.tar -C /workspace/tar-scratch-space/']
 - name: edit-tar
    image: ubuntu
    command: ["/bin/bash"]
    args: ['-c', 'echo crazy > /workspace/tar-scratch-space/rules_docker-master/crazy.txt']
 - name: tar-it-up
   image: ubuntu
   command: ["/bin/bash"]
   args: ['-c', 'cd /workspace/tar-scratch-space/ && tar -cvf /workspace/customworkspace/rules_docker-master.tar rules_docker-master']

Volumes

为你的Task或是所有的step指定一个或多个需要用到volume。

如,使用卷来完成以下常见任务之一:

  • 挂载k8s secret。
  • 创建一个emptyDir卷以充当缓存,以便在多个构建步骤中使用。考虑使用永久卷进行内部版本缓存。
  • 挂载k8s configmap
  • 载主机的Docker套接字以使用Dockerfile进行容器映像构建。注意:使用docker build on-cluster构建容器映像是非常不安全的。请改用kaniko。这仅用于演示目的

Step Template

指定一个容器配置,它将用作“任务”中所有步骤的基础。单个步骤中的配置将覆盖或与步骤模板的配置合并。

在下面的示例中,任务指定环境变量FOO设置为bar的stepTemplate。第一步将对该值使用FOO,但是在第二步中,将FOO覆盖并设置为baz。

stepTemplate:
  env:
    - name: "FOO"
      value: "bar"
steps:
  - image: ubuntu
    command: [echo]
    args: ["FOO is ${FOO}"]
  - image: ubuntu
    command: [echo]
    args: ["FOO is ${FOO}"]
    env:
      - name: "FOO"
        value: "baz"

Sidecars

指定要与“步骤”一起运行的“容器”列表。这些容器可以提供辅助功能,例如Docker中的Docker或运行模拟API服务器,以使您的应用在测试过程中命中。
Sidecar在执行Task的步骤之前启动,并在所有步骤完成后销毁。有关Sidecar生命周期的更多信息,请参阅[TaskRun文档]
(https://github.com/tektoncd/p...

以下示例中,运行了docker in docker的 sidecar,以便一个步骤可以使用它来构建docker映像

steps:
  - image: docker
    name: client
    workingDir: /workspace
    command:
      - /bin/sh
      - -c
      - |
        cat > Dockerfile << EOF
        FROM ubuntu
        RUN apt-get update
        ENTRYPOINT ["echo", "hello"]
        EOF
        docker build -t hello . && docker run hello
        docker images
    volumeMounts:
      - mountPath: /var/run/
        name: dind-socket
sidecars:
  - image: docker:18.05-dind
    name: server
    securityContext:
      privileged: true
    volumeMounts:
      - mountPath: /var/lib/docker
        name: dind-storage
      - mountPath: /var/run/
        name: dind-socket
volumes:
  - name: dind-storage
    emptyDir: {}
  - name: dind-socket
    emptyDir: {}

Variable Substitution

任务支持使用所有输入和输出中的值替换字符串。

可以使用以下变量替换语法在任务规范中引用输入参数,其中是参数的名称:

$(inputs.params.)

来自资源的参数值也可以使用变量替换来访问。

参数类型为数组的变量替换

类型为array的引用参数将扩展为在引用字符串的位置插入数组元素。

因此,使用以下参数:

inputs:
    params:
      - name: array-param
        value: 
          - "some"
          - "array"
          - "elements"

then command: ["first", "$(inputs.params.array-param)", "last"] 将变成 command: ["first", "some", "array", "elements", "last"]

请注意,必须在较大的字符串数组中的完全隔离的字符串中引用数组参数。任何其他尝试引用数组的尝试均无效,并且将引发错误。

例如,如果build-args是array类型的声明参数,那么这是无效的步骤,因为字符串不是隔离的:

- name: build-step
      image: gcr.io/cloud-builders/some-image
      args: ["build", "additionalArg $(inputs.params.build-args)"]

同样,在非数组字段中引用build-args也无效:

- name: build-step
      image: "$(inputs.params.build-args)"
      args: ["build", "args"]

对build-args参数的有效引用是隔离的,并且位于合格字段(本例中为args)中:

- name: build-step
      image: gcr.io/cloud-builders/some-image
      args: ["build", "$(inputs.params.build-args)", "additonalArg"]

Variable Substitution within Volumes

可以设置任务卷名称和不同类型的卷。当前支持包括广泛使用的卷类型,例如configmap,secret和PersistentVolumeClaim。这是有关如何在“任务定义”中使用此示例。

Examples

例如,封装Dockerfile构建的Task可能看起来像这样:

注意:使用docker build on-cluster构建容器映像是非常不安全的。请改用kaniko。这仅用于演示目的。

spec:
  inputs:
    resources:
      - name: workspace
        type: git
    params:
      # These may be overridden, but provide sensible defaults.
      - name: directory
        type: string
        description: The directory containing the build context.
        default: /workspace
      - name: dockerfileName
        type: string
        description: The name of the Dockerfile
        default: Dockerfile
  outputs:
    resources:
      - name: builtImage
        type: image
  steps:
    - name: dockerfile-build
      image: gcr.io/cloud-builders/docker
      workingDir: "$(inputs.params.directory)"
      args:
        [
          "build",
          "--no-cache",
          "--tag",
          "$(outputs.resources.image)",
          "--file",
          "$(inputs.params.dockerfileName)",
          ".",
        ]
      volumeMounts:
        - name: docker-socket
          mountPath: /var/run/docker.sock

    - name: dockerfile-push
      image: gcr.io/cloud-builders/docker
      args: ["push", "$(outputs.resources.image)"]
      volumeMounts:
        - name: docker-socket
          mountPath: /var/run/docker.sock

  # As an implementation detail, this Task mounts the host's daemon socket.
  volumes:
    - name: docker-socket
      hostPath:
        path: /var/run/docker.sock
        type: Socket

使用一个外部 volume

挂载多个卷:

spec:
  steps:
    - image: ubuntu
      entrypoint: ["bash"]
      args: ["-c", "curl https://foo.com > /var/my-volume"]
      volumeMounts:
        - name: my-volume
          mountPath: /var/my-volume

    - image: ubuntu
      args: ["cat", "/etc/my-volume"]
      volumeMounts:
        - name: my-volume
          mountPath: /etc/my-volume

  volumes:
    - name: my-volume
      emptyDir: {}
      

使用 Kubernetes Configmap 作为卷

spec:
 inputs:
   params:
     - name: CFGNAME
       type: string
       description: Name of config map
     - name: volumeName
       type: string
       description: Name of volume
 steps:
   - image: ubuntu
     entrypoint: ["bash"]
     args: ["-c", "cat /var/configmap/test"]
     volumeMounts:
       - name: "$(inputs.params.volumeName)"
         mountPath: /var/configmap

 volumes:
   - name: "$(inputs.params.volumeName)"
     configMap:
       name: "$(inputs.params.CFGNAME)"

使用 secret 作为环境变量

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
 name: goreleaser
spec:
 inputs:
   params:
   - name: package
     type: string
     description: base package to build in
   - name: github-token-secret
     type: string
     description: name of the secret holding the github-token
     default: github-token
   resources:
   - name: source
     type: git
     targetPath: src/$(inputs.params.package)
 steps:
 - name: release
   image: goreleaser/goreleaser
   workingdir: /workspace/src/$(inputs.params.package)
   command:
   - goreleaser
   args:
   - release
   env:
   - name: GOPATH
     value: /workspace
   - name: GITHUB_TOKEN
     valueFrom:
       secretKeyRef:
         name: $(inputs.params.github-token-secret)
         key: bot-token

你可能感兴趣的:(k8s,golang,kubernetes,build,ci)