在 OpenShift 上配置极狐GitLab Runner

本文档描述如何在 OpenShift 上配置极狐GitLab Runner。

向极狐GitLab Runner 执行器传递属性

当创建 Runner 时,您可以通过在它的 spec 中设置属性来配置。例如,您可以指定它将要注册到的极狐GitLab URL,或者包含注册令牌的密钥的名称:

apiVersion: apps.gitlab.com/v1beta2
kind: Runner
metadata:
 name: dev
spec:
 gitlabUrl: https://gitlab.example.com
 token: gitlab-runner-secret # Name of the secret containing the Runner token

所有可用属性请参见运算符属性

运算符属性

以下是可以传递给运算符的支持的属性列表。

一些属性只有在新版本运算符中可用。

设置 运算符 描述
gitlabUrl 所有 极狐GitLab 实例的完全限定域名,如 https://gitlab.example.com
token 所有 包含用于注册 Runner 的 runner-registration-token key 的 Secret 的名称。
tags 所有 应用于 Runner 的以逗号分隔的标签的列表。
concurrent 所有 限定可以并发运行的作业的数量。最大数量是所有定义的 Runner。0 不表示无限。默认为 10
interval 所有 定义检查新作业的秒数。默认为 30
locked 1.8 定义 Runner 是否应该被锁定到项目。默认为 false
runUntagged 1.8 定义是否应该运行无标签的作业。如果没有指定标签,默认为 true,否则为 false
protected 1.8 定义 Runner 是否应该只在受保护的分支上运行作业。默认为 false
cloneURL 所有 覆盖极狐GitLab 实例的 URL。只有在 Runner 无法连接到极狐GitLab URL 的时候使用。
env 所有 包含作为环境变量注入到 Runner pod 的键值对的 ConfigMap 的名称。
runnerImage 1.7 覆盖默认的极狐GitLab Runner 镜像。默认的是运算符绑定的 Runner 镜像。
helperImage 所有 覆盖默认的极狐GitLab Runner helper 镜像。
buildImage 所有 当没有指定 Docker 镜像时,用于作业的默认的 Docker 镜像。
cacheType 所有 用于 Runner 产物的缓存类型。gcss3azure 中的一个。
cachePath 所有 定义文件系统上的缓存路径。
cacheShared 所有 在 Runner 之间启用缓存共享。
s3 所有 用于设置 S3 缓存的选项。详情请参考缓存属性
gcs 所有 用于设置 GCS 缓存的选项。详情请参考缓存属性
azure 所有 用于设置 Azure 缓存的选项。详情请参考缓存属性
ca 所有 包含自定义 CA 证书的 TLS 密钥的名称。
serviceAccount 所有 用于覆盖用于运行 Runner pod 的服务账号。
config 所有 用于通过配置模板提供自定义的配置 map。

缓存属性

S3 缓存

设置 运算符 描述
server 所有 S3 服务器地址。
credentials 所有 包含用于访问对象存储的 accesskeysecretkey 属性的 Secret 的名称。
bucket 所有 存储缓存的桶的名称。
location 所有 存储缓存的 S3 区域的名称。
insecure 所有 使用不安全的连接或 HTTP

GCS 缓存

设置 运算符 描述
credentials 所有 包含用于访问对象存储的 access-idprivate-keySecret 的名称。
bucket 所有 存储缓存的桶的名称。
credentialsFile 所有 取 GCS 凭证文件 keys.json

Azure 缓存

设置 运算符 描述
credentials 所有 包含用于访问对象存储的 accountNameprivateKey 属性的 Secret 的名称。
container 所有 存储缓存的 Azure 容器的名称。
storageDomain 所有 Azure blob 存储的域名。

配置代理环境

创建代理环境:

  1. 编辑 custom-env.yaml 文件。例如:

    apiVersion: v1
    data:
      HTTP_PROXY: example.com
    kind: ConfigMap
    metadata:
      name: custom-env
    
  2. 更新 OpenShift 以应用更改。

    oc apply -f custom-env.yaml
    
  3. 更新您的 gitlab-runner.yml 文件。

    apiVersion: apps.gitlab.com/v1beta2
    kind: Runner
    metadata:
      name: dev
    spec:
      gitlabUrl: https://gitlab.example.com
      token: gitlab-runner-secret # Name of the secret containing the Runner token
      env: custom-env
    

如果代理无法访问 Kubernetes API,您会在您的 CI/CD 作业中看到如下报错信息:

ERROR: Job failed (system failure): prepare environment: setting up credentials: Post https://172.21.0.1:443/api/v1/namespaces/<KUBERNETES_NAMESPACE>/secrets: net/http: TLS handshake timeout. Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information

