kubernetes部署GItLab Runner及Gitlab-CI配置
系统环境
Gitlab版本:16.1.0
Gitlab Runner版本:14.6.0
Kubernetes版本:1.20.0
GitLab-CI介绍
GitLab CI/CD是GitLab的一部分,支持从计划到部署具有出色的用户体验,CI/CD是开源GitLab社区版和专有GitLab企业版的一部分,可以根据需要添加任意数量的计算节点,每个构建可以拆分为多个作业,这些作业可以在多台计算机上并行运行
GitLab-CI轻量级,不需要复杂的安装手段,配置简单,与gitlab可直接适配。实时构建日志十分清晰,UI交互体验很好。使用YAML进行配置,任何人都可以很方便的使用。GitLabCI有助于DevOps人员,例如敏捷开发中,开发与运维是同一个人,最便捷的开发方式
在大多数情况,构建项目都会占用大量的系统资源,如果让gitlab本身来运行构建任务的话,显然Gitlab的性能会大幅度下降。GitLab-CI最大的作用就是管理各个项目的构建状态。因此运行构建任务这种浪费资源的事情交给一个独立的Gitlab Runner来做就会好很多,更重要的是Gitlab Runner可以安装到不同的机器上,甚至是我们本机,这样完全就不会影响Gitlab本身了
从GitLab8.0开始,GitLab-CI就已经集成在GitLab中,我们只需要在项目中添加一个.gitlab-ci.yaml文件,然后运行一个Runner,即可进行持续集成
GitLab-CI:集成、开源、无缝、可扩展、更快的结果、针对交付进行了优化:
GItLab Runner
Gitlab Runner是一个开源项目,用于运行您的作业并将结果发送给gitlab。它与Gitlab CI结合使用,gitlab ci是Gitlab随附的用于协调作用的开源持续集成服务。
Gitlab Runner是用Go编写的,可以作为一个二进制文件运行,不需要特定于语言的要求
它皆在GNU/Linux,MacOS和Windows操作系统上运行。另外注意:如果要使用Docker,Gitlab Runner要求Docker 至少是v1.13.0版本才可以。
Kubernetes Gitlab CICD演示图:
部署Gitlab
接下来顺便创建一个项目,用于演示
进入该项目下,左侧栏CICD里有三种方式:Pipelines、Jobs、Schedules
部署注册Gitlab Runner
配置gitlab runner资源清单 (runner-configmap.yaml)
[root@k8s01 gitlab]# cat runner-cm.yaml
apiVersion: v1
data:
REGISTER_NON_INTERACTIVE: "true"
REGISTER_LOCKED: "false"
METRICS_SERVER: "0.0.0.0:9100"
CI_SERVER_URL: "http://gitlab.tools-env.svc.cluster.local/ci"
RUNNER_REQUEST_CONCURRENCY: "4"
RUNNER_EXECUTOR: "kubernetes"
KUBERNETES_NAMESPACE: "tools-env"
KUBERNETES_PRIVILEGED: "true"
KUBERNETES_CPU_LIMIT: "1"
KUBERNETES_CPU_REQUEST: "500m"
KUBERNETES_MEMORY_LIMIT: "1Gi"
KUBERNETES_SERVICE_CPU_LIMIT: "1"
KUBERNETES_SERVICE_MEMORY_LIMIT: "1Gi"
KUBERNETES_HELPER_CPU_LIMIT: "500m"
KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"
KUBERNETES_PULL_POLICY: "if-not-present"
KUBERNETES_TERMINATIONGRACEPERIODSECONDS: "10"
KUBERNETES_POLL_INTERVAL: "5"
KUBERNETES_POLL_TIMEOUT: "360"
kind: ConfigMap
metadata:
labels:
app: gitlab-ci-runner
name: gitlab-ci-runner-cm
namespace: tools-env
[root@k8s01 gitlab]# kubectl apply -f runner-cm.yaml
configmap/gitlab-ci-runner-cm created
CI_SERVER_URL 这个地址是gitlab的地址,如果gitlab在宿主机直接写宿主机的ip即可,容器是格式为:svc名称.命名空间.svc.cluster.local,另外在ConfigMap添加新选项后,需要删除Gitlab ci Runner Pod
如果想添加其它选项,那么可以在等到后面的gitlab-ci-runner的Pod容器启动成功后,登录gitlab-ci-runner的pod容器内部运行gitlab-ci-multi-runner register --help 命令来查看所有可使用的选项,只需要为配置的标志添加env变量即可
[root@k8s01 gitlab]# kubectl exec -it -n tools-env gitlab-ci-runner-0 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
gitlab-runner@gitlab-ci-runner-0:/$ gitlab-ci-multi-runner register --help
...
OPTIONS:
-c value, --config value Config file (default: "/home/gitlab-runner/.gitlab-runner/config.toml") [$CONFIG_FILE]
--template-config value Path to the configuration template file [$TEMPLATE_CONFIG_FILE]
--tag-list value Tag list [$RUNNER_TAG_LIST]
-n, --non-interactive Run registration unattended [$REGISTER_NON_INTERACTIVE]
--leave-runner Don't remove runner if registration fails [$REGISTER_LEAVE_RUNNER]
-r value, --registration-token value Runner's registration token [$REGISTRATION_TOKEN]
--run-untagged Register to run untagged builds; defaults to 'true' when 'tag-list' is empty [$REGISTER_RUN_UNTAGGED]
--locked Lock Runner for current project, defaults to 'true' [$REGISTER_LOCKED]
--access-level value Set access_level of the runner to not_protected or ref_protected; defaults to not_protected [$REGISTER_ACCESS_LEVEL]
--maximum-timeout value What is the maximum timeout (in seconds) that will be set for job when using this Runner (default: "0") [$REGISTER_MAXIMUM_TIMEOUT]
--paused Set Runner to be paused, defaults to 'false' [$REGISTER_PAUSED]
--name value, --description value Runner name (default: "gitlab-ci-runner-0") [$RUNNER_NAME]
--limit value Maximum number of builds processed by this runner (default: "0") [$RUNNER_LIMIT]
--output-limit value Maximum build trace size in kilobytes (default: "0") [$RUNNER_OUTPUT_LIMIT]
--request-concurrency value Maximum concurrency for job requests (default: "4") [$RUNNER_REQUEST_CONCURRENCY]
...
还需要配置一个用于注册、运行和取消gitlab ci runner的脚本,只有当Pod正常通过K8S (TERM信号)的终止流程时,才会触发注销注册。如果强行终止Pod(SIGKILL信号),Runner将不会自己注销自身,必须手动完成对这种Runner的清理 (注意:只有在k8s集群里安装GitLan Runner才这样操作,二进制安装非K8s上安装则不受这个影响)
[root@k8s01 gitlab]# cat runner-scripts-cm.yaml
apiVersion: v1
data:
run.sh: |
#!/bin/bash
unregister() {
kill %1
echo "Unregistering runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner unregister -t "$(/usr/bin/gitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)" -n ${RUNNER_NAME}
exit $?
}
trap 'unregister' EXIT HUP INT QUIT PIPE TERM
echo "Registering runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN}
sed -i 's/^concurrent.*/concurrent = '"${RUNNER_REQUEST_CONCURRENCY}"'/' /home/gitlab-runner/.gitlab-runner/config.toml
echo "Starting runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner run -n ${RUNNER_NAME} &
wait
kind: ConfigMap
metadata:
labels:
app: gitlab-ci-runner
name: gitlab-ci-runner-scripts
namespace: tools-env
[root@k8s01 gitlab]# kubectl apply -f runner-scripts-cm.yaml
configmap/gitlab-ci-runner-scripts created
接着需要创建一个GITLAB_CI_TOKEN,然后使用gitlab ci runner token来创建一个Kubernetes secret对象,需要提前对token进行base64转码:
[root@k8s01 gitlab]# echo GR1348941z5xpoYRx17s11xK6EzaA3|base64 -w0
R1IxMzQ4OTQxejV4cG9ZUngxN3MxMXhLNkVSFAS
特别注意:这里的token就是gitlab runner上截图的地方,base64只有在k8s环境上需要,登录Gitlab,Runner右边栏token信息 如下图
使用上面的token创建一个Sercret对象 (gitlab-ci-token-secret.yaml)
[root@k8s01 gitlab]# cat gitlab-ci-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: gitlab-ci-token
namespace: tools-env
labels:
app: gitlab-ci-runner
data:
GITLAB_CI_TOKEN: R1IxMzQ4OTQxejV4cG9ZUngxN3MxMXhLNkVSFAS
[root@k8s01 gitlab]# kubectl apply -f gitlab-ci-token-secret.yaml
secret/gitlab-ci-token created
使用Statefulset部署Runner,在开始运行的时候,尝试取消注册所有的同名Runner,当节点丢失时(即NodeLost事件)尤其有用,然后再尝试注册自己并开始运行。在正常停止Pod的时候,Runner将会运行unregister命令来尝试取消自己,gitlab就不能再使用这个Runner,这个则是通过kubernetes Pod生命周期中的hooks来完成的
[root@k8s01 gitlab]# cat runner-statefulset.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-ci
namespace: tools-env
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: tools-env
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: tools-env
subjects:
- kind: ServiceAccount
name: gitlab-ci
namespace: tools-env
roleRef:
kind: Role
name: gitlab-ci
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Service
metadata:
name: gitlab-ci-runner
namespace: tools-env
labels:
app: gitlab-ci-runner
spec:
ports:
- port: 9100
targetPort: 9100
name: http-metrics
clusterIP: None
selector:
app: gitlab-ci-runner
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gitlab-ci-runner
namespace: tools-env
labels:
app: gitlab-ci-runner
spec:
updateStrategy:
type: RollingUpdate
replicas: 2
serviceName: gitlab-ci-runner
selector:
matchLabels:
app: gitlab-ci-runner
template:
metadata:
labels:
app: gitlab-ci-runner
spec:
volumes:
- name: gitlab-ci-runner-scripts
projected:
sources:
- configMap:
name: gitlab-ci-runner-scripts
items:
- key: run.sh
path: run.sh
mode: 0755
serviceAccountName: gitlab-ci
securityContext:
runAsNonRoot: true
runAsUser: 999
supplementalGroups: [999]
containers:
- image: gitlab/gitlab-runner:latest
name: gitlab-ci-runner
command:
- /scripts/run.sh
envFrom:
- configMapRef:
name: gitlab-ci-runner-cm
- secretRef:
name: gitlab-ci-token
env:
- name: RUNNER_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 9100
name: http-metrics
protocol: TCP
volumeMounts:
- name: gitlab-ci-runner-scripts
mountPath: "/scripts"
readOnly: true
restartPolicy: Always
[root@k8s01 gitlab]# kubectl apply -f runner-statefulset.yaml
serviceaccount/gitlab-ci created
role.rbac.authorization.k8s.io/gitlab-ci created
rolebinding.rbac.authorization.k8s.io/gitlab-ci created
service/gitlab-ci-runner created
statefulset.apps/gitlab-ci-runner created
[root@k8s01 gitlab]# kubectl get -n tools-env po|grep runner
gitlab-ci-runner-0 1/1 Running 0 3m25s
gitlab-ci-runner-1 1/1 Running 0 2m42s
此时登录Gitlab查看Runner信息,发现就已经将这2个pod节点添加进来了
这里也可以更改Runner的一些配置,比如添加tag标签等
Gitlab Runner配置使用
在代码仓库中添加 .gitlab-ci.yml文件,这里仅展示了基本格式
image: ruby:2.1
#定义Stages
stages:
- package
- build
- deploy
#定义package阶段的一个job
package-job:
stage: package
image: node:14
script:
- echo "Hello, package-job"
- echo "开始编译代码"
- echo "npm install"
#定义build阶段的一个job
test-job:
stage: build
script:
- echo "Hello, build-job"
- echo "开始打包镜像"
- echo "docker build"
#定义deploy阶段的一个job
deploy-job:
stage: deploy
script:
- echo "Hello, deploy-job"
- echo "开始发布服务"
- echo "sh deploy.sh"
具体参数参考gitlab官方文档