×

流水线和任务可能需要凭据才能与 Git 存储库和容器存储库进行身份验证。在 Red Hat OpenShift 流水线中,您可以使用密钥对在执行过程中与 Git 存储库或容器存储库交互的流水线运行和任务运行进行身份验证。

用于与 Git 存储库进行身份验证的密钥称为 *Git 密钥*。

流水线运行或任务运行通过关联的服务帐户访问密钥。或者,您可以在流水线或任务中定义工作区,并将密钥绑定到工作区。

先决条件

  • 您已安装 oc OpenShift 命令行实用程序。

使用服务帐户提供密钥

您可以使用服务帐户为 Git 存储库和容器存储库提供身份验证密钥。

您可以将密钥与服务帐户关联。密钥中的信息将提供给在此服务帐户下运行的任务。

服务帐户密钥的类型和注释

如果您使用服务帐户提供身份验证密钥,OpenShift 流水线支持多种密钥类型。对于大多数这些密钥类型,您必须提供定义身份验证密钥有效的存储库的注释。

Git 身份验证密钥

如果您使用服务帐户提供身份验证密钥,OpenShift 流水线支持以下类型的 Git 身份验证密钥

  • kubernetes.io/basic-auth:基本身份验证的用户名和密码

  • kubernetes.io/ssh-auth:基于 SSH 的身份验证密钥

如果使用服务账户提供身份验证密钥,则 Git 密钥必须具有一个或多个注解键。每个键的名称必须以tekton.dev/git-开头,其值为 OpenShift Pipelines 必须在密钥中使用凭据的主机的 URL。

在以下示例中,OpenShift Pipelines 使用basic-auth密钥访问github.comgitlab.com上的存储库。

示例:使用多个 Git 存储库的基本身份验证凭据
apiVersion: v1
kind: Secret
metadata:
  name: git-secret-basic
  annotations:
    tekton.dev/git-0: github.com
    tekton.dev/git-1: gitlab.com
type: kubernetes.io/basic-auth
stringData:
  username: <username> (1)
  password: <password> (2)
1 存储库用户名
2 存储库密码或个人访问令牌

您还可以使用ssh-auth密钥提供用于访问 Git 存储库的私钥,如下例所示

示例:基于 SSH 的身份验证的私钥
apiVersion: v1
kind: Secret
metadata:
  name: git-secret-ssh
  annotations:
    tekton.dev/git-0: https://github.com
type: kubernetes.io/ssh-auth
stringData:
  ssh-privatekey: (1)
1 SSH 私钥文件的内容。

容器注册表身份验证密钥

如果使用服务账户提供身份验证密钥,OpenShift Pipelines 支持以下类型的用于容器(Docker)注册表身份验证的密钥

  • kubernetes.io/basic-auth:基本身份验证的用户名和密码

  • kubernetes.io/dockercfg:序列化后的~/.dockercfg文件

  • kubernetes.io/dockerconfigjson:序列化后的~/.docker/config.json文件

如果使用服务账户提供身份验证密钥,则kubernetes.io/basic-auth类型的容器注册表密钥必须具有一个或多个注解键。每个键的名称必须以tekton.dev/docker-开头,其值为 OpenShift Pipelines 必须在密钥中使用凭据的主机的 URL。对于其他类型的容器注册表密钥,不需要此注解。

在以下示例中,OpenShift Pipelines 使用basic-auth密钥(依赖用户名和密码)访问quay.iomy-registry.example.com上的容器注册表。

示例:使用多个容器存储库的基本身份验证凭据
apiVersion: v1
kind: Secret
metadata:
  name: docker-secret-basic
  annotations:
    tekton.dev/docker-0: quay.io
    tekton.dev/docker-1: my-registry.example.com
type: kubernetes.io/basic-auth
stringData:
  username: <username> (1)
  password: <password> (2)
1 注册表用户名
2 注册表密码或个人访问令牌

您可以从现有配置文件创建kubernetes.io/dockercfgkubernetes.io/dockerconfigjson密钥,如下例所示

示例:从现有配置文件创建用于向容器存储库进行身份验证的密钥的命令
$ oc create secret generic docker-secret-config \
    --from-file=config.json=/home/user/.docker/config.json \
    --type=kubernetes.io/dockerconfigjson

您还可以使用oc命令行实用程序从凭据创建kubernetes.io/dockerconfigjson密钥,如下例所示

