Gitlab-CICD實踐篇


一.背景

隨着公司項目使用gitlab越來越多,業務發布的次數越來越頻繁,對於發布效率提出了更高的要求。從2012開始,Gitlab官方開始集成了Continuous Integration (CI) & Continuous Delivery (CD)功能。本文主要針對該功能的實踐做一個分享。

GitLab CI/CD可以做很多事情,下圖展現了GitLab CI/CD工作流程中整個的服務能力,而無需使用外部工具來交付軟件。
file

在介紹實踐方案之前,我們先簡單的了解一下和Continuous Integration (CI) & Continuous Delivery (CD)功能有關的相關知識。

二.基礎知識

術語介紹
file

gitlab-pipeline
一次pipeline其實相當於一次任務構建,里面可以包含多個流程,如安裝依賴、運行測試、編譯代碼、部署測試服務器、部署生產服務器等。任何提交或者Merge Request的合並都可以觸發pipeline,觸發pipeline創建的方式主要有如下。如需詳細了解,請查閱官網
file

gitlab-stage
Stage表示一個構建階段,我們可以在一個Pipeline中定義多個Stage,這些Stage會有以下特點:

所有Stage會按照Stages參數里定義的順序串行執行,即當一個Stage完成后,才會執行下一個Stage。
默認情況下只有當所有Stage成功后,最終的pipeline構建任務才會成功。
默認情況下任何一個Stage失敗,那么后面的Stage不會執行,該構建任務最終會失敗。

pipeline和stage的關系簡單理解為下圖。
file

gitlab-job
job表示構建工作,即某個Stage里面執行的工作內容。我們可以在同一個Stage里面定義多個Job,這些Jobs會有以下特點:

相同Stage中的Job會並行執行。
相同Stage中的Job都執行成功時,該Stage才會成功。
如果任何一個Job失敗,那么該Stage失敗,即該構建任務失敗。

stage和jobs的關系簡單理解為下圖。
file

我們以某個pipeline為例解釋pipeline、stage、job的含義,具體請看下圖。
file

gitlab-ci-yaml
pipeline執行的內容使用ymal語言進行描述,默認文件名為.gitlab-ci.yml,該文件默認放在倉庫的根目錄下即可生效。

下表對gitlab 11.11.4版本中.gitlab-ci.yml文件里常用的關鍵字參數進行簡單說明。
file
file
file

