.NET Core 2.0 持續(xù)集成,持續(xù)發(fā)布環(huán)境

隨著敏捷軟件開發(fā)方法論的普及,越來越多的原來由開發(fā)者完成的重復(fù)性工作都自動化讓機器來執(zhí)行了,對于一個開發(fā)團隊來說,如果沒有自動化的pipeline,開發(fā)人員的痛苦相信大家都深有體會,隨著.NET Core 2.0 的發(fā)布,在.NET Core平臺上的所有開發(fā)工具都跨平臺化了,這也給團隊在Linux環(huán)境上部署持續(xù)集成(CI),持續(xù)發(fā)布(CD)工作帶來方便,整套環(huán)境對團隊的開發(fā)效率的提升可以說是指數(shù)級別的,以下以 Ubuntu 16.0.4 服務(wù)器為例,演示CI CD搭建獸如何搭建整個環(huán)境,當(dāng)你征服了手動搭建過程后,就可以借助 ansible docker 等工具將這一過程自動化,后續(xù)文章將演示這一自動化搭建的過程。

一,服務(wù)器環(huán)境的準(zhǔn)備

  • 因為家里的文件服務(wù)器是 Ubuntu 16.0.4 Server 版,為了方便,就選這個作為服務(wù)器了。
  • 按照 .NET Core 2.0 SDK安裝指南 安裝.NET Core SDK,.NET Core 項目需要 dotnet 工具來編譯,發(fā)布,測試項目。
  • 按照 Docker官方安裝指南安裝 docker 服務(wù)。
  • 通過 sudo apt install nginx 安裝 Nginx 服務(wù)器,后面會用到該服務(wù)來反向代理內(nèi)部所有的服務(wù),這樣 HTTPS 的問題都交給 Nginx 來解決。

二,安裝并配置Jenkins CD 服務(wù)

目前比較流行的CD工具有 JenkinsGoCD,此處我們選擇Jinkins,當(dāng)然 Jenkins 服務(wù)可以使用docker來運行,但考慮到簡單性,我們此處直接安裝為本地服務(wù)運行。

參照官方安裝指南安裝 Jenkins 服務(wù), 默認服務(wù)端口為:8080,為了服務(wù)的安全性,我們在服務(wù)器上安裝了nginx 服務(wù)通過 https
反向代理 Jenkins 服務(wù),最后的服務(wù)地址為:https://home.freemanke.com:28080,當(dāng)然如果你的服務(wù)器主機是云主機有固定IP可以直接使用443端口,我的服務(wù)器在家里,通過DDNS暴露到外網(wǎng),而家里的路由器又把443和80端口占用了,所以服務(wù)需要用其他端口(28080等)來服務(wù),SSL證書可以通過騰訊云SSL證書服務(wù)申請個人免費證書(當(dāng)然前提是你要有一個你自己的域名),有效期一年。

Nginx 反向代理配置如下:

####################################################################
## jenkins service - https://home.freemanke.com:28080
server {
        listen 28080;
        server_name home.freemanke.com;

        ssl on;
        ssl_certificate     /home/freeman/ssl/home.freemanke.com.crt;
        ssl_certificate_key /home/freeman/ssl/home.freemanke.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;

        location / {
                proxy_pass http://127.0.0.1:8080/;
                proxy_redirect default;
        }
}

搭建完成后訪問服務(wù)地址https://home.freemanke.com:28080

Jenkins服務(wù)界面

默認安裝完成是樸素的默認theme,我們可以參照 jenkins-material-theme 來自定義界面,此處我選擇了綠色的 Material
主題。

安裝完成后的配置步驟比較多,不一一列舉,根據(jù)每個人團隊的需要不同而不同,一下列舉本次用到插件和配置

  • Bitbucket Plugin 因為我使用的git庫是 https://bitbucket.org/,所以需要安裝 Bitbucket Plugin 來支持 Webhook,當(dāng)git又提交時,bitbucket通過 Webhook 功能發(fā)送請求到 Jenkins 服務(wù)器,服務(wù)器將實時觸發(fā)指定 pipeline 的構(gòu)建,這樣才能具有持續(xù)構(gòu)建的能力。
  • Email,Slack 擴展,將pipeline通過 Email 或 Slack 通知到開發(fā)者,實時反饋構(gòu)建的過程和結(jié)果。

三,安裝 docker registry 本地服務(wù)

