在 Serverless kubernetes 集群中运行 Gitlab Runner
背景
Serverless Kubernetes 让您无需管理和维护集群与服务器,即可快速创建 Kuberentes 容器应用,并且根据应用实际使用的 CPU 和内存资源量进行按需付费。使用 Serverless Kubernetes,您可以专注于设计和构建应用程序,而不是管理运行应用程序的基础设施。充分结合了虚拟化资源带来的安全性、弹性和 Kubernetes 生态。
由此定位,这种集群是很适合用来跑 CI 流程场景的。CI 触发时创建对应资源,CI 结束后销毁对应的资源。目前 Serverless Kubernetes 或多或少有一些不友好的体验,比如:
- 不能自定义
CoreDNS
/Kube-DNS
配置。 - 不能使用
docker-in-docker
方式构建镜像。
需求资源
- NAS 存储
- Serverless Kubernetes 集群
部署
注册 Runner
获取 registration token
在项目的 settings/ci_cd
页面,或者管理员的 /admin/runners
页面都可以找到 token
。token
是 Runner 注册的凭证。如果是从项目获取的 token
,那么这个 Runner 属于此项目,可以通过配置允许其他项目也可以使用。如果是从管理员页面获取的 token
,那么这个 Runner,所有项目可见,都可以使用,即共享 Runner。
下面以共享的 Runner 为例:
需要获取图中模糊处理的两个参数:
- URL:
https://gitlab.example.choerodon.io
- Registration token:
XXXXXXXXXXXXXXXXXXX
注册 Runner
运行 Runner,进入容器
docker run -it --rm --entrypoint=bash dockerhub.azk8s.cn/gitlab/gitlab-runner:alpine-v11.8.0
进行注册
gitlab-runner register
注册成功后查看生成的token
cat /etc/gitlab-runner/config.toml
执行完上述操作记录 [[runners]]
域下的 token
:
- token:
**********************
部署 Runner
- 创建缓存挂载PV/PVC配置文件:cache.yaml (若不需要缓存挂载,请跳过此步骤) PS: 若需挂载多个目录,请按实际情况创建PV、PVC
apiVersion: v1
kind: PersistentVolume
metadata:
name: runner-cache-pv
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 100Gi
mountOptions:
- nolock,tcp,noresvport
- vers=3
nfs:
path: /cache
server: abcde.cn-shanghai.nas.example.choerodon.io
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: runner-cache-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
volumeName: runner-cache-pv
- 在触发 CI 流程时,Runner 会在 Kubenertes 集群中创建对应的 Pod 执行任务,故需要集群权限,复制
kubeconfig
文件中的信息,将对应值粘贴到对应字段创建Secret
,这里不再累述。最后 Runner 引用到这个Secret
用以认证,编写文件serverless-runner-kubeconfig.yaml
。
apiVersion: v1
kind: Secret
metadata:
name: serverless-runner-kubeconfig
type: kubernetes.io/tls
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUq......
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR......
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQp......
编写 Runner 配置文件:
serverless-runner-config.yaml
apiVersion: v1 kind: ConfigMap metadata: name: serverless-runner-config data: config.toml: | # 可同时并发执行任务的数量 concurrent = 10 check_interval = 0 [[runners]] name = "runner" url = "https://gitlab.example.choerodon.io" # [[runners]] 域下的 token token = "**********************" executor = "kubernetes" # 日志大小限制 output_limit = 51200 # 常用固定环境变量 environment = ["CHOERODON_URL=http://api.example.choerodon.io", "SONAR_URL=http://sonarqube.example.choerodon.io"] [runners.kubernetes] # kubeconfig 文件中的 apiserver 访问地址 host = "https://abcde.serverless-1.kubernetes.cn-shanghai.example.choerodon.io:6443" # 对应上面创建的 Secret cert_file = "/etc/gitlab-runner/tls.crt" key_file = "/etc/gitlab-runner/tls.crt" ca_file = "/etc/gitlab-runner/ca.crt" namespace = "default" pull_policy = "always" # 由于 Serverless Kubernetes 使用有规格约束,故在 Pod 资源申请与限制应按相应规格进行设置,本例为 4c8g cpu_limit = "3750m" cpu_request = "3750m" memory_limit = "7680Mi" memory_request = "7680Mi" helper_cpu_limit = "250m" helper_cpu_request = "250m" helper_memory_limit = "512Mi" helper_memory_request = "512Mi" helper_image = "dockerhub.azk8s.cn/gitlab/gitlab-runner-helper:x86_64-4745a6f3" [runners.kubernetes.pod_annotations] # 未购买 snat 可挂载 eip 使得 CI Job 可以访问公网资源,例如阿里云使用以下 annotation # "k8s.aliyun.com/eci-with-eip" = "true" [runners.kubernetes.volumes] # 挂载缓存目录(可选) [[runners.kubernetes.volumes.pvc]] name = "runner-cache-pvc" mount_path = "/cache" readonly = false # [[runners.kubernetes.volumes.pvc]] # name = "runner-maven-pvc" # mount_path = "/root/.m2" # readonly = false
编写 Runner manifest 文件:
serverless-runner.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: serverless-runner spec: selector: matchLabels: app: gitlab-runner template: metadata: labels: app: gitlab-runner spec: containers: - image: dockerhub.azk8s.cn/gitlab/gitlab-runner:alpine-v11.8.0 imagePullPolicy: IfNotPresent name: runner-gitlab volumeMounts: - mountPath: /etc/gitlab-runner name: config volumes: - name: config projected: defaultMode: 420 sources: - secret: items: - key: ca.crt path: ca.crt - key: tls.crt path: tls.crt - key: tls.key path: tls.key name: serverless-runner-kubeconfig - configMap: items: - key: config.toml path: config.toml name: serverless-runner-config
应用配置
- 创建PV/PVC (可选)
kubectl apply -f cache.yaml
- 应用 Runner
kubectl apply -f serverless-runner-kubeconfig.yaml -f serverless-runner-config.yaml -f serverless-runner.yaml
- 创建PV/PVC (可选)
不能自定义CoreDNS/Kube-DNS配置
自定义CoreDNS/Kube-DNS配置是为了让集群内部应用不通过公网访问同一VPC下的其他应用直接通过内网即可,比如Gitlab,Harbor等。
例如阿里云官方提供的解决方案是使用privateZone,其他云厂商也有类似的云产品。
不能使用 docker-in-docker
方式构建镜像
使用kaniko进行镜像构建,这里我们将官方镜像中的可执行文件复制到自己的CI镜像中即可使用,Dockerfile如下。
FROM gcr.azk8s.cn/kaniko-project/executor:v0.18.0 AS kaniko
FROM registry.cn-shanghai.aliyuncs.com/c7n/cibase:0.9.1
COPY --from=kaniko /kaniko/executor /usr/bin/kaniko
这是有build好可直接使用的镜像:
registry.cn-shanghai.aliyuncs.com/c7n/cibase:0.10.0
- 待友好解决的问题:执行kaniko后会出现
Deleting filesystem...
操作,导致执行完kaniko后不能再执行其他命令,在CI中可以再分出一个stage
来规避这个问题。
作者:钟梓凌
出处:Choerodon
欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。