前期搭建了云服务器私有的gitlab和k8s环境,但是都是独立运行的,每次代码更新需要手动去打包好镜像,推送到镜像仓库,然后在deployment里面更新image,这样平时不太有问题,但是会给运维我这边产生很多琐事(反正就是想偷懒,能自动化的为什么要手动,懒惰才是提高生产力的动力!)。在这种情况下我就考虑上自动化CI/CD,因为有了gitlab-runner我以为很容易就能完成,结果花了3天时间暂时跑通了整个流程,其中有些部分还是需要后期再优化,下面罗列一下其中遇到的坑:
一、安装注册gitlab-runner
先要确定gitlab-runner是要安装到哪里,我用的gitlab版本是16.0.1,点开你的项目-“设置”-“CI/CD”-“Runner”-“Expand”,在这里新建项目的runner(当然如果你是管理员,你可以在首页的“设置”-“CI/CD”里面新建),这里你可以看到几种安装环境以及官方给出的安装方法:
这里我选择的Kubernetes(中途也想换成linux算了,直接shell处理不用这么麻烦,本来也不是什么大的项目,最后还是好奇心驱动自己一步步的走下去)。安装Kubernetes executor,我们需要用到helm,helm的安装可以参考官方文档 https://helm.sh/zh/docs/intro/install/很简单。
安装完之后我们添加gitlab helm仓库:
helm repo add gitlab https://charts.gitlab.io
1.
更新一下
helm repo update gitlab
1.
查看有哪些版本的gitlab-runner
helm search repo -l gitlab/gitlab-runner
1.
现在我们准备2个yaml文件,values.yaml是最重要的,其中有很多参数需要我们调整,我会提出其中重要的部分,标准文件可以在官网下载
gitlabUrl: https://git.test.com/ #这里需要更改为你自己的gitlab地址
rbac:
create: true #rbac这里需要开启,默认是没有开启的,这样pod会起不来,这里的rules是可以细化的而且会影响到后面的
#每一步的执行权限,很重要,下一步的我会研究rbac这块
runners:
config: |
[[runners]]
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "ubuntu:20.04" #executor运行的image
privileged = true #一定要是true,否则起不来
[[runners.kubernetes.volumes.empty_dir]]
name = "docker-certs"
mount_path = "/certs/client"
medium = "Memory"
secret: secrets #存放runner-registration-token的secret文件,很重要,runner注册的关键
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
下面我们来创建secret.yaml,就是对应上面runners里面的secret的
apiVersion: v1
kind: Secret
metadata:
name: projected-secrets
namespace: gitlab-ci
type: Opaque
stringData:
runner-registration-token: "glrt-***************" #gitlab里Runner生成的token
runner-token: "" #默认是REDACTED,一定要删除,不是runner启动不了,大坑
1.
2.
3.
4.
5.
6.
7.
8.
9.
这样我们就准备好在k8s里运行runner了,之后就能在设置里的Runner里看到连接成功,绿灯
#运行secret
kubectl create -f secret.yaml
#运行runner,这里是在k8s中namespace gitlab-ci下创建名字为gitlab-runner版本0.53.1的depolyment
helm install --namespace gitlab-ci gitlab-runner -f values.yaml gitlab/gitlab-runner --version 0.53.1
1.
2.
3.
4.
5.
这里我是遇到了pipeline报错的情况
ERROR: Job failed (system failure): prepare environment: setting up credentials: secrets is forbidden:
User "system:serviceaccount:gitlab-ci:default" cannot create resource "secrets" in API group "" in the namespace
"gitlab-ci". Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information
1.
2.
3.
该报错意思是gitlab-ci命名空间下的名为gitlab-runner的serviceaccount没有在kube-system中创建secrets的权限。该问题通常是因为RBAC权限不足引起。通过添加相关的RBAC权限解决,我用的简单粗暴的
kubectl create clusterrolebinding gitlab-admin --clusterrole=cluster-admin --serviceaccount=gitlab-ci:gitlab-runner
1.
二、编辑流水线pipeline
这里我们主要编辑的是项目根目录下的.gitlab-ci.yml文件,这个文件定义了我们是怎么样去打包、测试、部署现有项目(不限于我说的这3步,可以自定义流程),我这里做的是需要更新代码后自动打包成镜像,推送到指定仓库,最后在k8s里更新镜像。
variables: # 声明环境变量
IMAGE: cn-guangzhou.cr.volces.com/test/web:$CI_COMMIT_SHORT_SHA
stages: # List of stages for jobs, and their order of execution
- build
- deploy
build-job: # This job runs in the build stage, which runs first.
stage: build
tags:
- k8s
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination $IMAGE
deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
tags:
- k8s
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl set image -n default deployment/xcx xcx=$IMAGE
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
语法的话,可以看一下官方文档https://docs.gitlab.com/ee/ci/yaml/,这里我主要说一下我遇到的一些坑。因为用的是私有的镜像仓库,所以我们需要在gitlab项目中设置的变量里定义CI_REGISTRY(镜像仓库地址)CI_REGISTRY_USER(登录账号)CI_REGISTRY_PASSWORD(密码)。
最开始我准备用docker命令去执行build、push,但是写出来pipeline执行就报错:
ERROR: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
1.
什么方法都试过了不行,直接放弃,用kaniko。用kaniko需要注意的是由于他的镜像地址是在google的国内拉不下来会报错,用其他地址代替;另外一个就是镜像必须用kaniko:debug的,只有这个才是带shell可以执行命令的。
镜像打包推送完了之后就需要在k8s里面更新镜像,这里需要注意就是加载kubectl的镜像。
通过上述操作就完成了从代码push到gitlab后自动build image, push image, 最后k8s的更新,后续会再研究一下rbac。
-