Pipeline的每次成功構(gòu)建,都將產(chǎn)生一個軟件的新的可發(fā)性版本,如果我們使用文件存儲,我們后續(xù)的部署起來非常繁瑣,此處我們使用 docker 來部署服務(wù),所以需要一個 docker registry 服務(wù)來保存托管這些新的鏡像,官方的速度太慢,所以需要本地服務(wù),此處直接使用 docker 來啟動服務(wù),腳本如下。


docker stop registry
docker rm -f registry
docker run \
--detach \
--name registry \
--publish 5000:5000 \
--volume /home/freeman/docker-registry:/var/lib/registry \
registry:2.6.2

同樣我們需要通過 Nginx 反向代理服務(wù),最后的服務(wù)地址為https://home.freemanke.com:25000/v2/_catalog,反向代理配置如下,注意此處的配置client_max_body_size 1000M; 因為 image 包都很大,而默認的 body size 為 2M,無法提交大的 Image 文件。

####################################################################
## docker-registry service - https://home.freemanke.com:25000
server {
        listen 25000;
        server_name home.freemanke.com;

        ssl on;
        ssl_certificate     /home/freeman/ssl/home.freemanke.com.crt;
        ssl_certificate_key /home/freeman/ssl/home.freemanke.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;

        client_max_body_size 1000M;

        location / {
                proxy_pass http://127.0.0.1:5000/;
                proxy_redirect default;
        }

}

四,準(zhǔn)備項目和 Pipeline

此處以我最近正在做的項目為例,項目的產(chǎn)出物是一個web站點和一個windows平臺的winform客戶端,此處先為 web 站點的開發(fā)構(gòu)建準(zhǔn)備一個自動化的CI CD Pipeline。

telemetry 項目

配置過程如下

  • 在 Jenkins 服務(wù)上新建一個 pipeline 名為 telemetry
  • 將項目的git地址添加到git源,并配置好授權(quán)信息
  • 在項目的根目錄下創(chuàng)建 Jenkinsfile,此處是 Pipeline as Code 的關(guān)鍵,如果你直接在 Jenkins 上配置構(gòu)建腳本的話,你將無法跟蹤到腳本的任何改動,如果我們使用文件作為配置,并放入到git管理中,我們每一個開發(fā)者都能實時修改并跟蹤 pipeline 配置變化。此處的腳本內(nèi)容如下,具體的內(nèi)容定義請參見官方文檔,此處的主要流程是:
    • 恢復(fù)nuget包應(yīng)用
    • 構(gòu)建解決方案
    • 運行測試
    • 發(fā)布 web 項目到指定環(huán)境,此處為 ubuntu.16.10-x64 環(huán)境
    • 構(gòu)建 docker 鏡像
    • 推送 docker 鏡像到 docker registry
    • 在 dev 環(huán)境上部署最新的代碼版本
#!/usr/bin/env groovy

pipeline {
    agent any
    stages {
        stage('build-test') {
            steps {
                sh 'dotnet restore ./src/Telemetry.sln'
                sh 'dotnet build ./src/Telemetry.sln'
                sh 'dotnet test --no-build --no-restore ./src/Telemetry.Data.Tests/'
            }
        }

        stage('build-push-image') {
            steps {
                sh 'dotnet publish ./src/Telemetry.Web/Telemetry.Web.csproj -c Release -r ubuntu.16.10-x64 -o ./bin/publish'
                sh 'dotnet publish ./src/Telemetry.Web/Telemetry.Web.csproj -c Release -r win7-x86 -o ./bin/win7/publish'
                sh 'docker build -t home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER} ./src/Telemetry.Web/'
                sh 'docker push home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER}'
            }
        }

        stage('deploy-dev') {
            steps {
                sh 'docker stop telemetry || true && docker rm -f telemetry || true'
                sh 'docker run -d --name telemetry -p 45000:45000 home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER}'
            }
        }
    }
}

五,驗證 Pipeline

git上的每次提交都自動觸發(fā) pipeline 的一次構(gòu)建,構(gòu)建結(jié)果如下

構(gòu)建結(jié)果

對于每次的構(gòu)建,我們可以跟蹤 Console 的輸出來定位是否有問題發(fā)生,一個典型的 Console 輸出結(jié)果如下圖,我們可以很清晰的跟蹤到每一個步驟的執(zhí)行情況。

Console output

自動構(gòu)建發(fā)布如果成功完成,將直接將最新的代碼部署到dev環(huán)境中,下圖是本站點的dev環(huán)境訪問截圖。

telemetry website

后續(xù)文章將把此次的手動搭建工作通過 ansible 和 docker 等輔助工具自動化,敬請期待!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容