系统环境

  • 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

Kubernetes部署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官方文档

文章作者: 鲜花的主人
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 爱吃可爱多
Gitlab Kubernetes Gitlab Kubernetes
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