基於 Gitlab + Harbor + K8s + Kuboard 的 CI 實踐

張臧乾發表於2023-03-16

CI/CD 概念

CI/CD 是一種透過在應用開發階段引入自動化來頻繁向客戶交付應用的方法。CI/CD 的核心概念是持續整合、持續交付和持續部署。作為一種面向開發和運維團隊的解決方案,CI/CD 主要針對在整合新程式碼時所引發的問題(亦稱:“整合地獄”)。

具體而言,CI/CD 可讓持續自動化和持續監控貫穿於應用的整個生命週期(從整合和測試階段,到交付和部署)。

下圖展示了當前比較典型的持續構建整合的一種做法。

圖片

大概流程為我們研發工程師程式碼提交到 GitLab 之後,使用 GitLab 的流水線自動編譯打包 docker 映象,提交到 Harbor,然後通知 Kuboard 進行自動拉取映象,部署最新程式碼。

廢話不多說,我們進入實戰環節。

先決條件

  1. 搭建 GitLab 服務
  2. 搭建 Harbor 服務
  3. 搭建 K8s 叢集以及 Kuboard 服務

請注意,因為 k8s 在1.20.x(包含)版本以後棄用 docker 執行容器而採用containerd ,因此本案例採用的是 1.19.5 版本的 k8s 叢集,安裝時請留意。

安裝註冊 GitLab Runner

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash

# 搜尋可用版本
yum list gitlab-runner --showuplicates | sort -r

# 指定版本安裝
yum install gitlab-runner-10.8.2-1 -y --nogpgcheck

# 註冊 runner,executor 選擇使用 docker,表示在 docker 容器中執行我們的 ci 流程
sudo gitlab-runner register -n \
  --url http://gitlab.example.com/ \
  --registration-token YOUR-REGISTRATION-TOKEN \
  --executor docker \
  --docker-image "docker:20.10.16" \
  --docker-privileged \
  --docker-volumes "/certs/client" \
  --docker-volumes "/var/run/docker.sock:/var/run/docker.sock"

如何檢視 registration-token?管理員賬戶登入GitLab,進入“管理區域”頁面,左側“概述”選單下選擇“Runners”,即可看到 registration-token。如下圖
圖片

專案配置 .gitlab-ci.yml

自定義 maven 映象

因為我們的後端專案需要從 maven 私服拉取二方庫,因此需要在將私服的 settings 配置檔案加入到映象中去,以便後續在 docker 容器中編譯程式碼時可以訪問 maven 私服拉取依賴。

建立Dockerfile 如下:

FROM maven:3.6.3-jdk-11-slim
ADD ./settings.xml /root/.m2/settings.xml

然後執行命令構建並推送 maven 映象至映象私服。

# 構建 maven 映象
docker build -f /path/to/your/Dockerfile . -t harbor.example.com/respository/maven:3.6.3-jdk-11-slim
# 推送至私服,推送前記得使用 docker login 登入私服
docker push harbor.example.com/respository/maven:3.6.3-jdk-11-slim

獲取 Kuboard CI 指令碼

Kuboard 獲取 CI 指令碼非常簡單,找到需要整合的專案,然後選擇 "CI/CD 整合",根據提示選擇(沒有則建立)秘鑰即可獲得指令碼,此指令碼用於在將 docker 映象推送私服後,通知 Kuboard 更新映象。如下圖所示。
獲取 cicd 指令碼
獲取 cicd 指令碼

後端配置模板

在專案根目錄建立 .gitlab-ci.yml 檔案,以 Java 專案為例,配置檔案內容模板如下:

image: docker:20.10.16

variables:
  DOCKER_TLS_CERTDIR: "/certs"
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

# maven 快取,不必每次打包都從遠端倉庫下載 jar 包
cache:
  paths:
    - .m2/repository
    - target/*.jar

stages:
  - build
  - package
  - deploy

build-jar:
  # 流程節點使用的基礎映象,使用該映象建立容器,在容器中執行 script 中所配置的命令
  # 如果你是前端專案,可以變更改映象,例如使用 node:latest,script 配置為 npm install build:prod
  image: harbor.mgdaas-int.com/arch/maven:3.6.3-jdk-11-slim
  stage: build
  script:
    - mvn clean package -DskipTests=true
  artifacts:
    paths:
      - target/*.jar
  cache:
    paths:
      - .m2/repository

build-docker-image:
  stage: package
  services:
    - name: docker:dind
      entrypoint: [ "dockerd-entrypoint.sh", "--tls=false" ]
  before_script:
    - docker login harbor.mgdaas-int.com --username admin --password Harbor123
  script:
    - docker  build . -t harbor.mgdaas-int.com/mgdaas-gateway/mgdaas-gateway:latest
    - docker push harbor.mgdaas-int.com/mgdaas-gateway/mgdaas-gateway:latest

notify-k8s:
  stage: deploy
  image: alpine:latest
  script:
    - sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
    - apk add --update curl
    # 此處為我們在 Kuboard 獲取到的 CI 指令碼
    - |
      curl -X PUT \
          -H "Content-Type: application/yaml" \
          -H "Cookie: KuboardUsername=zhangzangqian; KuboardAccessKey=zcsee8ax35nx.53p74dj4zpstx5t8fs7p2722z76564xt" \
          -d '{"kind":"deployments","namespace":"oa","name":"mgdaas-gateway"}' \
          "http://kuboard.mgdaas-int.com/kuboard-api/cluster/default/kind/CICDApi/zhangzangqian/resource/restartWorkload"

如此提交程式碼之後便可以看到 GitLab CI/CD 的流水線開始自動執行了。

執行結果
執行結果

相關文章