为解决这个错误,需要在 custom-env.yaml 文件的 NO_PROXY 配置中添加 Kubernetes API 的 IP 地址:

   apiVersion: v1
   data:
     NO_PROXY: 172.21.0.1
     HTTP_PROXY: example.com
   kind: ConfigMap
   metadata:
     name: custom-env

您可以通过运行如下命令验证 Kubernetes API 的 IP 地址:

oc get services --namespace default --field-selector='metadata.name=kubernetes' | grep -v NAME | awk '{print $3}'

通过配置模板自定义 config.toml

note 使用配置模板自定义 config.toml 当前仅限于指定 [runners.kubernetes.volumes] 设置。

您可以使用配置模板自定义 runner config.toml 文件。

  1. 创建自定义配置模板文件。例如,我们构建 Runner 挂载 EmptyDir 卷。创建 custom-config.toml 文件:

    [[runners]]
      [runners.kubernetes]
        [runners.kubernetes.volumes]
          [[runners.kubernetes.volumes.empty_dir]]
            name = "empty-dir"
            mount_path = "/path/to/empty_dir"
            medium = "Memory"
    
  2. 从我们的 custom-config.toml 文件创建名为 custom-config-tomlConfigMap

     oc create configmap custom-config-toml --from-file config.toml=custom-config.toml
    
  3. 设置 Runnerconfig 属性:

     apiVersion: apps.gitlab.com/v1beta2
     kind: Runner
     metadata:
       name: dev
     spec:
       gitlabUrl: https://gitlab.example.com
       token: gitlab-runner-secret
       config: custom-config-toml
    

配置自定义 TLS cert

  1. 为设置自定义 TLS cert,用 key tls.crt 创建密钥。 在这个例子中,文件的名称是 custom-tls-ca-secret.yaml

     apiVersion: v1
     kind: Secret
     metadata:
         name: custom-tls-ca
     type: Opaque
     stringData:
         tls.crt: |
             -----BEGIN CERTIFICATE-----
             MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix
             .....
             7vQMfXdGsRrXNGRGnX+vWDZ3/zWI0joDtCkNnqEpVn..HoX
             -----END CERTIFICATE-----
    
  2. 创建密钥:

    oc apply -f custom-tls-ca-secret.yaml
    
  3. runner.yaml 中,将 ca key 的名称设置成我们的密钥的名称:

     apiVersion: apps.gitlab.com/v1beta2
     kind: Runner
     metadata:
       name: dev
     spec:
       gitlabUrl: https://gitlab.example.com
       token: gitlab-runner-secret
       ca: custom-tls-ca
    

配置 Runner Pod 的 CPU 和内存

基于集群资源配置每个 Runner 的作业并发

设置 Runner 资源的 concurrent 属性:

   apiVersion: apps.gitlab.com/v1beta2
   kind: Runner
   metadata:
     name: dev
   spec:
     gitlabUrl: https://gitlab.example.com
     token: gitlab-runner-secret
     concurrent: 2

作业并发由项目的要求决定。

  1. 尝试判断执行 CI 作业所需的计算和内存资源。
  2. 计算作业能够执行集群中给定资源的次数。

如果您将并发值设置得过大,Kubernetes 执行器会尽快处理作业。 然而,Kubernetes 集群的调度器容量决定了调度作业的时间。

故障排除

根 vs 非根

极狐GitLab Runner 运算符和极狐GitLab Runner pod 以非根用户运行。因此,作业中使用的构建镜像需要以非根用户运行,用以成功完成。 这是为了确保作业能够以最小的权限运行成功。然而为了达到这个目的, CI 作业的构建镜像也需要构建为以非根的形式运行,且不应该写入限制文件系统。记住大多数 OpenShift 集群上的容器文件系统是只读的,除了挂载卷、 /var/tmp/tmp 和其他以 tmpfs 挂载到根文件系统的卷。

覆盖 HOME 环境变量

如果创建自定义构建镜像或覆盖 env 变量,请确保环境变量没有被设置为只读的 /。 特别是当您的作业需要向主目录写入文件时。 您需要在 /home 下面创建一个目录,如 /home/ci,并在您的 Dockerfile 中设置 ENV HOME=/home/ci

注意 SCC

默认情况下,当安装了新的 OpenShift 项目,极狐GitLab Runner 运算符会以非根形式运行。 但也有例外,当项目中的所有服务账户被授以 anyuid 访问权限,如 default 项目。 在那种情况下,镜像的用户会是 root。通过在任意容器 shell(例如作业)中运行 whoami 可以轻松进行检查。 详情请参见 Red Hat 容器平台文档 > 管理安全上下文约束

