前面已經介紹過了 ".Net Core 程式發佈到 Docker 容器" 的內容。但是每次通過 SSH 鏈接到伺服器敲命令,運行腳本也是挺麻煩的一件事。程式員是最懶的,能讓電腦解決的問題絕不手動解決,如果當我們push一次代碼後自動build代碼,自動跑單元測試,如果測試通過,自動發佈程式,如果失敗 ...
前面已經介紹過了 .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一下代碼就自動構建自動發佈程式就差一點點了,太晚了下次再說吧。