示例:从凭据创建用于向容器存储库进行身份验证的密钥的命令
$ oc create secret docker-registry docker-secret-config \
  --docker-email=<email> \ (1)
  --docker-username=<username> \ (2)
  --docker-password=<password> \ (3)
  --docker-server=my-registry.example.com:5000 (4)
1 注册表电子邮件地址
2 注册表用户名
3 注册表密码或个人访问令牌
4 注册表的主机名和端口

使用服务账户为 Git 配置基本身份验证

为了使管道能够从受密码保护的存储库检索资源,您可以为此管道配置基本身份验证。

建议使用基于 SSH 的身份验证而不是基本身份验证。

要为管道配置基本身份验证,请创建一个基本身份验证密钥,将此密钥与服务账户关联,并将此服务账户与TaskRunPipelineRun资源关联。

对于 GitHub,使用普通密码进行身份验证已弃用。请改用个人访问令牌

步骤
  1. secret.yaml文件中创建密钥的 YAML 清单。在此清单中,指定用户名和密码或GitHub 个人访问令牌以访问目标 Git 存储库。

    apiVersion: v1
    kind: Secret
    metadata:
      name: basic-user-pass (1)
      annotations:
        tekton.dev/git-0: https://github.com
    type: kubernetes.io/basic-auth
    stringData:
      username: <username> (2)
      password: <password> (3)
    1 密钥名称。在此示例中为basic-user-pass
    2 Git 存储库用户名。
    3 Git 存储库密码或个人访问令牌。
  2. serviceaccount.yaml文件中创建服务账户的 YAML 清单。在此清单中,将密钥与服务账户关联。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: build-bot (1)
    secrets:
      - name: basic-user-pass (2)
    1 服务账户名称。在此示例中为build-bot
    2 密钥名称。在此示例中为basic-user-pass
  3. run.yaml文件中创建任务运行或管道运行的 YAML 清单,并将服务账户与任务运行或管道运行关联。使用以下示例之一

    • 将服务账户与TaskRun资源关联

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: build-push-task-run-2 (1)
      spec:
        taskRunTemplate:
          serviceAccountName: build-bot (2)
        taskRef:
          name: build-push (3)
      1 任务运行名称。在此示例中为build-push-task-run-2
      2 服务账户名称。在此示例中为build-bot
      3 任务名称。在此示例中为build-push
    • 将服务账户与PipelineRun资源关联

      apiVersion: tekton.dev/v1
      kind: PipelineRun
      metadata:
        name: demo-pipeline (1)
        namespace: default
      spec:
        taskRunTemplate:
          serviceAccountName: build-bot (2)
        pipelineRef:
          name: demo-pipeline (3)
      1 管道运行名称。在此示例中为demo-pipeline
      2 服务账户名称。在此示例中为build-bot
      3 管道名称。在此示例中为demo-pipeline
  4. 通过输入以下命令应用您创建的 YAML 清单

    $ oc apply --filename secret.yaml,serviceaccount.yaml,run.yaml

使用服务账户为 Git 配置 SSH 身份验证

为了使管道能够从使用 SSH 密钥配置的存储库检索资源,您必须为此管道配置基于 SSH 的身份验证。

要为管道配置基于 SSH 的身份验证,请使用 SSH 私钥创建一个身份验证密钥,将此密钥与服务账户关联,并将此服务账户与TaskRunPipelineRun资源关联。

步骤
  1. 生成一个SSH 私钥,或复制现有私钥(通常位于~/.ssh/id_rsa文件中)。

  2. secret.yaml文件中创建密钥的 YAML 清单。在此清单中,将ssh-privatekey的值设置为 SSH 私钥文件的内容,并将known_hosts的值设置为已知主机文件的内容。

    apiVersion: v1
    kind: Secret
    metadata:
      name: ssh-key (1)
      annotations:
        tekton.dev/git-0: github.com
    type: kubernetes.io/ssh-auth
    stringData:
      ssh-privatekey: (2)
      known_hosts: (3)
    1 包含 SSH 私钥的密钥名称。在此示例中为ssh-key
    2 SSH 私钥文件的内容。
    3 已知主机文件的内容。

    如果您省略已知主机文件,OpenShift Pipelines 将接受任何服务器的公钥。

  3. 可选:通过在注解值的末尾添加:<port_number>来指定自定义 SSH 端口。例如,tekton.dev/git-0: github.com:2222

  4. serviceaccount.yaml文件中创建服务账户的 YAML 清单。在此清单中,将密钥与服务账户关联。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: build-bot (1)
    secrets:
      - name: ssh-key (2)
    1 服务账户名称。在此示例中为build-bot
    2 包含 SSH 私钥的密钥名称。在此示例中为ssh-key
  5. run.yaml文件中,将服务账户与任务运行或管道运行关联。使用以下示例之一

    • 将服务账户与任务运行关联

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: build-push-task-run-2 (1)
      spec:
        taskRunTemplate:
          serviceAccountName: build-bot (2)
        taskRef:
          name: build-push (3)
      1 任务运行名称。在此示例中为build-push-task-run-2
      2 服务账户名称。在此示例中为build-bot
      3 任务名称。在此示例中为build-push
    • 将服务账户与管道运行关联

      apiVersion: tekton.dev/v1
      kind: PipelineRun
      metadata:
        name: demo-pipeline (1)
        namespace: default
      spec:
        taskRunTemplate:
          serviceAccountName: build-bot (2)
        pipelineRef:
          name: demo-pipeline (3)
      1 管道运行名称。在此示例中为demo-pipeline
      2 服务账户名称。在此示例中为build-bot
      3 管道名称。在此示例中为demo-pipeline
  6. 应用更改。

    $ oc apply --filename secret.yaml,serviceaccount.yaml,run.yaml

