Gitlab的持续集成功能依赖于Gitlab Runner
组件完成,gitlab runner作为Gitlab这个中控机
的执行者,按照代码仓库里面.gitlab-ci.yaml
文件里面预定义的任务job
按照指定的顺序或并发的执行完成系列的编译、测试、部署等操作,也就是说只要按照.gitlab-ci.yaml的配置格式[1]将写好的.gitlab-ci.yml文件放在代码仓库内,待下一次代码提交commit
的时候就会自动的触发仓库绑定的Gitlab Runner
去按照.gitlab-ci.yml里面配置的指定的执行。
总结一下,在Gitlab进行CICD,需要简单的做几步, Gitlab runner运行的架构下图所示:
安装Gitlab Runner
把代码仓库与Gitlab Runner进行绑定
在代码仓库里面配置.gitlab-ci.yml
在.gitlab-ci.yml
文件里面定义好编译、单元测试、部署等任务(jobs)
上一篇,我们将Gitlab服务安装在我们的ACK(阿里云的kubernetes)里面,下面我们也将在Kubernetes里面安装部署Gitlab Runner[2],给Gitlab增加持续集成的功能,这里有两种方式安装,一种通过helm(省事简单),一种手动安装,第一种方式这里简单的说明一下,我们使用第二种进行部署Gitlab Runner.
如果你已经准备好了Helm
的话,可以参考此种方式,获取gitlab runner 的helm chat
git clone https://github.com/haoshuwei/gitlab-runner.git
cd gitlab-runner
#修改values.yaml里面的gitlabUrl和runnerRegistrationToken,runnerRegistrationToken可以从Admin Area>Overview>Runner处获取Runner的Token.修改完成之后,通过helm进行打包,然后安装到k8s环境
☸️ ACK???? devops ~/v1.11.5/Runner-toml/gitlab-runner master ● ???? ???? helm package .
Successfully packaged chart and saved it to: /Users/marionxue/v1.11.5/Runner-toml/gitlab-runner/gitlab-runner-0.1.37.tgz
☸️ CKA???? devops ~/v1.11.5/Runner-toml/gitlab-runner master ● ???? ???? helm install gitlab-runner *.tgz #安装到当前的devops空间下
如果你使用的是阿里云的ACK的话,可以参考阿里云的文档:https://www.alibabacloud.com/help/zh/doc-detail/106968.htm
此部分参考Edenmal[3]的笔记,手动安装Gtilab Runner到K8s集群内,首先声明一个Configmap gitlab-runner.configmap.yaml
来为Gitlab Runner提供需要的环境变量以及一些资源约束信息:
在向 ConfigMap 添加新的环境变量,需要删除已有的
GitLab CI Runner Pod
。因为我们是使用envFrom
来注入上面的这些环境变量而不是直接使用env
的(envFrom 通过将环境变量放置到ConfigMaps
或Secrets
来帮助减小清单文件。
apiVersion: v1
data:
REGISTER_NON_INTERACTIVE: "true"
REGISTER_LOCKED: "false"
METRICS_SERVER: "0.0.0.0:9100"
CI_SERVER_URL: "http://gitlab.devops.svc.cluster.local/ci" # k8s内gitlab服务的通信地址格式:svc.namespace.svc.cluster.local, 同时加上/ci这个prefix,这里也可以使用外网访问地址
RUNNER_REQUEST_CONCURRENCY: "4"
RUNNER_EXECUTOR: "kubernetes"
KUBERNETES_NAMESPACE: "devops" # 服务运行的namespace
KUBERNETES_PRIVILEGED: "true"
KUBERNETES_CPU_LIMIT: "1"
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" # image的拉取策略
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: devops
同样的,还需要准备一个Configmapgitlab-ci-runner-scripts.configmap.yml
存储清理未被正常调度的Gitlab Runner的Pod. 正常来说,Gitlab runner在完成自己的使命之后,Kubernetes就会发送一个TERM signal
信号用于正常的注销Gitlab runner, 所以那些被强制终止的Pod是不会自动的被清理的,而这个脚本就是完成这部分Pod的清理工作。
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: devops
我们需要创建一个Secretgitlab-ci-token-secret.yaml
来存储Gitlab Runner的Token.以便上面的脚本能正常的运行,在secret内需要存放base64加密后的字符串。
echo YOUR_GITLAB_CI_TOKEN | base64 # YOUR_GITLAB_CI_TOKEN从Gitlab上获取,前面已经说过了.
apiVersion: v1
kind: Secret
metadata:
name: gitlab-ci-token
namespace: devops # 指定命名空间
labels:
app: gitlab-ci-runner
data:
GITLAB_CI_TOKEN: SERnMUE3Znh5YVZ4dE1oSkhkQnQK # 这是base64加密Gitlab runner token之后的字符串
我们通过sts(statefulset控制器)gitlab-runner-sts.yaml
创建Gitlab Runner。在开始运行的时候,尝试取消注册所有的同名 Runner,当节点丢失时(NodeLost
事件)尤其有用。然后再尝试重新注册自己并开始运行。在正常停止 Pod 的时候,Runner 将会运行unregister
命令来尝试取消自己,所以 Gitlab 就不能再使用这个 Runner 了,这个是通过 Kubernetes Pod 生命周期中的hooks
来完成的,在运行Gitlab Runner的时候,我们通过Envfrom
调用之前创建的脚本以及Gitlab runner运行需要的环境变量信息.
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: gitlab-ci-runner
namespace: devops # gitlab运行的命名空间
labels:
app: gitlab-ci-runner
spec:
updateStrategy:
type: RollingUpdate # Gitlab Runner的更新模式
replicas: 2
serviceName: 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 # 创建一个serviceAccount,创建pod
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
从sts配置清单中看到,我们还需要一个ServiceAccount
来有足够的权限做一些事情,因此我们创建一个gitlab-ci
的ServiceAccount
, 配置清单为:gitlab-runner-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-ci
namespace: devops
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: devops
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: devops
subjects:
- kind: ServiceAccount
name: gitlab-ci
namespace: devops
roleRef:
kind: Role
name: gitlab-ci
apiGroup: rbac.authorization.k8s.io
这样,我们就准备好Gitlab Runner运行需要的配置清单,接下来,我们开始创建一下服务:
☸️ ACK???? devops ~/v1.11.5/gitlab/runner ???? ???? k apply -f .
secret/gitlab-ci-token created
configmap/gitlab-ci-runner-cm created
serviceaccount/gitlab-ci created
role.rbac.authorization.k8s.io/gitlab-ci created
rolebinding.rbac.authorization.k8s.io/gitlab-ci created
configmap/gitlab-ci-runner-scripts created
statefulset.apps/gitlab-ci-runner created
☸️ ACK???? devops ~/v1.11.5/gitlab/gitlab-ci-demo master ???? ???? k get pods
NAME READY STATUS RESTARTS AGE
gitlab-866cc5b84b-6hznk 1/1 Running 0 17h
gitlab-ci-runner-0 1/1 Running 0 34s
gitlab-ci-runner-1 1/1 Running 0 30s
gitlab-redis-5d86f5cf95-g6m7l 1/1 Running 0 17h
postgresql-64d79556cf-xggf8 1/1 Running 0 17h
此时我们在Gitlab平台上即可看到刚才注册的Runner服务
查看注册的Gitlab Runner这样就完成了Gitlab runner的注册.Gitlab可以对于不同语言的服务进行构建,测试,架构不同、构建环境等一切确定着Gitlab runner的运行环境,所以针对这样的场景,只要Gitlab能与Runner进行通信,就可以通过Tag等进行匹配调度。
完成Gitlab Runner服务的安装之后,下一步就可以开始探索Gitlab Pipeline的实践了。
[1]
.gitlab-ci.yaml: https://docs.gitlab.com/ee/ci/quick_start/README.html
[2]Gitlab Runner: https://docs.gitlab.com/ee/ci/quick_start/README.html
[3]Edenmal.moe: https://edenmal.moe/
???? Gitlab CICD 与Kubernetes实践·部署GitLab
???? 从GitLabCE CI/CD方法论中探索实践
???? 15 个 Kubectl 现有命令使用技巧 - 拿来即用
???? Jenkins在kubernetes上的初体验
???? 走进Network Namespace学会容器网络调试
???? 实践 | Kubernetes守护进程集之DaemonSet
???? 神奇!如何快速成为一名优秀的YAML工程师?
???? 最流行的五款Kubernetes交互式可视化工具
???? ab压力测试模拟实现kubernetes Pod水平自动伸缩
???? 用Prometheus对业务服务进行监控
???? Prometheus监控系列-监控篇
???? kubernetes炼气期之掌握Kubernetes的背景
???? Prometheus监控系列-部署篇
???? 2020年最高效的10款Kubernetes助力神器
???? 写给孩子看的Kubernetes动画指南
???? kubernetes的ingress控制器比较(traefik2.0.5安装指南)
???? kubernetes深度探究Node和Pod的亲和性和反亲和性
???? 在kuebernetes上通过nfs-server持久化postgresql
???? kubernetes监控架构核心组件Metrics-server
???? 基于BasicAuth认证的Traefik2.0.5
???? 在Kubernetes上部署Nginx Ingress controller
???? kubernetes安装方案大全
???? kubernetes最常用的资源对象Deployment
???? kubernetes炼气期之掌握kuebernetes背景
???? kubernetes炼气期之k8s平台快速搭建
???? 二进制部署Kubernetes集群1.9版本
你可能还喜欢
点击下方图片即可阅读