Intro
Azure DevOps Pipeline 現在對於公開的專案完全免費,這對於開源專案來講無疑是個巨大的好訊息,在 Github 的 Marketplace 裡有個 Azure Pipeline,就是微軟的 Azure DevOps Pipeline。
實現 Docker 容器化的持續整合
實現的標的:
-
push 程式碼自動打包 docker 映象並上傳至docker hub
-
ssh 自動部署到虛擬機器上
有了docker image 之後後面就可以按照自己的需求加以定製了,比如透過ssh部署到伺服器或者進行服務通知等。
新建 Pipeline
可以在 Azure 的 devops 新建一個 pipelines 的專案來專門管理 Github 上的pipeline
新建一個pipeline
第一次使用的話,會需要進行授權
授權之後就可以選擇 Github 上的專案了,選擇要配置的專案
可以基於模板建立也可以選擇下麵基於已有的 yaml 檔案建立
Azure pipeline config
這裡提供一份示例,原始碼在這裡:
# Docker image
# Build a Docker image to deploy, run, or push to a container registry.
# Add steps that use Docker Compose, tag images, push to a registry, run an image, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker
pool:
vmImage: 'Ubuntu 16.04'
variables:
imageName: '$(dockerId)/activityreservation'
steps:
- script: |
docker build -f Dockerfile -t $(imageName) .
docker login -u $(dockerId) -p $(pswd)
docker push $(imageName)
pipeline 配置解析
-
agent pool 配置
透過 vmImage 來指定要用來執行 build 任務的 agent
pool:
vmImage: 'Ubuntu 16.04'
-
variables
可以透過 variables 來指定一些全域性變數,這裡我用了一個 imageName 的變數來設定 docker 映象的名稱
variables:
imageName: 'activityreservation'
-
敏感資訊的儲存
要上傳 docker 映象,我這裡是直接上傳到 docker hub 上,需要 docker 的使用者名稱以及密碼,pipeline 可以設定一些不配置在 pipeline 配置檔案裡的其它配置,一些敏感資訊就可以這樣配置來保證安全訪問
可以將 pipeline 獨有的一些配置放在 Pipeline Variables
裡,一些比較通用的,別的 pipeline 也會使用的變數可以放到一個 Variable groups
,然後在 pipeline 的 variables 裡 link 一下對應的 Variable Group 就可以使用 group 裡配置的變數了,我把 docker 的 username 和 password 配置在了一個 docker 的 Variable Group 裡。
-
docker 映象的打包以及上傳
配置 pipeline 的 step,step 對應的就是需要 build agent 去執行的task
steps:
- script: |
docker build -f Dockerfile -t $(imageName) .
docker login -u $(dockerId) -p $(pswd)
docker push $(imageName)
配置上面的指令碼我們就可以自動 build 並 push docker 映象了。
build 完成之後再去 docker hub 上檢視對應的 docker 映象就會發現 docker 映象已經更新了。
在 vm 上自動部署 docker 映象
首先要在 pipeline 上新建一個 SSH 的 Service Connection
steps:
- script: |
docker build -f Dockerfile -t $(imageName) .
docker login -u $(dockerId) -p $(pswd)
docker push $(imageName)
- task: SSH
displayName: 'Run shell inline on remote machine'
inputs:
sshEndpoint: 'weihanli-vm'
runOptions: inline
inline: |
containers=$(docker ps -q --filter name=activityreservation)
if test -n "$containers"; then
docker stop $(docker ps -q --filter name=activityreservation) >> /dev/null 2>&1
rc=$?
if [[ $rc != 0 ]];
then
echo 'failed to stop container...'
exit $rc;
fi
fi
containers1=$(docker ps -q -a --filter name=activityreservation)
if test -n "$containers1"; then
docker rm $(docker ps -q -a --filter name=activityreservation) >> /dev/null 2>&1
rc=$?
if [[ $rc != 0 ]];
then
echo 'failed to remove container...'
exit $rc;
fi
fi
docker pull $(imageName):latest >> /dev/null 2>&1
rc=$?
if [[ $rc != 0 ]];
then
echo 'failed to pull container...'
exit $rc;
fi
docker run -d -p 7010:80 --name activityreservation --link redis:redis-server $(imageName):latest >> /dev/null 2>&1
rc=$?
if [[ $rc != 0 ]];
then
echo 'failed to run container...'
exit $rc;
fi
danglings=$(docker images -f "dangling=true" -q)
if test -n "$danglings"; then
docker rmi $(docker images -f "dangling=true" -q) >> /dev/null 2>&1
rc=$?
if [[ $rc != 0 ]];
then
echo 'failed to remove danglings container...'
exit $rc;
fi
fi
sshEndpoint 設定為連線的名稱,inline 後面是在遠端執行的指令碼,大概流程如下:
-
檢查是否有指定名稱的 container 在執行,如果有 stop 並 remove
-
拉取最新的 docker 映象
-
執行 docker 容器
-
移除可能的懸掛映象(名稱為 none 的中間映象)
驗證
配置完成之後我們就可以提交程式碼,就會自動出發 build,自動執行我們定義的 pipeline 任務,按照上面的配置的話,就會先 build 並 push Docker 映象到 docker hub,然後 SSH 到遠端伺服器,遠端過去之後執行指令碼,停掉並移除指定的 docker 容器(如果有)然後拉取並部署最新的docker映象,最後清理資源,刪除 docker 懸掛映象。
示例專案
現在有兩個專案是這種樣式去自動化部署的,原始碼以及 pipeline 的配置都在 Github 上
-
活動室預約系統 https://reservation.weihanli.xyz/
-
簡單賬單系統
現在這兩個專案的部署樣式是這樣的,以活動室預約系統為例:
前面一個 nginx 作為反向代理,後面是直接跑在 docker 容器裡
nginx 示例配置:
server {
listen 80;
listen 443;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
server_name reservation.weihanli.xyz;
location / {
proxy_pass http://localhost:7010;
proxy_set_essay-header X-Real-IP $remote_addr;
proxy_set_essay-header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
這裡會把 reservation.weihanli.xyz
的請求轉發到 localhost:7010
,也就是這個 docker 映象對映的本地埠
Memo
如果有什麼問題或建議,歡迎與我聯絡
原文地址:https://www.cnblogs.com/weihanli/p/10464507.html
.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com