使用服务账户配置容器注册表身份验证

为了使管道能够从注册表检索容器镜像或将容器镜像推送到注册表,您必须为此注册表配置身份验证。

要为管道配置注册表身份验证,请使用 Docker 配置文件创建一个身份验证密钥,将此密钥与服务账户关联,并将此服务账户与TaskRunPipelineRun资源关联。

步骤
  1. 通过输入以下命令,从包含身份验证信息的现有config.json文件创建容器注册表身份验证密钥

    $ oc create secret generic my-registry-credentials \ (1)
      --from-file=config.json=/home/user/credentials/config.json (2)
    
    1 密钥名称,在此示例中为my-registry-credentials
    2 config.json文件的路径名,在此示例中为/home/user/credentials/config.json
  2. serviceaccount.yaml文件中创建服务账户的 YAML 清单。在此清单中,将密钥与服务账户关联。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: container-bot (1)
    secrets:
      - name: my-registry-credentials (2)
    1 服务账户名称。在此示例中为container-bot
    2 包含 SSH 私钥的密钥名称。在此示例中为my-registry-credentials
  3. 创建一个 YAML 清单作为run.yaml文件用于任务运行或管道运行。在此文件中,将服务账户与任务运行或管道运行关联。使用以下示例之一

    • 将服务账户与任务运行关联

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: build-container-task-run-2 (1)
      spec:
        taskRunTemplate:
          serviceAccountName: container-bot (2)
        taskRef:
          name: build-container (3)
      1 任务运行名称。在此示例中为build-container-task-run-2
      2 服务账户名称。在此示例中为container-bot
      3 任务名称。在此示例中为build-container
    • 将服务账户与管道运行关联

      apiVersion: tekton.dev/v1
      kind: PipelineRun
      metadata:
        name: demo-pipeline (1)
        namespace: default
      spec:
        taskRunTemplate:
          serviceAccountName: container-bot (2)
        pipelineRef:
          name: demo-pipeline (3)
      1 管道运行名称。在此示例中为demo-pipeline
      2 服务账户名称。在此示例中为container-bot
      3 管道名称。在此示例中为demo-pipeline
  4. 通过输入以下命令应用更改

    $ oc apply --filename serviceaccount.yaml,run.yaml

使用服务帐户进行身份验证的其他注意事项

在某些情况下,您必须完成其他步骤才能使用您使用服务帐户提供的身份验证密钥。

任务中的 SSH Git 身份验证

您可以在任务步骤中直接调用 Git 命令并使用 SSH 身份验证,但是您必须完成一个额外的步骤。

OpenShift Pipelines 在/tekton/home/.ssh目录中提供 SSH 文件,并将$HOME变量设置为/tekton/home。但是,Git SSH 身份验证会忽略$HOME变量,并使用/etc/passwd文件中为用户指定的 home 目录。因此,使用 Git 命令的步骤必须将/tekton/home/.ssh目录符号链接到关联用户的 home 目录。

例如,如果任务以root用户身份运行,则步骤必须在 Git 命令之前包含以下命令:

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: example-git-task
spec:
  steps:
    - name: example-git-step
#     ...
      script:
        ln -s $HOME/.ssh /root/.ssh
#     ...

但是,当您使用git类型或Tekton目录中提供的git-clone任务的流水线资源时,不需要显式符号链接。

