Gitlab CI对接Kubernetes Agent自签名证书x509报错问题咨询
问题现象
当前使用的.gitlab-ci.yml配置如下:
deploy: stage: deploy image: name: bitnami/kubectl:latest entrypoint: [''] script: - echo "Hello, Rules!" - kubectl config get-contexts - kubectl config use-context OurGroup/our-repo:agent-0 - kubectl get pods rules: - if: '$CI_COMMIT_REF_NAME == "master"' when: manual allow_failure: true - if: '$CI_COMMIT_REF_NAME == "develop"' when: manual allow_failure: true tags: - docker
执行流水线部署任务时触发两类报错:
- 连接Kubernetes API时报错:
Unable to connect to the server: x509: certificate signed by unknown authority - 部分kubectl命令执行时报错:无法连接localhost:8080
现有环境为使用自签名证书的自托管GitLab实例,选用bitnami/kubectl:latest镜像执行kubectl操作,该镜像默认以非root权限运行。尝试执行echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/my-ca.crt && update-ca-certificates命令注入CA证书时,因容器无系统目录写入权限、未预装sudo执行失败。
根因说明
- bitnami/kubectl镜像默认使用UID 1001的非root用户运行,对系统级证书存储目录
/usr/local/share/ca-certificates/无写入权限,无法直接更新系统信任链 - 若kubectl未正确加载GitLab Kubernetes Agent自动注入的kubeconfig文件,会默认尝试连接本地localhost:8080的API端点,触发连接失败
- 自签名CA证书未加入kubectl的信任列表,导致TLS握手阶段证书校验不通过
符合安全规范的解决方案
禁止使用--insecure-skip-tls-verify=true参数跳过TLS校验,该配置存在中间人攻击风险,不符合生产环境安全要求,可根据场景选择以下两种方案:
方案1:运行时加载证书(无需自定义镜像,快速落地)
该方案无需root权限,通过kubectl支持的用户级配置加载CA证书,步骤如下:
- 将自签名CA证书内容配置为GitLab项目/组级CI/CD文件类型变量,命名为
K8S_CA_CRT,开启变量掩码、仅保护分支可见规则,避免证书泄露 - 修改流水线脚本,将CA证书写入容器内当前用户可读写的
$HOME/.kube目录,通过kubectl配置指令为目标集群绑定CA证书,修改后的配置如下:
deploy: stage: deploy image: name: bitnami/kubectl:latest entrypoint: [''] script: - echo "Hello, Rules!" # 初始化用户kube配置目录,写入CA证书 - mkdir -p $HOME/.kube - cp "$K8S_CA_CRT" $HOME/.kube/my-ca.crt # 确认GitLab自动注入的kubeconfig路径,解决localhost:8080连接问题 - export KUBECONFIG=$KUBECONFIG - kubectl config get-contexts - kubectl config use-context OurGroup/our-repo:agent-0 # 为当前使用的集群设置CA证书路径 - CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}') - kubectl config set-cluster "$CLUSTER_NAME" --certificate-authority=$HOME/.kube/my-ca.crt - kubectl get pods rules: - if: '$CI_COMMIT_REF_NAME == "master"' when: manual allow_failure: true - if: '$CI_COMMIT_REF_NAME == "develop"' when: manual allow_failure: true tags: - docker
方案2:预构建自定义基础镜像(适合多任务复用场景)
如果团队内多个流水线任务都需要调用kubectl操作集群,可提前构建内置自签名CA证书的基础镜像,存放在内部私有镜像仓库,运行时无需额外处理证书逻辑:
- 编写Dockerfile,构建阶段切换root用户完成证书注入,构建完成后切回非root用户运行,符合最小权限要求:
FROM bitnami/kubectl:latest USER root # 将本地保存的自签名CA证书复制到系统证书目录 COPY my-ca.crt /usr/local/share/ca-certificates/my-ca.crt # 更新系统信任链 RUN update-ca-certificates # 切回原镜像默认非root用户运行 USER 1001
- 构建镜像并推送到内部可访问的私有镜像仓库后,直接将流水线中的镜像地址替换为自定义镜像地址即可,无需额外修改证书相关脚本。
注意:不要在流水线中硬编码任何kubeconfig凭证、CA证书内容,所有敏感信息统一通过GitLab CI/CD变量管理,自动注入到运行环境中。
内容的提问来源于stack exchange,提问作者Killerwife
相关产品推荐
相关产品推荐