gitlab-runner
.gitlab-ci.yml文件里的內容由誰來執行呢,答案就是gitlab-runnter,一般gitlab-runner會和gitlab所在服務器進行隔離,因為一個任務的構建,往往會執行編譯、測試、發布的過程,這個過程會大量消耗系統資源。gitlab-runner幾乎可以安裝在任何機器上。下面介紹gitlab-runner的官方倉庫源安裝方式。關於gitlab-runner的其他安裝方式請查閱官方文檔(https://docs.gitlab.com/runner/install/)。

1.添加倉庫源

# For Debian/Ubuntu/Mint
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash

# For RHEL/CentOS/Fedora
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash

2.安裝指定的gitlab-runner版本,比如這里安裝11.11.4版本。

sudo apt-get install gitlab-runner=11.11.4

# for RPM based systems
sudo yum install gitlab-runner-11.11.4

3.點擊左側欄Settings->CI/CD->Runners->Collapse獲取runner的token,如下圖。
file

4.注冊gitlab-runner到gitlab實例。
file

三.實踐方案

該實踐方案主要介紹微服務項目使用gitlab自帶的GitLab Continuous Integration (CI) & Continuous Delivery (CD)功能,在gitlab提供的runner里面進行打包、測試、發布。

持續集成主要是代碼編譯和打包的過程,一般最終會集成一個適合業務場景的系統層docker鏡像。下面為集成系統層docker鏡像Dockerfile的主要內容:

FROM debian:stretch

# 准備軟件包文件
ADD soft/ /data/soft/

# 安裝基本軟件
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y vim htop wget dnsutils dmidecode ipmitool pciutils perl \
    rsync screen less sysstat at stress tcpdump lsof curl telnet ntp rsyslog sudo locales logrotate cron supervisor \
    numactl openssh-server-x509 openssh-client iptables gawk filebeat mongodb3.4.16 graphviz \
       && apt-get clean

# 安裝開發環境
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && apt-get install -y python python-pip gcc g++ build-essential python-dev python-setuptools python-smbus \
    build-essential libncursesw5-dev libgdbm-dev libc6-dev zlib1g-dev libsqlite3-dev tk-dev libssl-dev openssl \
    libffi-dev cmake automake python-setuptools libtcmalloc-minimal4 sockstat strace gdb graphviz \
    && apt-get clean

# 安裝python3.7
RUN cd /data/soft/ && tar xf /data/soft/Python-3.7.0.tgz && cd Python-3.7.0 && ./configure --enable-optimizations --with-ssl-default-suites=openssl --enable-shared \
    && make && make install && cp libpython3.7m.so.1.0 /lib64/  && ldconfig && rm -rf /data/soft

# 業務啟動腳本
COPY entrypoint.sh /sbin/entrypoint.sh
ENTRYPOINT ["/bin/bash", "-x", "/sbin/entrypoint.sh"]

那么怎么把docker鏡像推送到docker倉庫呢?可在.gitlab-ci.yml文件中進行描述,把build好的鏡像推送到gitlab內置的registry中。關於gitlab內置的registry部署可參考官網說明
(https://docs.gitlab.com/ce/user/packages/container_registry/index.html)。下面為打包並上傳容器鏡像stage的主要內容。

build_push:
  only:
    refs:
      - tags
    variables:
      - $CI_COMMIT_REF_NAME =~ /^rel_[0-9].*$/  # 規定必須通過打tag且名字為rel_xxx的格式才觸發pipeline。
  tags:
    - docker
  stage: ex_build
  script:
    # build docker image
    - docker login $DOCKER_REGISTRY
    - echo "$ docker pull $BUILD_IMAGE"
    - docker pull $BUILD_IMAGE  # 防止$BUILD_IMAGE更新后,runner會緩存,故在build之前先pull一次。
    - echo "$ docker build -t $image"
    - docker build --no-cache -t $image .  
    - echo "$ docker tag  $image $latest"
    - docker tag  $image $latest

    # push  docker image
    - echo "$ docker push $image"
    - docker push $image
    - echo "$ docker push $latest"
    - docker push $latest
    - docker logout $DOCKER_REGISTRY
  when: manual  # 手工確認
  allow_failure: false
  environment:
    name: build

gitlab-runner中對應job的部分日志截圖如下:
file

持續交付CD
持續交付或者持續發布的方式其實有很多種,理論上只要服務方提供了發布接口,你就可以封裝在.gitlab-ci.yml文件里使用gitlab-runner調用api進行自動發布。下面主要介紹容器的發布方式。

發布容器時主要調用自建容器服務的發布接口,其中主要的stage內容如下:

deployment_production:
  only:
    refs:
      - tags
    variables:
      - $CI_COMMIT_REF_NAME =~ /^exrel_[0-9].*$/
  tags:
    - docker
  stage: ex_deployment_production
  script:
    # 更新當前環境下指定渠道
    - deploy_service ${CI_ENVIRONMENT_NAME} "$image"  #image為持續集成build后push到registry的docker鏡像。deploy_service是封裝容器發布過程的函數。該函數主要是根據傳入的image,請求k8s的kube接口進行微服務發布。
  when: manual
  environment:
    name: production

gitlab-runner中發布game微服務的job日志截圖如下。
file

發布流程
微服務的發布流程主要分2種類型:常規發布和熱更發布。常規發布需要重建容器,熱更發布無需重建容器。

下面為常規發布場景下整體的發布流程。
file

熱更發布
核心思路是把需要熱更的內容put到etcd集群,服務端集群自動獲取內容進行熱更,下面為熱更發布場景下整體的發布流程。
file

四.效果展示

常規發布下的pipeline
file

熱更發布下的pipeline
file


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM