Gitlab Pipeline+Supervisor 實戰Python專案CI/CD

redhatxl發表於2019-05-04

一.背景

談到到CI/CD,我們不禁會想到Gitlab + Jenkins + Docker等一些列優秀的工具,Jenkins以其豐富的外掛及靈活配置已經非常好的滿足我們日常工作中的CI/CD需求,通常的做法為Gitlab配置webhook,開發人員通過push程式碼或merge request可以觸發執行一些列的測試部署上線工作,打通了開發到部署到整個生命週期,完成持續整合持續構建。 在Gitlab 也是具有一套CI/CD到框架,通過簡單的註冊Gitlab Runner,根據業務測試部署需求撰寫 .gitlab-ci.yml檔案,即可輕鬆的實現CI/CD,無需多餘的工具介入,方便快捷。 本文對記錄下利用Gitlab pipeline+supervisor來實戰部署Python對tornado專案。

二.基礎必備

2.1 Gitlab

2.1.1 Gitlab 簡介

Gitlab為一套開原始碼倉庫管理系統,有CE(社群版)和EE(企業版),相較與共有的程式碼管理平臺Githab,Gitlab常用與私有化部署在企業內網,方便對程式碼倉庫及人員的分組及許可權管控,輕鬆方便管理團隊開發流程及多人合作開發規範,通過註冊Runner,編寫.gitlab-ci.yml實現快速專案CI/CD。

2.1.2 搭建部署

  • 更新yum源
