Gitlab是一个受众较广的代码托管工具,为了便于进行ci/cd,其增加了通过编辑.gitlab-ci.yml文件来简洁的实现ci/cd功能配置的功能,同时其gitlab-runner可以非常方便的和linux主机、k8s集群进行集成。本篇就结合huaweicloud CCE(商用k8s)进行集成测试。

一、安装配置gitlab-runner

因为只是出于测试目的,这里选用了公网gitlab服务,免去了安装gitlab的麻烦,因为gitlab自有的Shared runners是付费服务,这里我先选用Specific runners(自有安装的runner)。

获取项目专用Runner的注册信息

  1. 登录GitLab。
  2. 在顶部导航栏中,选择Projects > Your projects。
  3. 在Your projects页签下,选择相应的Project。
  4. 在左侧导航栏中,选择Settings > CI / CD。
  5. 单击Runners右侧的Expand。
    gitlab-runner
    gitlab-runner

    这里主要是获取域名信息和token信息,获取后,下载我放在github上的gitlab-runner目录下的代码,修改values.yaml文件里对应的gitlabUrl和runnerRegistrationToken项。

配置缓存云磁盘

同时注意,如果用的不是华为CCE,还需要修改templates/pvc.yaml目录下的PVC项内容,比如阿里云对于磁盘的定义就是volume.beta.kubernetes.io/storage-provisioner: alicloud/disk。这里挂载碰盘的目的,主要用于本地缓存,具体可以配合templates/configmap.yaml文件一起查看下。

helm安装gitlab-runner

调整完成后,执行helm安装(需要提前安装helm指令,helm选择最新版本在华为云CCE上会报错,可以选用华为云官方推荐版本):

 1[root@testcce-68506-l3jp4 gitlab-runner]# ll
 2total 20
 3-rw-r--r-- 1 root root  369 Apr 13 22:33 Chart.yaml
 4-rw-r--r-- 1 root root  229 Apr 13 22:33 README.md
 5drwxr-xr-x 2 root root 4096 Apr 14 01:16 templates
 6-rw-r--r-- 1 root root 6470 Apr 19 05:20 values.yaml
 7[root@testcce-68506-l3jp4 gitlab-runner]# helm package .
 8WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
 9WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
10Successfully packaged chart and saved it to: /data/gitlab-runner/gitlab-runner-0.1.37.tgz
11[root@testcce-68506-l3jp4 gitlab-runner]# helm install --namespace gitlab gitlab-runner *.tgz
12WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/.kube/config
13WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /root/.kube/config
14NAME: gitlab-runner
15LAST DEPLOYED: Tue Apr 19 05:20:47 2022
16NAMESPACE: gitlab
17STATUS: deployed
18REVISION: 1
19TEST SUITE: None
20NOTES:
21Your GitLab Runner should now be registered against the GitLab instance reachable at: "https://gitlab.com/"

安装完成后就会多出来一个tag为k8s-runner的runner。
直接需要使用linux指令安装的,也可以参考官方文档,注意安装过程中的名称和tag,在有多个runner时,是需要通过tag字段来区分具体使用哪个runner。

备注:如果使用云磁盘进行缓存,安装完成后,可以通过如下指令查看到对应的碰盘信息:

 1[root@testcce-68506-l3jp4 gitlab-runner]# kubectl get sc
 2NAME                PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
 3csi-disk            everest-csi-provisioner         Delete          Immediate              true                   5d23h
 4csi-nas             everest-csi-provisioner         Delete          Immediate              true
 5……
 6[root@testcce-68506-l3jp4 gitlab-runner]# kubectl get pv
 7NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS   REASON   AGE
 8pvc-04900bed-40c6-46d9-8c8b-b722e61698d1   20Gi       RWO            Delete           Bound    gitlab/gitlab-runner-cache    csi-disk                6m20s
 9pvc-c5005850-5fdb-4a85-bc39-41044997e13f   10Gi       RWO            Delete           Bound    monitoring/pvc-prometheus-0   csi-disk                5d23h
10[root@testcce-68506-l3jp4 gitlab-runner]# kubectl get pvc
11No resources found in default namespace.
12[root@testcce-68506-l3jp4 gitlab-runner]# kubectl get pvc -A
13NAMESPACE    NAME                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
14gitlab       gitlab-runner-cache   Bound    pvc-04900bed-40c6-46d9-8c8b-b722e61698d1   20Gi       RWO            csi-disk       6m30s
15monitoring   pvc-prometheus-0      Bound    pvc-c5005850-5fdb-4a85-bc39-41044997e13f   10Gi       RWO            csi-disk       5d23h

二、配置gitlab pipeline

这里使用的测试代码是:https://github.com/361way/java ,这里的代码只到编译成docker images部分。对于配置pipeline和发布到deployment服务部分没有定义,我们在拉取完代码并上传到gitlab项目后,新增.gitlab-ci.yml文件和deployment.yaml文件,具体在gitlab上的结构如下图:

gitlab-project-repo
gitlab-project-repo

.gitlab-ci.yml文件的内容如下:

 1image: docker:stable
 2stages:
 3  - package
 4  - docker_build
 5  - deploy_k8s
 6variables:
 7  KUBECONFIG: /etc/deploy/config
 8  MAVEN_OPTS: "-Dmaven.repo.local=/opt/cache/.m2/repository"
 9mvn_build_job:
10  image: maven:3.3-jdk-8
11  stage: package
12  tags:
13    - k8s-runner
14  script:
15    - mvn package -Dmaven.test.skip=true -U -e -X -B
16    - cp target/demoapp.jar /opt/cache
17docker_build_job:
18  image: docker:latest
19  stage: docker_build
20  tags:
21    - k8s-runner
22  script:
23    - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD swr.la-north-2.myhuaweicloud.com
24    - mkdir target
25    - cp /opt/cache/demoapp.jar target/demoapp.jar
26    - docker build -t swr.la-north-2.myhuaweicloud.com/testca/gitlabci-java-demo:$CI_PIPELINE_ID .
27    - docker push swr.la-north-2.myhuaweicloud.com/testca/gitlabci-java-demo:$CI_PIPELINE_ID
28
29deploy_k8s_job:
30  image:
31    name: bitnami/kubectl:latest
32    entrypoint: [""]
33  stage: deploy_k8s
34  tags:
35    - k8s-runner
36  before_script:
37    - echo $kube_config |base64 -d >  /.kube/config
38  script:
39    # - docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD swr.la-north-2.myhuaweicloud.com
40    # - mkdir -p /etc/deploy
41    - sed -i "s/IMAGE_TAG/$CI_PIPELINE_ID/g" deployment.yaml
42    - cat deployment.yaml
43    - kubectl --kubeconfig /.kube/config apply -f deployment.yaml
44    - echo "finish!

这里主要分为三个阶段(stages),分别是:
1. 使用maven镜像,通过mvn指令进行编译打包;
2. 使用docker指令,通过Dockerfile文件的定义打包成image镜像,并上传到华为云镜像仓库SWR(和registry、harbor的作用一样);
3. 通过预定义的deployment.yaml文件,在k8s上发布服务。

deployment.yaml文件的内容如下:

 1apiVersion: apps/v1
 2kind: Deployment
 3metadata:
 4  labels:
 5    version: v1
 6  name: javatest
 7  namespace: default
 8spec:
 9  selector:
10    matchLabels:
11      app: javatest
12      version: v1
13  template:
14    metadata:
15      annotations:
16        metrics.alpha.kubernetes.io/custom-endpoints: '[{"api":"","path":"","port":"","names":""}]'
17      labels:
18        app: javatest
19        version: v1
20    spec:
21      containers:
22        - image: 'swr.la-north-2.myhuaweicloud.com/testca/gitlabci-java-demo:IMAGE_TAG'
23          name: container-0
24          resources:
25            requests:
26              cpu: 1000m
27              memory: 1024Mi
28            limits:
29              cpu: 1000m
30              memory: 1024Mi
31  replicas: 1
32  minReadySeconds: 0
33  strategy:
34    type: RollingUpdate
35    rollingUpdate:
36      maxSurge: 0
37      maxUnavailable: 1
38
39---
40apiVersion: v1
41kind: Service
42metadata:
43  name: javatest
44  labels:
45    app: javatest
46  namespace: default
47  annotations: {}
48spec:
49  selector:
50    app: javatest
51  externalTrafficPolicy: Cluster
52  ports:
53    - name: cce-service-0
54      targetPort: 8080
55      nodePort: 0
56      port: 8080
57      protocol: TCP
58  type: NodePort

三、配置环境变量

这个时候触发的gitlab pipeline还是有问题的,因为里面很多变量是获取不到值的,变量的配置可以通过Settings > CI / CD > Variables完成配置:

gitlab-pipeline-variables
gitlab-pipeline-variables

这里注意选择的masked可以在日志中隐藏掉敏感信息,另外这里的kube_config使用不是直接原始值,是通过base64进行了简单的加密操作的:

1echo $(cat ~/.kube/config | base64) | tr -d " "

同时也可以发现,在.gitlab-ci.yml文件中有一个echo $kube_config |base64 -d > /.kube/config对应的解密动作。

gitlab-pipeline-jobs
gitlab-pipeline-jobs

参考文档:
华为云CCE之PV、PVC和StorageClass
使用GitLab CI运行GitLab Runner并执行Pipeline
【上面的内容和 https://www.alibabacloud.com/help/zh/container-service-for-kubernetes/latest/use-gitlab-ci-to-run-a-gitlab-runner-and-run-a-pipeline-on-kubernetes 该链接里的内容一样】