有关在git类型任务中使用 SSH 身份验证的示例,请参考authenticating-git-commands.yaml

以非root用户身份使用密钥

在某些情况下,您可能需要以非root用户身份使用密钥,例如:

  • 平台会随机化容器用于执行运行的用户和组。

  • 任务中的步骤定义了非root安全上下文。

  • 任务指定了一个全局非root安全上下文,该上下文应用于任务中的所有步骤。

在这种情况下,请考虑以下以非root用户身份执行任务运行和流水线运行的方面:

  • Git 的 SSH 身份验证要求用户在/etc/passwd目录中配置有效的 home 目录。指定没有有效 home 目录的 UID 将导致身份验证失败。

  • SSH 身份验证会忽略$HOME环境变量。因此,您必须将OpenShift Pipelines定义的$HOME目录(/tekton/home)中的相应密钥文件符号链接到非root用户的有效 home 目录。

此外,要配置非root安全上下文中的 SSH 身份验证,请参考身份验证 git 命令示例中的git-clone-and-check步骤。

使用工作区提供密钥

您可以使用工作区为 Git 存储库和容器存储库的身份验证提供密钥。

您可以在任务中配置命名工作区,并指定安装工作区的路径。运行任务时,将密钥作为此名称的工作区提供。当 OpenShift Pipelines 执行任务时,密钥中的信息可供任务使用。

如果您使用工作区提供身份验证密钥,则不需要密钥的注释。

使用工作区配置 Git 的 SSH 身份验证

为了使管道能够从使用 SSH 密钥配置的存储库检索资源,您必须为此管道配置基于 SSH 的身份验证。

要为流水线配置基于 SSH 的身份验证,请创建一个包含 SSH 私钥的身份验证密钥,在任务中为此密钥配置命名工作区,并在运行任务时指定该密钥。

步骤
  1. 通过输入以下命令,从现有.ssh目录中的文件创建 Git SSH 身份验证密钥:

    $ oc create secret generic my-github-ssh-credentials \ (1)
      --from-file=id_ed25519=/home/user/.ssh/id_ed25519 \ (2)
      --from-file=known_hosts=/home/user/.ssh/known_hosts (3)
    
    1 密钥名称,在此示例中为my-github-ssh-credentials
    2 私钥文件的名称和完整路径名,在此示例中为/home/user/.ssh/id_ed25519
    3 已知主机文件的名称和完整路径名,在此示例中为/home/user/.ssh/known_hosts
  2. 在您的任务定义中,为 Git 身份验证配置命名工作区,例如ssh-directory

    工作区定义示例:
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: git-clone
    spec:
      workspaces:
        - name: ssh-directory
          description: |
            A .ssh directory with private key, known_hosts, config, etc.
  3. 在任务步骤中,使用$(workspaces.<workspace_name>.path)环境变量中的路径访问目录,例如$(workspaces.ssh-directory.path)

  4. 运行任务时,通过在tkn task start命令中包含--workspace参数来指定命名工作区的密钥

    $ tkn task start <task_name>
          --workspace name=<workspace_name>,secret=<secret_name> (1)
          # ...
    1 <workspace_name>替换为您配置的工作区名称,并将<secret_name>替换为您创建的密钥名称。
