gitlab version: gitlab helm chart 2.3.2,此版本前后应该都有这个问题。

使用 helm charts 安装完成后,使用 CI/CD 功能时,发现 job日志中关于 cache 的部分给出如下信息:

Checking cache for develop...
No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted.

Creating cache develop...
/builds/fengxin58/echoheader/.m2/repository/: found 2126 matching files
No URL provided, cache will be not uploaded to shared cache server. Cache will be stored only locally.
Created cache

在 gitlab runner pod 的日志中发现如下的日志:

error while generating S3 pre-signed URL

在 gitlab runner 源码中查询如上的关键字,定位到 gitlab runner 源码的 cache 部分。
通过查看 gitlab runner 源码得知,git runner 使用 minio-go 作为支持 s3 协议的存储的客户端。

于是查找 gitlab runner 源码和 minio-go 参考文档,查看 gitlab runner 中是如何使用 minio-go 这个 s3 协议的 sdk的。

查找 minio-go 的用法,得知 minio-go 中初始化一个 MinIO Client(S3 Client)必备的参数有 CACHE_S3_SERVER_ADDRESS,CACHE_S3_ACCESS_KEY 和 CACHE_S3_SECRET_KEY ,还有一个是否开启 SSL 的标识。

根据 gitlab 中的惯例,查看 gitlab runner pod 的环境变量,发现只有 CACHE_S3_SERVER_ADDRESS,没有 CACHE_S3_ACCESS_KEY 和 CACHE_S3_SECRET_KEY 的值。

gitlab helm charts 安装时,会生成名为 {deploy-name}-minio-secret 的 kubernetes secret ,里面存储的就是 minio server 的 用户名和密码(accesskey 和 secretkey)。于是猜测可能是 gitlab runner 启动时自动读取的这个 secret 里的内容,这样可以不需要外部设置环境变量。

查找 gitlab runner 的启动文件,在 gitlab runner 中查找到此镜像的入口文件内容如下:

#!/bin/bash
set -e
mkdir -p /home/gitlab-runner/.gitlab-runner/
cp /scripts/config.toml /home/gitlab-runner/.gitlab-runner/

# Register the runner
if [[ -f /secrets/accesskey && -f /secrets/secretkey ]]; then
export CACHE_S3_ACCESS_KEY=$(cat /secrets/accesskey)
export CACHE_S3_SECRET_KEY=$(cat /secrets/secretkey)
fi

if [[ -f /secrets/gcs-applicaton-credentials-file ]]; then
export GOOGLE_APPLICATION_CREDENTIALS="/secrets/gcs-applicaton-credentials-file"
else
if [[ -f /secrets/gcs-access-id && -f /secrets/gcs-private-key ]]; then
export CACHE_GCS_ACCESS_ID=$(cat /secrets/gcs-access-id)
# echo -e used to make private key multiline (in google json auth key private key is oneline with \n)
export CACHE_GCS_PRIVATE_KEY=$(echo -e $(cat /secrets/gcs-private-key))
fi
fi

if [[ -f /secrets/runner-registration-token ]]; then
export REGISTRATION_TOKEN=$(cat /secrets/runner-registration-token)
fi

if [[ -f /secrets/runner-token ]]; then
export CI_SERVER_TOKEN=$(cat /secrets/runner-token)
fi

if ! sh /scripts/register-the-runner; then
exit 1
fi

# Start the runner
exec /entrypoint run --user=gitlab-runner \
--working-directory=/home/gitlab-runner

在 pod 中访问 kubernetes secret 的内容只有一种方式,就是将 secret 挂载到 pod 中,于是去查看 gitlab runner 的 deployment 文件,发现没有挂载 minio-secret 这个 secret。

在 gitlab runner 中使用 env 命令查看所有的环境变量,再次验证 CACHE_S3_ACCESS_KEY 和 CACHE_S3_SECRET_KEY 确实没有。

可以确认是 gitlab 忘记挂载了这个 secret 。

知道了问题。对症下药即可,找到 gitlab runner 的 deployment,可以使用如下的重新生成查看

$ helm install gitlab/gitlab -f values.yaml --dry-run --debug >> gitlab-tmp.yaml

找到 gitlab runner 的 deployment 部分,增加 {deploy-name}-minio-secret 的挂载即可。

也即可直接给 gitlab runner 添加 CACHE_S3_ACCESS_KEY 和 CACHE_S3_SECRET_KEY 两个环境变量。gitlab runner 的 deployment 里有很多的环境变量,增加上这两个即可,值就是 {deploy-name}-minio-secret 这个 secret 的值。

参考

​MinIO Go Client API Reference​​​​gitlabhq/gitlab-runner​