1. 程式人生 > >GitLab 容器化 CI 流程填坑記(一)

GitLab 容器化 CI 流程填坑記(一)

本文以SpringBoot專案的部署構建為例,對基於GItLab的CI流程進行簡要介紹。

 

環境準備:

1. 系統環境:

作業系統:CentOS 7.2 1511

GitLab:v11.1.4

GitLab-runner:v11.2.0

Docker:17.03.2 ce

 

2. 應用環境:

應用框架:Spring boot v2.0.x

專案構建管理:Maven v3.5.x

 

CI整合流程:

關於證書(HTTPS需要,HTTP請忽略):

注:下述 "hostname.com" 請自行替換為GitLab域名

1. 完整自簽證書:

sudo openssl genrsa -des3 -out /etc/gitlab/ssl/hostname.com.key 2048
sudo openssl req -new -key /etc/gitlab/ssl/hostname.com.key -out /etc/gitlab/ssl/hostname.com.csr
sudo openssl x509 -req -days 3650 -in /etc/gitlab/ssl/hostname.com.csr -signkey /etc/gitlab/ssl/hostname.com.key -out /etc/gitlab/ssl/hostname.com.crt

2. 服務端已有證書:

可直接通過瀏覽器匯出證書,並將檔案存為hostname.com.crt, 存於/etc/gitlab/ssl/(預設)目錄下。

 

完成證書的獲取後,可使用:

openssl s_client -connect hostname.com:443 -CAfile hostname.com.crt -state

進行證書的校驗。

若返回0則表示無問題,如下圖所示:

 

 

具體實現:

1. 安裝GitLab:略(直接容器部署即可)

2. 在GitLab中建立專案:略

3. 安裝runner:

gitlab-runner有多種安裝方式,具體詳見

gitlab-runner安裝 ,本文采用的docker的方式進行runner的部署:

docker run -d --name bala-runner --restart always \
-v /etc/gitlab-runner/certs/hostname.com.crt:/usr/local/share/ca-certificates/hostname.com.crt \
-v /etc/gitlab-runner/certs/hostname.com.crt:/etc/gitlab-runner/certs/hostname.com.crt \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /root/build_cache:/cache \
gitlab/gitlab-runner:latest

注:

1. 第一和第二個 -v 實現證書目錄內容的掛載;

2. 第三個 -v 實現docker.sock的掛載(因為後續要實現docker in docker的使用,即 docker executor);

3. 第四個 -v 實現gitlab-runner cache目錄的掛載(可選),cache相關請參考 docker executor 下的cache部分

 

4. 進入runner更新證書:

docker-enter <name>
update-ca-certificates

沒有 docker-enter 可使用 docker exec -it /bin/bash 進入容器。

docker-enter配置方式請參考這裡

 

5. 註冊runner:

runner註冊的引數很多,可通過下述命令進行檢視(config文件地址):

gitlab-runner register --help

這裡,本文使用如下命令進行runner註冊:

gitlab-runner register -n \
  --url https://hostname.com/ \
  --registration-token Bz7bb9xxxxxxxxxYxf91 \
  --tls-cert-file /etc/gitlab-runner/certs/hostname.com.crt \
  --executor docker \
  --pre-clone-script "git config --global http.sslVerify false" \
  --output-limit 81920 \
  --description "BalaBalaYi Runner" \
  --docker-image "balabalayi/maven-plus-docker:jdk-8-maven-3.5.4-docker-17.03" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

注:

1.url 為 gitlab的地址;

2. registration-token 為專案下的token,可通過 gitlab -> project -> settings -> ci/cd 下獲得,如圖所示:

3. tls-cert-file 為證書目錄,注意與啟動runner容器時的掛載目錄要一致;

4. executor,使用 docker 作為 executor;

5. pre-clone-script 表示 git clone 倉庫程式碼前執行的命令,本文這裡簡化了git的過程,直接禁用了sslVerify,若對環境安全性要求高,請自行配置git ssl;

6. output-limit 為日誌輸出的大小限制,預設為4096 (4MB);

7. description 為 runner 的描述資訊,請自定義;

8. docker-image 為 executor 所採用的預設 docker 映象(會被gitlab-ci.yml中的配置覆蓋)。這裡,因為本文要使用mvn docker:build命令,因此採用了自己封裝的映象(包括 java8+maven3+docker17.03 環境);

9. docker-volumes ,因採用 "docker executor" ,必須掛載宿主機的docker.sock,

10. 如果需要掛載cache到宿主機,docker-volumes 還需新增宿主機目錄到容器內cache目錄(預設為/cache)的對映(可選)。

 

6. 編寫.gitlab-ci.yml

.gitlab-ci.yml 是控制整個ci流程的核心配置檔案,本文僅針對SpringBoot應用構建的幾個要點進行闡述,其它請具體參考 gitlab-ci.yml 指導文件

 

maven環境的引用:

在企業內部,實際專案的構建過程大多依賴私有倉庫等設定,因此預設的maven環境是不能滿足需要的。但是因為在本篇文章所涉及的CI流程中,無論是executor還是runner,都是以容器化的方式託管給GitLab進行操作,所以介紹下如何在該場景下便捷地引用maven的配置,方法有三:

1. 通過自定義官方的maven映象的dockerfile,重新配置指定目錄下的settings.xml,並在內部實現變數,方便後續在CI流程中通過外部定義變數的方式,實現maven自定義動態配置的匯入。