cat > /etc/yum.repos.d/gitlab-ce.repo <<EOF
[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el\$releasever/
gpgcheck=0
enabled=1
EOF
複製程式碼
  • 安裝
yum clean all && yum makecache
sudo yum install gitlab-ce        #自動安裝最新版
sudo yum install gitlab-ce-x.x.x    #安裝指定版本
複製程式碼
  • 配置啟動
1.修改gitlab配置檔案指定為安裝gitlab伺服器ip和自定義埠: vim /etc/gitlab/gitlab.r
2.重置並啟動GitLab
執行:
gitlab-ctl reconfigure
gitlab-ctl restart
初始賬戶: root 密碼: 5iveL!fe

自定義密碼:
gitlab-rails console production     #開始初始化密碼
u=User.where(id:1).first        來查詢與切換賬號(User.all 可以檢視所有使用者)

u.password=12345678  設定密碼
u.password_confirmation=12345678
u.save!
exit
複製程式碼
  • 修改預設儲存路徑

更改倉庫儲存位置 預設時GitLab的倉庫儲存位置在“/var/opt/gitlab/git-data/repositories”,在實際生產環境中我們會新建資料盤,將重要資料儲存在單獨的資料盤分割槽中,我這裡規劃把資料存放在“/data/gitlabdata”目錄下。

mkdir -pv /data/gitlabdata 
vim /etc/gitlab/gitlab.rb 

git_data_dirs({ "default" => { "path" => "/data/gitlabdata" } })

1 在沒有資料的情況下

[root@gitlab ~]# gitlab-ctl stop
[root@gitlab ~]# gitlab-ctl reconfigure //使修改生效


2.如果 /var/opt/gitlab/git-data 目錄已經存在Git倉庫資料, 你可以用下面的命令把資料遷移到新的位置:

# 準備遷移之前要停止GitLab服務,防止使用者寫入資料。
[root@gitlab ~]# gitlab-ctl stop

# 注意 'repositories'後面不帶斜槓,而
# '/home/gitlab-data'後面是有斜槓的。
[root@gitlab ~]# rsync -av /var/opt/gitlab/git-data/repositories /data/gitlabdata/

# 如果需要修復許可權設定,
# 可執行下面的命令進行修復。
[root@gitlab ~]# gitlab-ctl reconfigure

# 再次檢查下  /data/gitlabdata 的目錄. 正常情況應該有下面這個子目錄:
# repositories
複製程式碼
  • 備份還原
  • 備份

確保/var/opt/gitlab/backups 目錄存在並且gitlab有許可權寫入檔案

gitlab-rake gitlab:backup:create
複製程式碼
  • 還原
將備份檔案拷貝到/var/opt/gitlab/backups下
停止相關資料連線服務
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq

1. 制定時間戳恢復
從備份恢復
從指定時間戳的備份恢復(backups目錄下有多個備份檔案時):

sudo gitlab-rake gitlab:backup:restore BACKUP=1500809139

2.從預設備份恢復(backups目錄下只有一個備份檔案時):

sudo gitlab-rake gitlab:backup:restore

啟動Gitlab
sudo gitlab-ctl start
sudo gitlab-ctl reconfigure

修改預設備份目錄【可選】
你也可以通過修改/etc/gitlab/gitlab.rb來修改預設存放備份檔案的目錄:

gitlab_rails['backup_path'] = '/data/gitlabbackup'

/data/gitlabbackup修改為你想存放備份的目錄即可, 修改完成之後使用gitlab-ctl reconfigure命令過載配置檔案即可

可配合定時任務或上傳到物件儲存,實現異地程式碼備份。
複製程式碼

2.1.3 Gitlab CI/CD概念

  • CI/CD的優勢:
    • 儘可能快地檢測錯誤:在開發人員的腦海中解決問題
    • 減少整合問題:更小的問題更容易消化
    • 避免複合問題:讓團隊更快,更自信地發展
    • 確保每個更改都是可釋放的:在呼叫之前測試所有內容,包括部署
    • 降低每次釋出的風險:使釋出“無聊”
    • 更頻繁地提供價值:可靠的部署意味著更多的版本
    • 嚴密的客戶反饋迴圈:客戶對變更的快速和頻繁反饋

圖片描述

  • Gitlab runner

Gitlab ci/cd是由獨立的runner程式完成,runner採用go語言編寫,因此可以很好的進行跨平臺,通常可以將runner部署到任何gitlab server之外的伺服器,從而避免對gitlab server的影響,gitlab runner相當於一個agent安裝在目標伺服器,或這多個專案公用一個runner,runner伺服器單獨來執行構建任務。 runner型別:

  • GitLab-Runner可以分類兩種型別:Shared Runner(共享型)和Specific Runner(指定型)。
  • Shared Runner:這種Runner(工人)是所有工程都能夠用的。只有系統管理員能夠建立Shared Runner。
  • Specific Runner:這種Runner(工人)只能為指定的工程服務。擁有該工程訪問許可權的人都能夠為該工程建立Shared Runner。
    圖片描述

根據上圖可以看出,gitlab-runner可以安裝到最終專案部署當伺服器上,一個伺服器可以部署多個runner,也可以單獨一臺伺服器專用與common-runner來負責多個專案當部署。

  • Pipeline

Pipeline相當於一次整體的構建任務,其中包含有多個流程步驟(Stages),例如檢測程式,清理環境,安裝依賴,測試,編譯,部署到dev/prod環境,程式檢查等,可以對比jenkins構建工作流來理解。任何提交程式碼或者 Merge Request 的合併都可以觸發 一條Pipeline。

  • Stages

Stages為一條Pipeline的基本構成步驟,一條pipeline的所有stages構成來一條完整的CI/CD工作流。 Stages特徵:

  • 順序執行,第一個stage執行完畢,第二個stage開始
  • stage序列執行,前面的一個stage執行失敗,後面的所有stage不會執行
  • 所有的stage執行都成功,該pipeline任務為成功。
  • Jobs

Jobs為單個stage中的具體執行工作 Jobs特徵:

  • 同一個stage的jobs會並行執行
  • 同一個stage中的所有jobs都執行成功,該stage為成功
  • 一個stage中的任意一個jobs執行失敗,該stage為失敗,該stage所在的pipline執行失敗

2.2 YAML

可參考:www.imooc.com/article/276…

2.3 Supervisor

  • 背景

在部署Python專案中,啟動Django專案或Tornado專案,如果將程式放在前臺或是利用nohup &放在後臺,gitlab pipeline無法進行退出,可以通過編寫指令碼部署,但是耗時耗力且需要做單獨對程式監控,不便於我們管理維護,因此利用Superviosr來實現對部署專案start/stop/restart/reload服務管理,通過fork/exec的方式把這些被管理的程式,當supervisor的子程式來啟動,完美解決來專案部署對難題。

  • 簡介

Superviosr為用Python語言開發對一套通用程式管理系統,可利用pip或yum進行安裝,其能將一個普通對命令列程式變為daemon,並監控其程式狀態,可通過配置如果監控程式異常退出則自動對其進行重啟,同時也擁有web管理介面方便管理檢視。

  • 配置部署
yum install supervisor  # 安裝

安裝完成後配置檔案會在/etc/supervisord.conf,對此可自行修改
[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 檔案,supervisorctl 會使用
;chmod=0700                 ;socket檔案的mode,預設是0700
;chown=nobody:nogroup       ;socket檔案的owner,格式:uid:gid
 
;[inet_http_server]         ;HTTP伺服器,提供web管理介面
;port=127.0.0.1:9001        ;Web管理後臺執行的IP和埠,如果開放到公網,需要注意安全性
;username=user              ;登入管理後臺的使用者名稱
;password=123               ;登入管理後臺的密碼
 
[supervisord]
logfile=/tmp/supervisord.log ;日誌檔案,預設是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日誌檔案大小,超出會rotate,預設 50MB,如果設成0,表示不限制大小
logfile_backups=10           ;日誌檔案保留備份數量預設10,設為0表示不備份
loglevel=info                ;日誌級別,預設info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 檔案
nodaemon=false               ;是否在前臺啟動,預設是false,即以 daemon 的方式啟動
minfds=1024                  ;可以開啟的檔案描述符的最小值,預設 1024
minprocs=200                 ;可以開啟的程式數的最小值,預設 200
 
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通過UNIX socket連線supervisord,路徑與unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通過HTTP的方式連線supervisord
 
; [program:xx]是被管理的程式配置引數,xx是程式的名稱
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程式啟動命令
autostart=true       ; 在supervisord啟動的時候也自動啟動
startsecs=10         ; 啟動10秒後沒有異常退出,就表示程式正常啟動了,預設為1秒
autorestart=true     ; 程式退出後自動重啟,可選值:[unexpected,true,false],預設為unexpected,表示程式意外殺死後才重啟
startretries=3       ; 啟動失敗自動重試次數,預設是3
user=tomcat          ; 用哪個使用者啟動程式,預設是root
priority=999         ; 程式啟動優先順序,預設999,值小的優先啟動
redirect_stderr=true ; 把stderr重定向到stdout,預設false
stdout_logfile_maxbytes=20MB  ; stdout 日誌檔案大小,預設50MB
stdout_logfile_backups = 20   ; stdout 日誌檔案備份數,預設是10
; stdout 日誌檔案,需要注意當指定目錄不存在時無法正常啟動,所以需要手動建立目錄(supervisord 會自動建立日誌檔案)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;預設為false,程式被殺死時,是否向這個程式組傳送stop訊號,包括子程式
killasgroup=false     ;預設為false,向程式組傳送kill訊號,包括子程式
 
;包含其它配置檔案
[include]
files = supervisord.d/*.conf     ;可以指定一個或多個以.conf結束的配置檔案
複製程式碼

通常我們修改include 中的副檔名為.conf來在其下目錄中配置為們自定義的專案。 在supervisord.d中配置我們對具體專案,例如:

[program:myproject]
command=/data/miniconda3/envs/go2cloud_api_env/bin/python /project/myproject/server.py 8011
user=root
stdout_logfile=/project/go2cloud_api/run.log
autostart=true
autorestart=true
startsecs=60
stopasgroup=true
ikillasgroup=true
startretries=1
redirect_stderr=true
複製程式碼
  • 啟動程式
supervisord -c /etc/supervisord.conf 
複製程式碼
  • 客戶端命令
supervisorctl 是 supervisord的命令列客戶端工具

supervisorctl status:檢視所有程式的狀態
supervisorctl stop myproject:停止es
supervisorctl start myproject:啟動myproject
supervisorctl restart myproject: 重啟myproject
supervisorctl update :配置檔案修改後可以使用該命令載入新的配置
supervisorctl reload: 重新啟動配置中的所有程式
...
複製程式碼
  • 把myproject 換成all 可以管理配置中的所有程式

注意事項

supervisor不能監控後臺程式,command 不能為後臺執行命令。

三.實戰部署

3.1 伺服器列表

名稱 IP 軟體 備註
gitlab-server 10.57.61.138 gitlab-server Gitlab 伺服器
gitlab-common-runner 10.57.61.11 gitlab-runner 公用runner伺服器
Des-server 172.21.0.10 miniconda/supervisor 專案部署伺服器

3.2 架構圖

圖片描述
根據上圖,我們可以清晰當看清楚兩種部署模式,多個專案公用一個gitlab-runner,和將gitlab-runner部署到目標伺服器上。由於存在多個專案,方便後期多專案管理,本次我們利用到為公用gitlab-runner。

3.3 前期準備

  • Gitlab-runner服務區的gitlab-runner使用者可以免金鑰登入des-server伺服器
  • Gitlab伺服器安裝配置
  • 在目標伺服器安裝配置conda虛擬環境
  • supervisor部署配置
[program:go2cloud_platform]
command=/data/miniconda3/envs/go2cloud_platform/bin/python /project/go2cloud_platform/runserver start all
user=root
stdout_logfile=/var/log/go2cloud_platform.log
autostart=true
autorestart=true
startsecs=60
stopasgroup=true
ikillasgroup=true
startretries=1
redirect_stderr=true
複製程式碼

3.4 配置部署

3.4.1 Gitalb Runner配置

  • Gitlab runner安裝註冊
    • gitlab-runner安裝
# 配置yum源
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash
# 安裝runner
sudo yum install -y gitlab-ci-multi-runner
複製程式碼
  • 開啟專案Pipelines

有的專案為開啟pipeline,需要手動開啟 settings->General->Visibility, project features, permissions->Pipelines 可以配置所有人或此專案到Members可以配置管理Pipeline

  • 記錄註冊資訊

settings->CI/CD>Runners

圖片描述
記錄註冊url和token
圖片描述

  • 在gitlabrunner伺服器進行註冊
# gitlab runner註冊到平臺
sudo gitlab-ci-multi-runner register
複製程式碼

圖片描述
此處我們選擇的為單機shell執行,如果為docker可以選擇docker,註冊完成後可以返回gitlab web管理介面檢視已經註冊的runner。
圖片描述

也可以對runner進行配置。

  • 配置runner

可以勾選Active,runner為公用對時候,暫停Runner不接受新的jobs 如果沒有制定tag,可以執行在未指定tag的作業。

圖片描述

3.4.2 .gitlab-ci.yml 編寫

stages:
  - clean_env            # 清理環境及殺死程式
  - deploy_src           # 部署原始碼
  - install_dependency   # 更新依賴  
  - restart_server       # 重啟服務
  - check_server         # 檢測服務
  

variables:
  BASE_DIR: "/go2cloud_platform/"

job clean_env_job:
  stage: clean_env
  script:
    - ssh -o stricthostkeychecking=no root@172.16.100.2 pkill supervisord || true
    - ssh -o stricthostkeychecking=no root@172.16.100.2 killall /data/miniconda3/bin/python || true
    - ssh -o stricthostkeychecking=no root@172.16.100.2 killall /data/miniconda3/envs/go2cloud_platform/bin/python || true
    - ssh -o stricthostkeychecking=no root@172.16.100.2 rm -rf /project${BASE_DIR}*
  tags:
    - 51common-runner
  only:
    - dev
  when: always


job deploy_src_job:
  stage: deploy_src
  script:
    - scp -r /home/gitlab-runner/builds/QFafrHEq/0/devops/${BASE_DIR}* root@172.16.100.2:/project${BASE_DIR}
    - ssh -o stricthostkeychecking=no root@172.16.100.2 cp /project/config/config.yml /project${BASE_DIR}
  tags:
    - 51common-runner
  only:
    - dev
  when: always


job install_dependency_job:
  stage: install_dependency
  script:
    - ssh -o stricthostkeychecking=no root@172.16.100.2 /data/miniconda3/envs/go2cloud_platform/bin/python -m pip install -r /project${BASE_DIR}requirements/requirements.txt
  tags:
    - 51common-runner
  only:
    - dev
  when: manual


job restart_server_job:
  stage: restart_server
  script:
    - ssh -o stricthostkeychecking=no root@172.16.100.2 sleep 7
    - ssh -o stricthostkeychecking=no root@172.16.100.2 supervisord -c /etc/supervisord.conf
    - ssh -o stricthostkeychecking=no root@172.16.100.2 ps -ef |grep supervisord |grep -v grep
  tags:
    - 51common-runner
  only:
    - dev
  when: always

job check_server_job:
  stage: check_server
  script:
    - ssh -o stricthostkeychecking=no root@172.16.100.2 sleep 7
    - ssh -o stricthostkeychecking=no root@172.16.100.2 ps -ef|grep "8088"
  tags:
    - 51common-runner
  only:
    - dev
  when: always
複製程式碼

在此我們部署服務分為五個步驟

  • 清理環境:可以配置為全部刪除目標原始碼或這rsync/scp增量覆蓋到目標伺服器,如果增量部署,需要考慮遷移資料庫到重複執行。
  • 部署原始碼:將gitlab-runner伺服器pull下來到程式碼scp到目標伺服器到目標部署目錄,
  • 安裝依賴:此處有可能後期更新requirements,配置為manual手動去執行更新,如果有更新,手動去安裝。
  • 重啟服務:此時啟動為supervisord服務,啟動後可以自動啟動配置到專案服務。
  • 檢測程式:由於此專案為平臺為寫單元測試,部署上去存在可能程式碼有異常程式為能正常啟動,檢測程式是否正常啟動可方便為們知道部署是否成功。

專案中到配置指標和變數可以參考:docs.gitlab.com/ee/ci/yaml/…

  • 檢視pipeline
    圖片描述
    圖片描述
  • 檢視具體jobs資訊
    圖片描述
    如果那個jobs執行失敗可以進行手動retry。
  • 檢視CI/CD charts

圖片描述
charts直觀的展示來構建到成功及失敗圖表。

  • 檢視構建郵件
    圖片描述
  • 在des-server檢視專案

圖片描述

  • 通過web介面檢視

圖片描述
至此一個完整到Gitlab runner就配置完成。

四.總結反思

  • gitlab-runner配置簡單,與gitlab整合友好,無需單獨搭建構建平臺,告警有gitalb傳送。當新建一個專案的時候,不需要配置webhook回撥地址,將部署繼承在程式碼的.gitlab-ci.yml 中易於維護管理。
  • gitlab-ci/cd沒有程式碼審計,需要單獨配置,隨著業務增加,團隊擴充需要單獨構建程式碼審計平臺。
  • 如果小型Devops團隊建議利用Gitlab CI/CD方便管理維護,如果大型gitlab ci/cd無法滿足可以結合jenkins來實現CI/CD。

五.參考資料

相關文章