基于.NetCore结合docker-compose实践Gitlab-CI/CD 排坑指南
引言
? ? ? ? ?看過docker-compose真香的園友可能留意到當時是【把部署dll文件拷貝到生產機器】,即時打包成鏡像并啟動容器,并沒有完成CI/CD。
? ? ? ? ?經過長時間實操驗證,終于完成基于Gitlab的CI/CD實踐,本次實踐的坑位很多, 實操過程盡量接近最佳實踐(不做hack, 不做騷操作),記錄下來加深理解。
? ? ? ? 第一部分:Gitlab CI/CD 原理 和 Gitlab Runner 安裝(這里使用shell執行器)
? ? ? ? 第二部分:Gitlab CI/CD 實踐:
? ? ?宏觀項目架構圖
? ? .gitlab-ci.yml 文件
? ? ?項目部署目錄
第一部分:gitlab CICD原理
? ? ? ?① Gitlab CI/CD架構:
Gitlab CI/CD ??存儲【構建】和【構建狀態】的api應用程序, 提供友好的管理界面, ?構建過程由 .gitlab-ci.yml文件定義,而這個文件一般置于代碼倉庫的根目錄。
Gitlab Runner 執行構建過程的應用程序,可與Gitlab Server 形成分布式部署, 如上圖所示, 其通過api 與Gitlab Server交互
? ?
② Gitlab CI/CD 配置界面 & Gitlab Runner 安裝
? ? ? ? ? ?Gitlab CICD的界面配置權限取決于你在Gitlab Server 中的角色,我的角色是maintainer, 足夠創建自定義的runner。
? ? ? ? ? ?本次演示【自定義Runner】,gitlab runner安裝------>?gitlab runner注冊?(與Gitlab Project建立聯系的過程)
? ? ? 注冊時需要關注的兩個配置是:
? ? tags? 可理解為與這個Runner有關的Pipeline任務, 在.gitlab-ci.yml用到
? ? runner ?executor:可理解為執行的初始環境,這里使用shell方式
? ? ? 注冊過程和結果請參考下圖:
?
第二部分:基于docker-compose的Gitlab-CI ?實踐
? ? ?①? 項目架構圖
? ? ??
Gitlab-CI Pipeline構建ReceiverAPP, webAPP鏡像(附帶本次git:tag)并推送到hub.docker.com;
? ?Gitlab-CD docker-compose拉取遠端nginx、ReceiveAPP、webapp鏡像啟動容器。?
? ? ?Pipeline對每一次提交或合并都會執行build任務, 形成Continous Intergation
? ? ?Pipeline對git: tag會執行build_Image任務,自動構建至deploy_staging任務,這樣就能形成基于git:tag的部署版本管理(部署出錯,也能很快回滾到上次的部署tag)
本處使用Gitlab Runner 服務器作為staging部署機器;原則上不允許自動隨意部署Prod(實踐中登陸到 Prod機器上執行部署命令,以下GitLab-CD也沒有完成Prod的自動部署過程,自行補上登陸終端的腳本即可)? ?
③ .gitlab-ci.yml 文件
? ? ? ?對比架構,Gitlab Pipeline定義了? build-->build_image-->deploy 三個任務, 某些任務還包括不同分支Job,寫.gitlab-ci.yml 的過程就是以上執行動作腳本化。
更多Gitlab-CI的資料
1 stages:2 - build
3 - build_image
4 - deploy
5
6 variables:
7 #CI_DEBUG_TRACE: "true" # 增加調試追蹤
8 deploy_path: "/home/xxxx/eqidmanager"
9
10 before_script:
11 - "docker info"
12
13 build:
14 stage: build
15 script:
16 - "for d in $(ls src);do echo $d;prog=$(pwd)/src/$d/$d.csproj; dotnet build $prog; done"
17 tags:
18 - another-tag
20build_image:EqidManager:
21stage: build_image
22script:
23 - dotnet publish src/EqidManager/EqidManager.csproj -c release -o ../../container/app/publish/
24 - docker build --pull -t $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME container/app
25 - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
26 - docker push $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME
27tags:
28 - another-tag
29 only: # Pipeline Job構建策略
30 -tags
31
32build_image:EqidReceiver:
33stage: build_image
34script:
35 - dotnet publish src/EqidReceiver/EqidReceiver.csproj -c release -o ../../container/receiver/publish
36 - docker build -t $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME container/receiver
37 - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
38 - docker push $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME
39tags:
40 - my-tag
41only:
42 -tags
43
44deploy:staging:
45stage: deploy
46script:
47 -cd $deploy_path
48 - export TAG=$CI_COMMIT_REF_NAME # 引入本次CI的git:tag名稱,覆蓋.env 文件默認配置
49 - "docker-compose build" # 根據docker-compose命令用法, 會自動merge docker-compose.yml和override文件
50 - "docker-compose up -d"
51tags:
52 - my-tag
53
54deploy:prod:
55stage: deploy
56script:
57 -# TODO 需要寫腳本登陸到Prod機器上
58 - export TAG=$CI_COMMIT_REF_NAME
59 -cd $deploy_path
60 - "docker-compose build"
61 - "docker-compose up -d"
62tags:
63 - my-tag
64 when: manual
?這里有些知識點和 坑位需要指出:
第8行:預先定義的環境變量,該變量定義gitlab CD的部署目錄
第16行:? 對src開發目錄下兩個程序執行dotnet build命令
第17行:tags定義具備該tags的Runner可以執行該任務, 注意這里的tags必須是字符串數組
第23-26行:構建鏡像并推送到鏡像倉庫的過程,用到兩種CI變量
? - 密鑰變量CI_REGISTRY_USER、CI_REGISTRY_PASSWORD ,可在GitLab-CI 界面配置
? ? ?- 預定義變量CI_COMMIT_REF_NAME, 該變量標記構建項目的git:branch或git:tag名稱,用于生成鏡像tag
? ? ?注意變量可被重寫,重寫有優先級 http://www.ttlsa.com/auto/gitlab-cicd-variables-zh-docum ent/
第29行;only定義此Job只在產生git:tag時被觸發,與上面我們使用 CI-COMMIT_REF_NAME 變量相互呼應
第47行:Gialab-CI pipeline每個Job會重新拉取git源碼執行Job任務(可登錄到Gitlab Runner工作目錄下觀察Runner執行過程),CD時需要選擇合適目錄,這是deploy_staging上使用deploy_path CI變量的原因
第48行:注入本次Gitlab-CI git:tag名稱, 實際上是覆蓋了.env同名環境變量
第49行:若存在docker-compose.yml、docker-compose.override.yml 兩個文件,docker-compose命令會自動merge這2個文件(使用docker-compose config命令查看merge 之后的結果)。
③ Continous Deploy
?在Gitlab Runner服務器的{deploy_path}路徑下建立了如下部署文件:
├── appsettings.secrets.json├── docker-compose.override.yml
├── docker-compose.yml
├── .env
├── EqidManager.db
├── nginx
│?? ├── Dockerfile
│?? └── nginx.conf
└── receiver.secrets.json
最佳實踐:定義docker-compose.yml、docker-compose.override.yml 兩個yml文件,前者定義相對易變的容器服務,后者定義基礎容器服務,docker-compose 命令在執行時會自動merge
軟件工作有種最佳實踐, 密鑰文件不要進入代碼管理,因此我們定義appsetting.secrets.json 和 receiver.secrets.json密鑰文件,又dccker-compose.yml掛載進入容器
.env文件存儲相對固定、與本次docker-compose命令相關的環境變量,dockee-compose命令默認可尋找同級目錄下的.env文件
TAG=master # 該TAG變量會在Pipeline:deploy_staging任務中被覆蓋,形成基本git:tag的imageName:tag
docker_host=172.16.1.1
COMPOSE_PROJECT_NAME=EqidManager
DOCKER_REGISTRY=***
依據.gitlab-ci.yml 文件定義的 deploy_staging腳本:
跳轉到部署目錄---->應用本次Gitlab-CD要用的git : tag----> 執行docker-compose 命令拉取指定tag鏡像并啟動容器。
原文鏈接:https://www.cnblogs.com/JulianHuang/p/11346615.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?
總結
以上是生活随笔為你收集整理的基于.NetCore结合docker-compose实践Gitlab-CI/CD 排坑指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件设计的第一性原理:结构化抽象
- 下一篇: .NET Core很酷,你不得不知