使用 SSH 密钥进行身份验证克隆 Git 存储库的任务示例:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
spec:
  workspaces:
    - name: output
      description: The git repo will be cloned onto the volume backing this Workspace.
    - name: ssh-directory
      description: |
        A .ssh directory with private key, known_hosts, config, etc. Copied to
        the user's home before git commands are executed. Used to authenticate
        with the git remote when performing the clone. Binding a Secret to this
        Workspace is strongly recommended over other volume types
  params:
    - name: url
      description: Repository URL to clone from.
      type: string
    - name: revision
      description: Revision to checkout. (branch, tag, sha, ref, etc...)
      type: string
      default: ""
    - name: gitInitImage
      description: The image providing the git-init binary that this Task runs.
      type: string
      default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.37.0"
  results:
    - name: commit
      description: The precise commit SHA that was fetched by this Task.
    - name: url
      description: The precise URL that was fetched by this Task.
  steps:
    - name: clone
      image: "$(params.gitInitImage)"
      script: |
        #!/usr/bin/env sh
        set -eu
        # This is necessary for recent version of git
        git config --global --add safe.directory '*'
        cp -R "$(workspaces.ssh-directory.path)" "${HOME}"/.ssh (1)
        chmod 700 "${HOME}"/.ssh
        chmod -R 400 "${HOME}"/.ssh/*
        CHECKOUT_DIR="$(workspaces.output.path)/"
        /ko-app/git-init \
          -url="$(params.url)" \
          -revision="$(params.revision)" \
          -path="${CHECKOUT_DIR}"
        cd "${CHECKOUT_DIR}"
        RESULT_SHA="$(git rev-parse HEAD)"
        EXIT_CODE="$?"
        if [ "${EXIT_CODE}" != 0 ] ; then
          exit "${EXIT_CODE}"
        fi
        printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
        printf "%s" "$(params.url)" > "$(results.url.path)"
1 该脚本将密钥的内容(以文件夹的形式)复制到${HOME}/.ssh,这是ssh搜索凭据的标准文件夹。
运行任务的命令示例:
$ tkn task start git-clone
      --param [email protected]:example-github-user/buildkit-tekton
      --workspace name=output,emptyDir=""
      --workspace name=ssh-directory,secret=my-github-ssh-credentials
      --use-param-defaults --showlog

使用工作区配置容器注册表身份验证

要使流水线能够从注册表检索容器映像,您必须为此注册表配置身份验证。

要为容器注册表配置身份验证,请创建一个包含 Docker 配置文件的身份验证密钥,在任务中为此密钥配置命名工作区,并在运行任务时指定该密钥。

步骤
  1. 通过输入以下命令,从包含身份验证信息的现有config.json文件创建容器注册表身份验证密钥

    $ oc create secret generic my-registry-credentials \ (1)
      --from-file=config.json=/home/user/credentials/config.json (2)
    
    1 密钥名称,在此示例中为my-registry-credentials
    2 config.json文件的路径名,在此示例中为/home/user/credentials/config.json
  2. 在您的任务定义中,为 Git 身份验证配置命名工作区,例如ssh-directory

    工作区定义示例:
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: skopeo-copy
    spec:
      workspaces:
        - name: dockerconfig
          description: Includes a docker `config.json`
    # ...
  3. 在任务步骤中,使用$(workspaces.<workspace_name>.path)环境变量中的路径访问目录,例如$(workspaces.dockerconfig.path)

  4. 要运行任务,请通过在tkn task start命令中包含--workspace参数来指定命名工作区的密钥

    $ tkn task start <task_name>
          --workspace name=<workspace_name>,secret=<secret_name> (1)
          # ...
    1 <workspace_name>替换为您配置的工作区名称,并将<secret_name>替换为您创建的密钥名称。
使用 Skopeo 从容器存储库复制映像的任务示例:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: skopeo-copy
spec:
  workspaces:
    - name: dockerconfig (1)
      description: Includes a docker `config.json`
  steps:
    - name: clone
      image: quay.io/skopeo/stable:v1.8.0
      env:
      - name: DOCKER_CONFIG
        value: $(workspaces.dockerconfig.path) (2)
      script: |
        #!/usr/bin/env sh
        set -eu
        skopeo copy docker://docker.io/library/ubuntu:latest docker://quay.io/example_repository/ubuntu-copy:latest
1 包含config.json文件的工作区名称。
2 DOCKER_CONFIG环境变量指向dockerconfig工作区中config.json文件的位置。Skopeo 使用此环境变量获取身份验证信息。
运行任务的命令示例:
$ tkn task start skopeo-copy
      --workspace name=dockerconfig,secret=my-registry-credentials
      --use-param-defaults --showlog

使用工作区将密钥限制到特定步骤

当您使用工作区提供身份验证密钥并在任务中定义工作区时,默认情况下,所有步骤都可以访问该工作区。

要将密钥限制到特定步骤,请在任务规范和步骤规范中都定义工作区。

步骤
  • 在任务规范和步骤规范下添加workspaces:定义,如下例所示:

    只有其中一个步骤可以访问凭据工作区的任务定义示例:
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: git-clone-build
    spec:
      workspaces: (1)
        - name: ssh-directory
          description: |
            A .ssh directory with private key, known_hosts, config, etc.
    # ...
      steps:
        - name: clone
          workspaces: (2)
            - name: ssh-directory
    # ...
        - name: build (3)
    # ...
    1 任务规范中ssh-directory工作区的定义。
    2 步骤规范中ssh-directory工作区的定义。此步骤可以将身份验证信息作为$(workspaces.ssh-directory.path)目录访问。
    3 由于此步骤不包含ssh-directory工作区的定义,因此此步骤无法访问身份验证信息。