以 anyuid SCC 运行

尽管不鼓励,但是在 CI 作业绝对必要以根用户运行或写入到根文件系统的情况下, 您需要在极狐GitLab Runner 容器所使用的极狐GitLab Runner 服务账户 gitlab-runner-sa 上设置 anyuid SCC。

oc adm policy add-scc-to-user anyuid -z gitlab-runner-sa -n <runner_namespace>

# Check that the anyiud SCC is set:
oc get scc anyuid -o yaml

配置 SETFCAP

如果您使用 Red Hat OpenShift Container Platform (RHOCP) 4.11 或更高版本,您可能会收到以下错误消息:

error reading allowed ID mappings:error reading subuid mappings for user

某些作业(例如 buildah)需要授予 SETFCAP 功能才能正确运行。要解决此问题:

  1. 将 SETFCAP 功能添加到极狐GitLab Runner 正在使用的 SCC(将 gitlab-scc 替换为分配给您的极狐GitLab Runner pod 的 SCC):

     oc patch scc gitlab-scc --type merge -p '{"allowedCapabilities":["SETFCAP"]}'  
    
  2. 更新您的 config.toml 并在 kubernetes 部分下添加 SETFCAP 功能:

     [[runners]]
       [runners.kubernetes]
       [runners.kubernetes.pod_security_context]
         [runners.kubernetes.build_container_security_context]
         [runners.kubernetes.build_container_security_context.capabilities]
           add = ["SETFCAP"]
    
  3. 在部署极狐GitLab Runner 的命名空间中使用此 config.toml 创建一个 configmap:

     oc create configmap custom-config-toml --from-file config.toml=config.toml 
    
  4. 修改您要修复的 Runner,添加 config: 参数以指向最近创建的 configmap(将 my-runner 替换为正确的 Runner pod 名称)。

     oc patch runner my-runner --type merge -p '{"spec": {"config": "custom-config-toml"}}'
    

详情请参见 Red Hat 文档

使用符合 FIPS 的极狐GitLab Runner

note 目前对于运算符,您只可以更改 helper 镜像。 为使用符合 FIPS 的极狐GitLab Runner Helper,请按照以下内容更改 helper 镜像:
apiVersion: apps.gitlab.com/v1beta2
kind: Runner
metadata:
 name: dev
spec:
 gitlabUrl: https://gitlab.example.com
 token: gitlab-runner-secret
 helperImage: gitlab/gitlab-runner-helper:ubi-fips
 concurrent: 2

使用自签名证书注册极狐GitLab Runner

当您使用自签名证书安装私有化部署极狐GitLab,您必须创建包含用于签署私有证书的 CA 证书的密钥。

密钥的名称由 Runner spec 部分的 CA 提供:

KIND:     Runner
VERSION:  apps.gitlab.com/v1beta2

FIELD:    ca <string>

DESCRIPTION:
     Name of tls secret containing the custom certificate authority (CA)
     certificates

使用下列命令创建密钥:

oc create secret generic mySecret --from-file=tls.crt=myCert.pem -o yaml

通过指向 IP 地址的外部 URL 注册极狐GitLab Runner

如果 Runner 用主机名无法匹配自签名证书,您可能会收到错误信息。当极狐GitLab 私有化部署实例被配置为从 IP 地址而不是主机名(###.##.##.## 是极狐GitLab 服务器的 IP 地址)访问时,会发生这种情况:

[31;1mERROR: Registering runner... failed               [0;m  [31;1mrunner[0;m=A5abcdEF [31;1mstatus[0;m=couldn't execute POST against https://###.##.##.##/api/v4/runners:
Post https://###.##.##.##/api/v4/runners: x509: cannot validate certificate for ###.##.##.## because it doesn't contain any IP SANs
[31;1mPANIC: Failed to register the runner. You may be having network problems.[0;m

解决这个问题:

  1. 在极狐GitLab 私有化部署服务器上,更改 openssl,将 IP 地址添加到 subjectAltName 参数中:

    # vim /etc/pki/tls/openssl.cnf
    
    [ v3_ca ]
    subjectAltName=IP:169.57.64.36 <---- Add this line. 169.57.64.36 is your GitLab server IP.
    
  2. 使用如下命令重新生成自签名 CA:

    # cd /etc/gitlab/ssl
    # openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/gitlab/ssl/169.57.64.36.key -out /etc/gitlab/ssl/169.57.64.36.crt
    # openssl dhparam -out /etc/gitlab/ssl/dhparam.pem 4096
    # gitlab-ctl restart
    
  3. 使用新的证书生成新的密钥。