1. 程式人生 > >.Net Core in Docker - 使用阿里雲Codepipeline及阿里雲容器映象服務實現持續整合(CI)

.Net Core in Docker - 使用阿里雲Codepipeline及阿里雲容器映象服務實現持續整合(CI)

前面已經介紹過了 .Net Core 程式釋出到 Docker 容器的內容。但是每次通過 SSH 連結到伺服器敲命令,執行指令碼也是挺麻煩的一件事。程式設計師是最懶的,能讓電腦解決的問題絕不手動解決,如果當我們push一次程式碼後自動build程式碼,自動跑單元測試,如果測試通過,自動釋出程式,如果失敗就發郵件通知管理員,這樣的話該多美好。為了達成這個目標於是持續整合(CI)持續交付/部署(CD)就被髮明出來了。CICD領域有個大名鼎鼎的工具:Jenkins,但是這次不使用它。如果你使用阿里雲的話,阿里雲已經提供了類似的功能,可以免去自己搭建Jenkins服務,以及Docker映象私倉的過程,而且目前它們是免費的。

阿里雲Codepipeline服務,是一套類似Jenkins的服務(其實我覺得它的核心引擎就是來自Jenkins)。

阿里雲容器映象服務,是一個映象倉庫,可以是公開的,也可以是私有的。

持續整合CI

持續整合指的是,頻繁地(一天多次)將程式碼整合到主幹。
它的好處主要有兩個。

(1)快速發現錯誤。每完成一點更新,就整合到主幹,可以快速發現錯誤,定位錯誤也比較容易。

(2)防止分支大幅偏離主幹。如果不是經常整合,主幹又在不斷更新,會導致以後整合的難度變大,甚至難以整合。

持續整合的目的,就是讓產品可以快速迭代,同時還能保持高質量。它的核心措施是,程式碼整合到主幹之前,必須通過自動化測試。只要有一個測試用例失敗,就不能整合。
Martin Fowler說過,"持續整合並不能消除Bug,而是讓它們非常容易發現和改正。"
摘自阮一峰大神的blog

下面就演示一下如何通過阿里雲Codepipeline跟容器映象服務來實現 .Net Core 程式的CICD。

持續整合

流程


程式碼push後Gitee通過webhook功能觸發Codepipeline構建,構建成功後自動推送映象到容器映象服務

新建一個 .Net Core MVC 的程式


新建一個 .net core mvc 程式名叫CoreCICDTest

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                 .UseKestrel(options =>
                 {
                     options.Listen(IPAddress.Any, 5000);
                 });
    }

修改Program的main方法,使Kestrel監聽5000埠

@{
    ViewData["Title"] = "Home Page";
}


<h3>
    .NET CORE CICD TEST -- V 1.0
</h3>

修改Home/index檢視

執行一下看看效果,網站正常顯示 .NET CORE CICD TEST -- V 1.0

新建一個 MSTest 專案


在CoreCICDTest的解決方案下新建一個 MSTest 專案用來寫單元測試,名叫CoreCICDTest.Tests

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            string str = "00";

            Assert.AreEqual(str, "00");
        }
    }

修改UnitTest1檔案中的TestMethod1方法,使其成為一個合法的TestMethod

執行一下單元測試,全部通過

新增Dockerfile檔案

FROM microsoft/dotnet:latest AS build
WORKDIR /app
COPY /. /app
RUN dotnet restore
WORKDIR /app/CoreCICDTest.Tests
RUN dotnet test CoreCICDTest.Tests.csproj
WORKDIR /app/CoreCICDTest
RUN dotnet publish -o ./out -c Release
EXPOSE 5000
ENTRYPOINT ["dotnet", "out/CoreCICDTest.dll"]

Dockerfile注意檔名沒有任何字尾,Dockerfile用來在Docker容器內自動test、build我們的程式碼

在Gitee上新建一個專案,並把CoreCICDTest解決方案推送上去

使用Gitee的免費Git服務,新建一個專案名叫CoreCICDTest,使用Git Push命令把原生代碼推送上去。

在阿里雲容器映象服務上新建專案並進行配置



點選“建立映象倉庫”按鈕,彈出建立介面。填寫名稱空間kklldog,倉庫名稱cicd_test


點選下一步,程式碼源選擇“本地倉庫”,點選“建立映象倉庫”完成倉庫的建立

在阿里雲Codepipeline上新建專案並進行配置


點選“新建”按鈕跳轉至新建專案頁面。這個介面跟Jenkins簡直就是一模一樣


