在 Tekton 中使用自定义镜像时遇到容器创建失败的问题

目录

问题描述

在 Tekton 流水线中,使用产品默认提供的镜像可以正常执行,但使用用户自定义镜像时可能会遇到 TaskRun 执行失败的问题。

错误表现

  1. TaskRun 执行失败,状态为 False,原因是 CreateContainerConfigError

    $ kubectl get taskruns -n ${namespace} ${taskrun_name}
    NAME                     SUCCEEDED   REASON                       STARTTIME   COMPLETIONTIME
    hello-c7pnj-run-script   False       CreateContainerConfigError   9m43s
  2. TaskRun 事件中显示错误信息:

    Failed: Failed to create pod due to config error
  3. 相关 Pod 事件中显示错误信息:

    Failed: Error: container's runAsUser breaks non-root policy

根因分析

此类问题通常由以下两个原因导致:

  1. 镜像本身存在问题。
  2. 镜像与 Task 的配置不兼容。

问题排查

如果该问题仅在使用自定义镜像时出现,建议按以下步骤排查:

  1. 验证镜像本身是否存在问题:

    $ docker run -it --rm ${registry} ${cmd}
  2. 检查 Task 配置与镜像的兼容性:

    • 检查 Task 是否配置了 runAsNonRoot: true
    • 检查镜像默认用户是否为 root 或非数字编号的用户 ID。

示例 Task 配置:

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: foo
spec:
  steps:
    - name: bar
      securityContext:
        runAsNonRoot: true

示例 Dockerfile 配置:

USER root

示例检查镜像默认用户

$ docker run -it --rm ${registry} id

# 表明镜像默认用户为 root
uid=0(root) gid=0(root) groups=0(root)

解决方案

方案一:调整镜像构建配置,设置默认用户为非 root 用户

前提条件

  • 具备重新构建镜像的环境和权限。

操作步骤

参考 调整 Dockerfile 构建适用于 Task 的自定义镜像 文档,调整 Dockerfile 的配置。

方案二:修改 TaskRun 或 PipelineRun 的运行配置

前提条件

  • 具备修改 TaskRun 或 PipelineRun 的权限。

操作步骤

  1. 单独执行 TaskRun 时添加配置:

    apiVersion: tekton.dev/v1
    kind: TaskRun
    metadata:
      name: foo
    spec:
      taskRef:
        name: foo
      podTemplate:
        securityContext:
          runAsUser: 65532
  2. 执行 PipelineRun 时添加配置:

    # 方式一:为所有 Task 添加配置
    apiVersion: tekton.dev/v1
    kind: PipelineRun
    spec:
      taskRunTemplate:
        podTemplate:
          securityContext:
            runAsUser: 65532
    
    # 方式二:为特定 Task 添加配置
    apiVersion: tekton.dev/v1
    kind: PipelineRun
    spec:
      taskRunSpecs:
        # 该 pipelineTaskName 为 Pipeline 中定义的 Task 名称
        - pipelineTaskName: example-git-clone
          podTemplate:
            securityContext:
              runAsUser: 65532
              fsGroup: 65532

方案三:修改全局 Tekton 配置

前提条件

  • 具备集群操作权限。
  • 具备 TektonConfig 资源的修改权限。
  • 注意:此配置会影响所有 Task。

操作步骤

  1. 修改 TektonConfig 资源: 增加如下的 spec.pipeline.default-pod-template 配置:

    apiVersion: config.tekton.dev/v1beta1
    kind: TektonConfig
    metadata:
      name: config
    spec:
      pipeline:
        default-pod-template: |
          securityContext:
            runAsUser: 65532
  2. 验证配置是否生效:

    $ kubectl get configmap -n tekton-pipelines config-defaults -o yaml | grep 'default-pod-template: |' -A2
    
    # 预期输出
    default-pod-template: |
      securityContext:
        runAsUser: 65532

方案四:修改 Task 定义

前提条件

  • 具备修改 Task 的权限。
  • 注意:此配置会影响所有使用到该 Task 的 TaskRun 或 PipelineRun。

操作步骤

  1. 方式一:移除 runAsNonRoot 配置:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: foo
    spec:
      steps:
        - name: bar
          securityContext:
            # 不限制容器必须以非 root 用户运行
            # runAsNonRoot: true
  2. 方式二:添加 runAsUser 配置:

    apiVersion: tekton.dev/v1
    kind: Task
    metadata:
      name: foo
    spec:
      steps:
        - name: bar
          securityContext:
            # 设置容器以非 root 用户运行
            runAsNonRoot: true
            runAsUser: 65532

预防错误

  1. 镜像构建

    • 优先使用非 root 用户构建镜像。
    • 统一使用 UID 65532 作为非 root 用户。
    • 确保应用程序能够以非 root 用户正常运行。
  2. Task 配置

    • 根据安全需求决定是否启用 runAsNonRoot
    • 如需启用,按需配置 runAsUser
  3. 权限管理

    • 遵循最小权限原则。
    • 提前规划好目录权限。
    • 定期审查权限配置。

相关内容