详解如何设计配置安全多租户隔离的gitlab-runner

经过实际的使用,本人的结论是,GitLab集成的CI/CD功能已经可以替代市面上绝大多数的外置的CI/CD工具。我不看好三方工具后期的发展,建议大家直接使用GitLab CI/CD就可以,不用再花经历在三方工具的复杂配置的学习上了。

本文将集中在CI侧的流程,从实际的角度而言,将流程跑通是很简单的,但是把整个流水线设计的符合安全规范,还是需要考虑相当多的问题的。

名词解释:

  • Runners:负责与gitlab之间通信,获取需要执行的任务,并反馈执行的结果。

  • Executors:runner的执行环境,比如你需要执行PowerShell指令,那么你的runner就需要安装在Windows机器上,并且赋予runner powershell的执行权限。我们默认安装使用的是Kubernetes executor,The executor calls the Kubernetes cluster API and creates a pod for each GitLab CI job.

一、helm及runner仓库的安装配置

helm安装:

helm为一个二进制程序,下载之后,放入PATH环境变量所包含的路径中即可。
二级制release地址:
https://github.com/helm/helm/releases
下载对应版本,解压。
mv linux-amd64/helm /usr/local/bin/helm
helm help

runner仓库的配置:

添加gitlab仓库:
helm repo add gitlab https://charts.gitlab.io
helm repo update gitlab
helm search repo -l gitlab/gitlab-runner

安装:
kubectl create ns runner-yf
helm install --namespace <NAMESPACE> gitlab-runner -f <CONFIG_VALUES_FILE> gitlab/gitlab-runner
helm install --namespace runner-yf gitlab-runner -f values.yaml gitlab/gitlab-runner
更新:
helm upgrade --namespace <NAMESPACE> -f <CONFIG_VALUES_FILE> <RELEASE-NAME> gitlab/gitlab-runner
helm upgrade --namespace runner-yf gitlab-runner -f values.yaml gitlab/gitlab-runner

二、安装规范

建议按照部门新建runner所属的独立namespace:
例如研发部门:runner-yf
kubectl create ns runner-yf
更新helm仓库:
helm repo update gitlab
helm search repo -l gitlab/gitlab-runner
拉取最新的仓库离线包,确保和gitlab主版本保持一致。
官方建议runner的版本需要与gitlab的版本保持一致,虽然老版本的runner功能性上不会有什么问题,但是版本跨度过大的话,还是会产生兼容性的问题。因此,需要制定计划,定期对于现有的runner进行统一的升级。
helm pull gitlab/gitlab-runner --version 0.55.0
tar -xzvf gitlab-runner-0.55.0.tgz
把解压出来的gitlab-runner文件夹,标注对用的APP version
mv gitlab-runner gitlab-runner-16.2.0
进行values.yaml的配置,命名规则:
研发部:values-kaniko-yf.yaml
进行安装
cd gitlab-runner gitlab-runner-16.2.0
helm install --namespace runner-yf gitlab-runner -f values-kaniko-yf.yaml ./
更新:
helm upgrade --namespace runner-yf gitlab-runner -f values-kaniko-yf.yaml ./
卸载:
helm list -n runner-yf
helm uninstall --namespace runner-yf gitlab-runner 
整个安装包,基于git项目进行管理。按照版本进行升级。

三、进行kubernetes节点的标签配置

假如复用现有节点,建议选择部分的节点运行CI容器,做好隔离。当使用独立集群进行CI作业时可忽略。

k8s node 打节点:
kubectl label nodes k8s-1 runner="true"

四、核心部分,进行helm chart values.yaml的配置

#重点关键的配置:
gitlabUrl: https://gitlab.xxx.com
runnerToken: "glrt-7A2yBa1eesMpNxxxxx" #请前往gitlab群组下新建runner,并获取token
#并行Job数:
concurrent: 10
#为runner创建RBAC
rbac:
  create: true
  rules: 
  - resources: ["configmaps", "pods", "pods/attach", "secrets", "services", "events"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create", "patch", "delete"]
  clusterWideAccess: false
  podSecurityPolicy:
    enabled: ture
    resourceNames:
    - gitlab-runner
#此处的allowed_images为pipeline中为定义镜像时的默认镜像,相关的权限将对于Executor的拉起的容器生效。
#建议在harbor中建立一个公共的目录,存放用于CI/CD过程所需的镜像。进行镜像来源的限制。
#建议在allowed_images限制容器打包的镜像为kaniko这种安全的方式,替换屌DIND这种不安全的方式。
具体如下图:

The [runners.kubernetes] section可配置的参数概览:

Parameter

Type

Description

host

string

Optional. Kubernetes host URL. If not specified, the runner attempts to auto-discovery it.

cert_file

string

Optional. Kubernetes auth certificate.

key_file

string

Optional. Kubernetes auth private key.

ca_file

string

Optional. Kubernetes auth ca certificate.

image

string

Default Docker image to use for jobs when none is specified.

allowed_images

array

Wildcard list of images that are allowed in .gitlab-ci.yml. If not present all images are allowed (equivalent to ["*/*:*"]). Use with the Docker or Kubernetes executors.

allowed_services

array

Wildcard list of services that are allowed in .gitlab-ci.yml. If not present all images are allowed (equivalent to ["*/*:*"]). Use with the Docker or Kubernetes executors.

namespace

string

Namespace to run Kubernetes jobs in.

privileged

boolean

Run all containers with the privileged flag enabled.

allow_privilege_escalation

boolean

Optional. Runs all containers with the allowPrivilegeEscalation flag enabled.

node_selector

table

table of key=value pairs of string=string. Limits the creation of pods to Kubernetes nodes that match all the key=value pairs.

image_pull_secrets

array

An array of items containing the Kubernetes docker-registry secret names used to authenticate Docker image pulling from private registries.

当你完成全部的配置之后,runner及executor容器的权限理论上如下图:

官方的核心参考文档:

https://docs.gitlab.com/runner/

https://docs.gitlab.com/runner/install/kubernetes.html

https://docs.gitlab.com/runner/configuration/advanced-configuration.html

https://docs.gitlab.com/runner/executors/kubernetes.html

官方原理图: