持续集成之应用容器化及自动化部署
通過(guò) Azure Pipelines 實(shí)現(xiàn)持續(xù)集成之docker容器化及自動(dòng)化部署
Intro
Azure DevOps Pipeline 現(xiàn)在對(duì)于公開(kāi)的項(xiàng)目完全免費(fèi),這對(duì)于開(kāi)源項(xiàng)目來(lái)講無(wú)疑是個(gè)巨大的好消息,在 Github 的 Marketplace 里有個(gè) Azure Pipeline,就是微軟的 Azure DevOps Pipeline。
實(shí)現(xiàn) Docker 容器化的持續(xù)集成
實(shí)現(xiàn)的目標(biāo):
push 代碼自動(dòng)打包 docker 鏡像并上傳至docker hub
ssh 自動(dòng)部署到虛擬機(jī)上
有了docker image 之后后面就可以按照自己的需求加以定制了,比如通過(guò)ssh部署到服務(wù)器或者進(jìn)行服務(wù)通知等。
新建 Pipeline
可以在 Azure 的 devops 新建一個(gè) pipelines 的項(xiàng)目來(lái)專(zhuān)門(mén)管理 Github 上的pipeline
新建一個(gè)pipeline
第一次使用的話,會(huì)需要進(jìn)行授權(quán)
授權(quán)之后就可以選擇 Github 上的項(xiàng)目了,選擇要配置的項(xiàng)目
可以基于模板創(chuàng)建也可以選擇下面基于已有的 yaml 文件創(chuàng)建
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 配置
通過(guò) vmImage 來(lái)指定要用來(lái)執(zhí)行 build 任務(wù)的 agent
pool: vmImage: 'Ubuntu 16.04'variables
可以通過(guò) variables 來(lái)指定一些全局變量,這里我用了一個(gè) imageName 的變量來(lái)設(shè)置 docker 鏡像的名稱(chēng)
variables: imageName: 'activityreservation'敏感信息的存儲(chǔ)
要上傳 docker 鏡像,我這里是直接上傳到 docker hub 上,需要 docker 的用戶名以及密碼,pipeline 可以設(shè)置一些不配置在 pipeline 配置文件里的其它配置,一些敏感信息就可以這樣配置來(lái)保證安全訪問(wèn)
可以將 pipeline 獨(dú)有的一些配置放在 PipelineVariables 里,一些比較通用的,別的 pipeline 也會(huì)使用的變量可以放到一個(gè) Variablegroups,然后在 pipeline 的 variables 里 link 一下對(duì)應(yīng)的 Variable Group 就可以使用 group 里配置的變量了,我把 docker 的 username 和 password 配置在了一個(gè) docker 的 Variable Group 里。
docker 鏡像的打包以及上傳
配置 pipeline 的 step,step 對(duì)應(yīng)的就是需要 build agent 去執(zhí)行的task
steps: - script: | docker build -f Dockerfile -t $(imageName) . docker login -u $(dockerId) -p $(pswd) docker push $(imageName)配置上面的腳本我們就可以自動(dòng) build 并 push docker 鏡像了。
build 完成之后再去 docker hub 上查看對(duì)應(yīng)的 docker 鏡像就會(huì)發(fā)現(xiàn) docker 鏡像已經(jīng)更新了。
在 vm 上自動(dòng)部署 docker 鏡像
首先要在 pipeline 上新建一個(gè) 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 fisshEndpoint 設(shè)置為連接的名稱(chēng),inline 后面是在遠(yuǎn)程執(zhí)行的腳本,大概流程如下:
檢查是否有指定名稱(chēng)的 container 在運(yùn)行,如果有 stop 并 remove
拉取最新的 docker 鏡像
運(yùn)行 docker 容器
移除可能的懸掛鏡像(名稱(chēng)為 none 的中間鏡像)
驗(yàn)證
配置完成之后我們就可以提交代碼,就會(huì)自動(dòng)出發(fā) build,自動(dòng)執(zhí)行我們定義的 pipeline 任務(wù),按照上面的配置的話,就會(huì)先 build 并 push Docker 鏡像到 docker hub,然后 SSH 到遠(yuǎn)程服務(wù)器,遠(yuǎn)程過(guò)去之后執(zhí)行腳本,停掉并移除指定的 docker 容器(如果有)然后拉取并部署最新的docker鏡像,最后清理資源,刪除 docker 懸掛鏡像。
示例項(xiàng)目
現(xiàn)在有兩個(gè)項(xiàng)目是這種模式去自動(dòng)化部署的,源代碼以及 pipeline 的配置都在 Github 上
活動(dòng)室預(yù)約系統(tǒng)?https://reservation.weihanli.xyz/
簡(jiǎn)單賬單系統(tǒng)
現(xiàn)在這兩個(gè)項(xiàng)目的部署模式是這樣的,以活動(dòng)室預(yù)約系統(tǒng)為例:
前面一個(gè) 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_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }這里會(huì)把 reservation.weihanli.xyz 的請(qǐng)求轉(zhuǎn)發(fā)到 localhost:7010 ,也就是這個(gè) docker 鏡像映射的本地端口
Memo
如果有什么問(wèn)題或建議,歡迎與我聯(lián)系
總結(jié)
以上是生活随笔為你收集整理的持续集成之应用容器化及自动化部署的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 持续集成之应用k8s自动部署
- 下一篇: 持续集成之 Nuget 进阶