結論:此方法可行。但是maven的配置較多,如果企業內部依賴maven的配置較多,此方法依舊較複雜。何況還要涉及dockerfile的修改及映象的構建。

 

2. 如果配置極少,可直接在 before_script 通過sed等命令,新增配置內容至settings.xml(以預設的settings.xml為基準) 。

結論:此方法在自定義配置專案較少時可用,配置項若較多,則異常繁瑣。

 

3. 將maven的settings.xml拷貝一份,置於專案根目錄下(與pom檔案一起),作為專案本身的配置檔案之一。在.gitlab-ci.yml中定義新的maven變數引用(mvn-setting.xml是自定義的名稱):

variables:
  MAVEN_CLI_OPTS: "-s ./mvn-settings.xml --batch-mode"

然後,在每個stage下對應的指令碼命令中,都可通過引用此變數來執行maven命令:

- mvn $MAVEN_CLI_OPTS clean deploy docker:build -DpushImage

結論:此方法最為簡單粗暴,無須擔心自定義的maven配置是否複雜。缺點是專案多維護了一個配置檔案(其實都多了.gitlab-ci.yml了,也不在乎多這一個)。

 

docker構建所需環境:

如果要實現 docker build 及其它 docker 命令,需要對應的docker環境,上述 /var/run/docker.sock 的掛載就是為此服務的。

除了與宿主機的docker.sock的共享,另外還需要當前環境下的docker安裝。在此針對SpringBoot應用構建,有兩種方式如下:

1. 使用 maven 的 dockerbuild 外掛,通過 mvn 命令在一個 stage 中完成打包以及 docker 的映象構建:

此方法需要使用者自行構建一個包含 JDK+MAVEN+DOCKER 環境的容器映象,然後使用此映象作為 executor 的映象執行CI流程。採用此方法一個命令即可完成打包,推送jar至倉庫,構建docker映象,推動docker映象至倉庫:

mvn $MAVEN_CLI_OPTS clean deploy docker:build -DskipTests -DpushImage

 

2. 分為兩個stage,分別完成打包和映象構建:

此方法,需要使用 cache 或是 artifact 在 package stage 步驟中保留打包後的jar及相關目標檔案,然後在 build stage 步驟中引用 cache 或是 artifact 儲存下來的目標內容進行後續的映象構建。大致的指令碼流程如下:

image: docker:latest

services:
  - docker:dind

stages:
  - package
  - build

# 打包
package:
  image: maven:3-jdk-8
  stage: package
  script:
    - docker login ip:port -u xxx -p xxxx
    - mvn clean deploy 
  cache:
    key: target
    paths:
      - target/*
   

# 構建
deploy:
  stage: deploy
  script:
    - docker login ip:port -u xxx -p xxxx
    - docker build xxx xxx
    - docker push xxx

上述程式碼只是一個示例,cache 和 artifacts 的使用還請參考 這裡,具體語法還請參考 gitlab-ci.yml 指導文件 。

 

docker的部署執行:

目前,部署執行環境主要為兩種,傳統的宿主機環境(物理機或是虛擬機器)以及kubernetes叢集。

1. 宿主機:

此方法大多需要通過ssh實現遠端命令控制,在此給出一個簡單的方法,使用sshpass:

deploy:
  stage: deploy
  script:
    - apt-get install -y sshpass
    - sshpass -p "$DEPLOY_HOST_PASSWORD" ssh -o StrictHostKeyChecking=no -tt [email protected]$DEPLOY_HOST_IP 'if [ -n "`docker ps -qa --filter name=xxx`" ];then docker rm -f xxx;fi'
    - sshpass -p "$DEPLOY_HOST_PASSWORD" ssh -o StrictHostKeyChecking=no -tt [email protected]$DEPLOY_HOST_IP "docker login $REGISTRY_HOST:$REGISTRY_PUBLIC_PORT -u $REGISTRY_ADMIN_USER -p $REGISTRY_ADMIN_USER_PASSWORD"
    - sshpass -p "$DEPLOY_HOST_PASSWORD" ssh -o StrictHostKeyChecking=no -tt [email protected]$DEPLOY_HOST_IP "docker run --name xxx -d $REGISTRY_HOST:$REGISTRY_PUBLIC_PORT/xx/xxx"

上述四行命令分別為:

1. 安裝sshpass;

2. 根據名稱清除已有的正在執行的容器;

3. 登入docker倉庫;

4. 部署執行容器。

 

官方使用ssh免密的方法:Using SSH keys with GitLab CI/CD

 

2. kubernetes叢集:

需要使用者自定義應用的k8s宣告檔案,配置k8s叢集訪問,然後在 .gitlab-ci.yml 中實現部署流程:

k8s-deploy:
  image: xxx
  stage: deploy
  script:
    - kubectl create secret docker-registry xxx --docker-server=https://registry.gitlab.com --docker-username=xxx --docker-password=xxx
    - kubectl apply -f deployment.yml

其它詳細請參考 k8s整合

 

7. 完成CI整合並測試

完成 .gitlab-ci.yml 檔案的編寫後,可通過 GitLab 的 CI Lint 對該檔案進行檢查,確認語法等是否有問題。

確認無問題後可提交併推送專案至 GitLab 即可觸發CI流程。具體過程可通過project -> ci/cd -> pipelines 進行檢視:

 

 

 

 

 

 

相關內容及文章引用:

openssl 工具使用

gitlab-runner官網文件

gitlab ci官網文件

 

結語:

最後感謝 Du Wenkai 小夥伴的技術和環境支援。