前期搭建了云服务器私有的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
更新一下
helm repo update gitlab
查看有哪些版本的gitlab-runner
helm search repo -l gitlab/gitlab-runner
现在我们准备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注册的关键
下面我们来创建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启动不了,大坑
这样我们就准备好在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
这里我是遇到了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
该报错意思是gitlab-ci命名空间下的名为gitlab-runner的serviceaccount没有在kube-system中创建secrets的权限。该问题通常是因为RBAC权限不足引起。通过添加相关的RBAC权限解决,我用的简单粗暴的
kubectl create clusterrolebinding gitlab-admin --clusterrole=cluster-admin --serviceaccount=gitlab-ci:gitlab-runner
二、编辑流水线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
语法的话,可以看一下官方文档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?
什么方法都试过了不行,直接放弃,用kaniko。用kaniko需要注意的是由于他的镜像地址是在google的国内拉不下来会报错,用其他地址代替;另外一个就是镜像必须用kaniko:debug的,只有这个才是带shell可以执行命令的。
镜像打包推送完了之后就需要在k8s里面更新镜像,这里需要注意就是加载kubectl的镜像。
通过上述操作就完成了从代码push到gitlab后自动build image, push image, 最后k8s的更新,后续会再研究一下rbac。
标签:CI,runner,gitlab,ci,镜像,k8s From: https://blog.51cto.com/shevastar/7069454