專案名稱填寫cicd_test,這裡沒有.net相關的模板,囧!專案型別選擇"構建一個自由風格的軟體"就可以

點選下一步,填寫專案基本資訊,原始碼選擇Gitee。構建型別預設是java,無所謂不用過它

點選“繫結雲碼賬號”跳轉至雲碼授權頁面進行授權,以便阿里雲可以拉取雲碼上的程式碼

進行授權後,原始碼管理介面就可以選擇到Gitee上的專案,填寫相應的分支

點選“增加構建步驟”,選擇“映象構建與釋出”

在“映象構建與釋出”介面填寫剛才建立的倉庫資訊

映象倉庫名格式為namespace/映象倉庫名。如果registry為Docker hub,拉取映象命令為docker pull docker,則本配置項填寫docker;如果 registry為阿里雲Docker映象倉庫,拉取映象命令為docker pull registry.cn-hangzhou.aliyuncs.com/acs-sample/wordpress, 則本配置項填寫acs-sample/wordpress。
  Registry地址 用來配置docker registry地址,如果為空,預設使用Docker hub registry (https://index.docker.io/v1/);如果使用阿里雲registry, 請填寫https://registry.cn-beijing.aliyuncs.com/v2/,其中地域(cn-beijing)根據使用者實際的映象倉庫地域來修改。
  Registry證書 用來新增授權資訊,請新增Registry授權型別的證書。


勾選“遠端觸發器”,先填寫分支master,然後點選“生成”會生成觸發器地址,這裡好像有點小bug,有的時候這個地址不起效,如果不起效,多生成幾次試試

在“構建後操作”介面填寫郵件地址,用來接收郵件通知。勾選“每次不穩定的構建都發送郵件通知”

在Gitee的CoreCICDTest專案上配置WebHook


點選“管理>WebHook”選單,進行WebHook的配置

WebHook的Url填寫剛才Codepipeline裡的“遠端觸發器”裡生成的url地址;密碼不填;勾選Push事件,勾選“啟用”;點選“新增”按鈕完成Webhook的配置。這樣當我們push程式碼的時候,Gitee會自動給配置的url傳送一次post請求,裡面攜帶了詳細的專案資訊,提交資訊等資料

當點選“新增”按鈕後Gitee會立馬往webHook配置的url地址Post一次請求,如果Codepipeline做出“Task has been scheduled to queue”的響應則說明Codepipeline開始進行自動構建了


返回Codepipeline專案列表,可以看到cicd_test專案已經構建成功了

這個時候構建的映象也應該被推送到了容器映象服務的cicd_test倉庫裡。

編寫shell指令碼執行容器

sudo vim publish_cicd_test.sh
輸入以下內容
#!/bin/bash
sudo docker stop cicd_test
sudo docker rm cicd_test
sudo docker rmi registry-vpc.cn-shanghai.aliyuncs.com/kklldog/cicd_test
sudo docker login --username=xxx --password=xxx registry-vpc.cn-shanghai.aliyuncs.com
sudo docker pull registry-vpc.cn-shanghai.aliyuncs.com/kklldog/cicd_test:latest
sudo docker run --name cicd_test -d -p 7000:5000 -v /etc/localtime:/etc/localtime registry-vpc.cn-shanghai.aliyuncs.com/kklldog/cicd_test:latest

新建一個shell指令碼命名為publish_cicd_test.sh;使用docker pull從倉庫中拉取最近的映象;使用docker run執行容器

sudo /bin/bash publish_cicd_test.sh


執行一下shell指令碼

sudo docker ps -a

使用docker ps命令檢視一下容器的執行狀態,可以看到cicd_test容器已經執行成功了

使用瀏覽器訪問一下對應的埠,網站已經正常運行了

Push程式碼觸發構建

剛才的構建是我們配置Webhook的時候Gitee預設傳送的一次請求,正常應該是使用者使用git push命令後Gitee會發送一次請求,讓我們模擬一下。

修改home/index頁面,把V1.0改成V2.0
提交成功之後檢視Codepipeline專案列表,等待專案構建成功之後,我們再次執行一下publis_cicd_test.sh指令碼,成功之後再次使用瀏覽器訪問一下對應的埠看看home/index是否已經變為了V2.0

可以看到home/index已經變成V2.0了,說明我們的持續整合流程跑通了

持續交付/部署

我們上面演示的過程離一開始說的push一下程式碼就自動構建自動釋出程式就差一點點了,太晚了下次再說吧