自签名证书或自定义证书颁发机构
引入于极狐GitLab Runner 0.7.0。
极狐GitLab Runner 提供两种配置用于验证 TLS 对端的证书的选项。
-
对于连接到极狐GitLab 服务器:可以按照极狐GitLab 服务器自签名证书的支持选项部分中介绍的内容指定证书文件。
解决了注册 Runner 时的
x509: certificate signed by unknown authority
问题。对于现存 Runner,当检查作业时,可以在 Runner 日志中看到相同的错误:
Couldn't execute POST against https://hostname.tld/api/v4/jobs/request: Post https://hostname.tld/api/v4/jobs/request: x509: certificate signed by unknown authority
-
适用如用户脚本、连接缓存服务器或外部 Git LFS 存储等其他场景的一个更加通用的方法:可以按照 Docker 和 Kubernetes 执行器的信任 TLS 证书部分中介绍的内容指定证书并在容器上安装。
关于缺少证书的 Git LFS 操作的作业日志错误示例:
LFS: Get https://object.hostname.tld/lfs-dev/c8/95/a34909dce385b85cee1a943788044859d685e66c002dbf7b28e10abeef20?X-Amz-Expires=600&X-Amz-Date=20201006T043010Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=svcgitlabstoragedev%2F20201006%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=012211eb0ff0e374086e8c2d37556f2d8ca4cc948763e90896f8f5774a100b55: x509: certificate signed by unknown authority
极狐GitLab 服务器自签名证书的支持选项
本部分介绍仅极狐GitLab 服务器需要自定义证书的情况。 如果其他主机(例如没有启用代理下载的对象存储服务)也需要自定义证书颁发机构(CA),请参见下一部分。
极狐GitLab Runner 支持下列选项:
-
默认 - 读取系统证书:极狐GitLab Runner 读取系统证书存储并依照存储在系统中的 CA 验证极狐GitLab 服务器。需要注意,Windows 不支持 从系统证书存储读取。
-
指定自定义证书文件:极狐GitLab Runner 在注册(
gitlab-runner register --tls-ca-file=/path
)中展示tls-ca-file
选项, 并且它在[[runners]]
部分的config.toml
中。 允许您指定自定义证书文件。 每次 Runner 试图访问极狐GitLab 服务器时,都会读取这个文件。 如果您使用的是极狐GitLab Runner Helm chart,您需要按照为访问极狐GitLab 提供自定义证书中的描述配置证书。 -
读取 PEM 证书:极狐GitLab Runner 从预定义的文件中读取证书(不支持 DER 格式):
-
当极狐GitLab Runner 以
root
用户身份执行时,是 *nix 系统上的/etc/gitlab-runner/certs/gitlab.example.com.crt
。如果您的服务器地址是
https://gitlab.example.com:8443/
,那么在/etc/gitlab-runner/certs/gitlab.example.com.crt
中创建证书文件。您可以使用
openssl
客户端将极狐GitLab 实例的证书下载到/etc/gitlab-runner/certs
:openssl s_client -showcerts -connect gitlab.example.com:443 -servername gitlab.example.com < /dev/null 2>/dev/null | openssl x509 -outform PEM > /etc/gitlab-runner/certs/gitlab.example.com.crt
您可以使用
openssl
这样的工具验证已正确安装了文件。例如:echo | openssl s_client -CAfile /etc/gitlab-runner/certs/gitlab.example.com.crt -connect gitlab.example.com:443 -servername gitlab.example.com
- 当极狐GitLab Runner 以非
root
用户身份执行时,是 *nix 系统上的~/.gitlab-runner/certs/gitlab.example.com.crt
。 - 其他系统上的
./certs/gitlab.example.com.crt
。如果极狐GitLab Runner 作为 Windows 服务运行,这无法生效,您需要指定自定义证书文件。
-
Notes:
-
如果您的极狐GitLab 服务器证书是由 CA 签署的,那么使用 CA 证书 (不是您的极狐GitLab 服务器签名的证书)。您或许也需要向链添加中级证书。 例如,如果您有初级、中级和根证书, 您可以把他们放入同一个文件中。
-----BEGIN CERTIFICATE----- (Your primary SSL certificate: your_domain_name.crt) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your intermediate certificate) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your root certificate) -----END CERTIFICATE-----
- 如果您为现存 Runner 更新证书,重启它。
- 如果您已经通过 HTTP 配置了 Runner,请将您的实例路径更新为
config.toml
中极狐GitLab 实例的新 HTTPS URL。 - 一个临时且不安全的解决方法是跳过证书验证,在
.gitlab-ci.yml
文件中的variables:
部分,将 CI 变量GIT_SSL_NO_VERIFY
设置为true
。
Git 克隆
Runner 使用 CI_SERVER_TLS_CA_FILE
注入缺失的证书以构建 CA 链。
这允许 git clone
和产物与不使用公开信任的证书的服务器一同工作。
这种方法很安全,但让 Runner 成为了单点信任。
Docker 和 Kubernetes 执行器的信任 TLS 证书
当我们想在容器上注册证书时,需要考虑两个上下文:
-
用户镜像,用于运行用户脚本。 在这种情况下,用户必须掌握如何安装证书,因为它高度依赖镜像本身,并且 Runner 不知道如何在每个可能的场景中安装证书。
-
Runner Helper 镜像用于处理 Git、产物和缓存操作。在这种情况下,用户仅需要在特定位置使证书文件可用(例如,
/etc/gitlab-runner/certs/ca.crt
)。Docker 容器会自动为用户安装。
信任用户脚本证书
如果您的构建脚本需要与对端通过 TLS 通信,并且需要依赖自签名证书或自定义 CA,您需要在构建作业中安装证书,因为运行用户脚本的 Docker 容器默认没有安装证书文件。这可能需要使用自定义缓存主机,进行次要 git clone
,或通过类似 wget
的工具获取文件。
安装证书步骤如下:
-
将必要文件映射为 Docker 卷,这样运行脚本的 Docker 容器就可以看见它们了。 您可以通过将卷添加到
config.toml
文件的[runners.docker]
的密钥中来实现。 例如:-
Linux:
[[runners]] name = "docker" url = "https://example.com/" token = "TOKEN" executor = "docker" [runners.docker] image = "ubuntu:latest" # Add path to your ca.crt file in the volumes list volumes = ["/cache", "/path/to-ca-cert-dir/ca.crt:/etc/gitlab-runner/certs/ca.crt:ro"]
-
-
仅 Linux:使用
pre_build_script
中映射的文件(例如ca.crt
),这些pre_build_script
:- 将其复制到 Docker 容器中的
/usr/local/share/ca-certificates/ca.crt
。 -
通过运行
update-ca-certificates --fresh
安装它。例如(命令根据您使用的分布而有所不同):-
在 Ubuntu 上:
[[runners]] name = "docker" url = "https://example.com/" token = "TOKEN" executor = "docker" # Copy and install CA certificate before each job pre_build_script = """ apt-get update -y > /dev/null apt-get install -y ca-certificates > /dev/null cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt update-ca-certificates --fresh > /dev/null """
-
在 Alpine 上:
[[runners]] name = "docker" url = "https://example.com/" token = "TOKEN" executor = "docker" # Copy and install CA certificate before each job pre_build_script = """ apk update >/dev/null apk add ca-certificates > /dev/null rm -rf /var/cache/apk/* cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt update-ca-certificates --fresh > /dev/null """
-
- 将其复制到 Docker 容器中的
如果您仅需要可以使用的极狐GitLab 服务器 CA cert,您可以从存储在 CI_SERVER_TLS_CA_FILE
变量的文件对其进行检索。
curl --cacert "${CI_SERVER_TLS_CA_FILE}" ${URL} -o ${FILE}
信任其他 CI/CD 阶段的证书
引入于极狐GitLab 13.3。
您可以在 Linux 或 Windows 上将证书文件分别映射到 /etc/gitlab-runner/certs/ca.crt
或 C:\GitLab-Runner\certs\ca.crt
。
Runner Helper 镜像在开始阶段安装用户定义的 ca.crt
文件,
并在进行克隆或上传产物等操作时使用它。
Docker
-
Linux:
[[runners]] name = "docker" url = "https://example.com/" token = "TOKEN" executor = "docker" [runners.docker] image = "ubuntu:latest" # Add path to your ca.crt file in the volumes list volumes = ["/cache", "/path/to-ca-cert-dir/ca.crt:/etc/gitlab-runner/certs/ca.crt:ro"]
-
Windows:
[[runners]] name = "docker" url = "https://example.com/" token = "TOKEN" executor = "docker" [runners.docker] image = "mcr.microsoft.com/windows/servercore:21H2" # Add directory holding your ca.crt file in the volumes list volumes = ["c:\\cache", "c:\\path\\to-ca-cert-dir:C:\\GitLab-Runner\\certs:ro"]
Kubernetes
为 Kubernetes 中运行的作业提供证书文件:
-
将证书作为 Kubernetes secret 存储在您的命名空间中:
kubectl create secret generic <SECRET_NAME> --namespace <NAMESPACE> --from-file=<CERT_FILE>
-
将 secret 作为卷挂载在您的 Runner 中,用适当的值替换
<SECRET_NAME>
和<LOCATION>
:gitlab-runner: runners: config: | [[runners]] [runners.kubernetes] namespace = "{{.Release.Namespace}}" image = "ubuntu:latest" [[runners.kubernetes.volumes.secret]] name = "<SECRET_NAME>" mount_path = "<LOCATION>"
mount_path
是容器中存储证书的目录。 如果您将/etc/gitlab-runner/certs/
用作mount_path
并且将ca.crt
用作您的证书文件,您的证书将在您容器中的/etc/gitlab-runner/certs/ca.crt
中可用。 -
作为作业的一部分,将映射的证书文件安装到系统证书存储区。 例如,在 Ubuntu 容器中:
script: - cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ - update-ca-certificates
由于 Kubernetes 执行器在处理 Helper 镜像的 ENTRYPOINT
时存在的问题,映射的证书文件不会自动安装到系统证书存储。
故障排查
请参考通用的 SSL 故障排查文档。
此外,您可以使用 tlsctl
工具从 Runner 端调试极狐GitLab 证书。
当尝试从私有镜像仓库拉取执行器镜像时报错 x509: certificate signed by unknown authority
当 runner 被调度到的 Docker 主机或 Kubernetes 节点不信任私有镜像仓库使用的证书时,就会出现此错误。为了解决此错误,请将相关的根证书颁发机构或证书链添加到系统的信任存储中,并重新启动容器服务。
如果您使用的是 Ubuntu 或 Alpine,请运行以下命令:
cp ca.crt /usr/local/share/ca-certificates/ca.crt
update-ca-certificates
systemctl restart docker.service
如果您使用的是其他操作系统,请阅读操作系统的文档以查找安装受信任证书的适当命令。
取决于您的极狐GitLab Runner 版本和 Docker 主机环境,您还可能需要禁用 FF_RESOLVE_FULL_TLS_CHAIN
功能标志。
在作业中出现 apt-get: not found
错误
在 runner 执行时,pre_build_script
命令在每个作业之前执行。如果您添加特定于某些发行版的命令,例如,当您为用户脚本安装证书时,使用 apk
或 apt-get
,则您的 CI 作业可能会失败,如果它们使用基于不同发行版的镜像。
例如,如果您的某些 CI 作业基于 Ubuntu 镜像而运行,而有些基于 Alpine 镜像而运行,并且您添加了 Ubuntu 命令,那么在 Alpine 基础镜像的作业中就会出现 apt-get: not found
错误。要解决此问题,您可以:
- 将
pre_build_script
编写为与发行版无关。 - 使用标签来确保 runner 只获取与镜像兼容的作业。