Jenkins部分
首先,我們要有個Jenkins咯,下載鏈接:https://jenkins.io/download/
我們安裝官網教程安裝好jenkins,安裝教程略....
嗯?不是說好手把手么?你妹的.
好好好,我們還是來手把手教程好了.
首先安裝JDK8
添加安裝源之后直接apt-get install就好,下面是ubuntu的安裝命令,其他系統自己玩一下就好.
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
下載jenkins.war + 啟動Jenkins
下載鏈接:http://mirrors.jenkins.io/war-stable/
在這里面找最新的下載,我當前最新的應該是2.107.2
下載好了jenkins.war之后,在當前目錄創建一個jenkins-home文件夾,設置JENKINS_HOME環境變量為jenkins-home(不設置也可以,默認在~/.jenkins)
wget http://mirrors.jenkins.io/war-stable/2.107.2/jenkins.war;
mkdir ~/jenkins-home;
export JENKINS_HOME=~/jenkins-home;
tmux;
java -jar jenkins.war
一般建議開個后台進程來跑jenkins,免得終端退出之后jenkins就死掉了.
所以上面我先打開了tmux之后再跑java -jar jenkins.war.
如下圖:
接着留意一下initialAdminPassword的輸出
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
XXXXXXXXXXXXXX
This may also be found at: /root/jenkins-home/secrets/initialAdminPassword
這個時候訪問當前主機的8080端口已經可以看到jenkins正在啟動了,稍等片刻就可以看到jenkins登錄頁.
這個時候把上面的XXXXXXXXXXXXXX復制出來,輸進去點擊繼續配置jenkins賬號密碼信息之類的.
接着安裝默認插件.
這里估計也要等幾分鍾不等,看你的機器性能和網絡速度.
安裝好了之后會進入配置登錄賬號密碼,安裝提示配置就完事.
最后進入jenkins頁面是這樣的.
到現在我們已經把jenkins跑起來了,也有了一些常用的插件.
我們先去把dotnet core docker 編譯發布相關的東西弄好之后再回來繼續做jenkins任務.
dotnet core docker 打包
在項目目錄下新建Dockerfile文件,內容如下:
FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "你的dotnet core程序.dll"]
這個Dockerfile基本就是把當前目錄的文件拷貝到aspnetcore-build鏡像中,再里面編譯好之后再發布到aspnetcore:2.0鏡像中,
最后指定運行你的dotnet core程序
來源:https://github.com/DaoCloud/dotnet-docker-samples
docker build + run 腳本(非必須,可以使用jenkins中腳本編譯替代)
以HouseCrawler.Web為例,
#!/bin/sh
image_version=`date +%Y%m%d%H%M`;
echo $image_version;
cd ~/code/58HouseSearch/HouseCrawler.Core/HouseCrawler.Web;
git pull --rebase origin master;
docker stop house-web;
docker rm house-web;
docker build -t house-web:$image_version .;
docker images;
docker run -p 8080:80 -v ~/docker-data/house-web/appsettings.json:/app/appsettings.json -v ~/docker-data/house-web/NLogFile/:/app/NLogFile --restart=always --name house-web -d house-web:$image_version;
docker logs house-web;
通過上面這個build+run腳本,我們已經把dotnet core程序編譯好了,並且打包成了docker images,還直接跑起來了.
但是我們想要的應該是自動化編譯部署,而且上面我們都把jenkins跑起來了,所以....
jenkins job配置
新建Job
打開jenkins首頁,左側選擇"新建任務"(newJob),如下圖:
給新的job取個名字,然后選擇"構建自由風格的軟件項目",如圖:
添加源碼倉庫
確認之后進入Job配置頁面,源碼管理里面選擇git,如圖:
如果git倉庫是需要權限的話需要配置一下權限,我一般簡單粗暴直接把jenkins主機的公鑰添加到git倉庫里面,所以這里直接配置成'From the Jenkins master ~/.ssh',也可以用賬號密碼訪問等等的.
"Branch Specifier (blank for 'any') "默認master分支,根據自己的需求填入不同的分支.
構建觸發器和構建環境先跳過,我們不管,待會弄.
構建
點擊"添加構建步驟",選擇"Execute shell",然后能看到如下圖:
還記得我們上一步的腳本么?修改一下源碼路徑再放進去.
# 切換到源碼目錄,對應在jenkins-home的workspace下面
cd ~jenkins-home/workspace/項目名稱/Dockerfile所在目錄;
image_version=`date +%Y%m%d%H%M`;
echo $image_version;
# 停止之前的docker container
docker stop house-web;
# 刪除這個container
docker rm house-web;
# build鏡像並且打上tag
docker build -t house-web:$image_version .;
docker images;
# 把剛剛build出來的鏡像跑起來
docker run -p 8080:80 -v ~/docker-data/house-web/appsettings.json:/app/appsettings.json -v ~/docker-data/house-web/NLogFile/:/app/NLogFile --restart=always --name house-web -d house-web:$image_version;
docker logs house-web;
如果jenkins主機和程序運行主機不在一台機器上,建議直接在把上面的腳本放在運行主機上,命名成 start_XXX.sh.
上面的命令直接就是成了
ssh username@發布主機的IP '~/start_XXX.sh'
ps:記得在jenkins主機配置ssh免登陸
構建觸發器
構建觸發器就是我們選擇什么時候來觸發構建任務,有幾種方案可以做.
- 使用 Build periodically,定時 or 隔N久去拉一次代碼構建
- Poll SCM:定時檢查源碼變更(根據SCM軟件的版本號),如果有變化就去執行構建
- GitHub hook trigger for GITScm polling 或者其他Git平台提供的webhook
- 安裝Generic Webhook Trigger插件之后,使用其他平台的webhook來觸發構建任務.
我這里選擇第4種方案,安裝Generic Webhook Trigger插件,下面馬上回告訴你為什么這樣做的.
Generic Webhook Trigger插件在"系統管理-管理插件-可選插件"里面直接搜"Generic Webhook Trigger"安裝就可以.
從上一步的構建步驟里面的腳本中我們就知道,其實我們現在要不就在jenkins主機上docker build,要不就在發布目標主機上build,
build過程比較慢而且還會產生鏡像在本機or目標主機上,docker images也沒有被管理起來.
有什么好的辦法么?嗯,還真有.直接用阿里雲"容器鏡像服務"來構建鏡像
使用阿里雲-容器鏡像服務
首先登錄阿里雲,然后進入容器鏡像服務,地址是https://cr.console.aliyun.com/
首次進入估計需要創建一個命名空間,一般用公司名或者你的名字就完事.
接着選擇"創建鏡像倉庫".
選地區-選命名空間-填倉庫名稱(就是鏡像名稱)-填摘要-設置代碼源(支持GitHub/阿里雲code/Bitbucket/私有Gitlab/本地Git等等,給個授權就完事)
構建設置選擇"代碼變更時自動構建鏡像",然后選一下構建分支為你想要的分支,填入Dockerfile在源碼中的路徑,然后保存
接着我們進入管理平台看一下.
點擊一下"立即構建",然后查看一下日志.
這個時候,我們用docker pull registry-internal.cn-hangzhou.aliyuncs.com/你的命名空間/你的鏡像名稱 就可以拉到這個阿里雲build成功的鏡像了.
鏡像build的問題解決了,那么我們怎么自動把鏡像發布到我們的運行主機呢?
這時候webhook又出來了.
jenkins webhook觸發配置
我們看阿里雲鏡像構建服務里面,有一項是webhook的,官方介紹在這里:阿里雲-webhook管理
這里就需要填入我們的webhook地址,還記得前面我無端端選擇的第四種方案,然后讓大家跟着安裝的Generic Webhook Trigger插件么?
我們就是用這貨來為我們提供webhook API.
理一下流程:
git倉庫代碼變化 ->阿里雲容器構建服務啟動 -> 構建好鏡像之后觸發webhook -> jenkins收到阿里雲的webhook之后觸發job執行部署腳本 ->部署腳本使用阿里雲鏡像run起來 ->完事.
我們繼續配置Generic Webhook Trigger.
Generic Webhook Trigger支持的命名觸發URL格式是這樣的:
http://jenkins登錄用戶名:token授權碼@jenkins IP:8080/generic-webhook-trigger/invoke?token=觸發器名稱
jenkins登錄名和token在"賬號-設置-API Token-Show API Token..."里面能看到,找出來之后填到上面去就可以.
最后一個token參數其實就是"構建觸發器"中"觸發遠程構建"的參數,建議使用job名字.這里的配置大概是這樣的:
最后我們還需要在jenkins全局安全設置中取消勾選“防止跨站點請求偽造(Prevent Cross Site Request Forgery exploits)"選項,這樣阿里雲webhook才能過得來.
手動在瀏覽器中訪問一下http://jenkins登錄用戶名:token授權碼@jenkins IP:8080/generic-webhook-trigger/invoke?token=觸發器名稱
如果對應的jenkins Job能正常開始執行,說明整個流程已經ok了.
最后我們回到上面"阿里雲-容器鏡像服務-對應鏡像倉庫-webhook-添加記錄"
PS:webhook名稱不要帶特殊字符or "-"之類的,不然一直保存失敗而且還不會提示你是因為名字不合法,下午被這個坑了半個小時.
到這里,我們基本大功告成了.
最后我們再改一下jenkins的腳本,不在本地build docker了,直接拿阿里雲鏡像服務構建出來的鏡像跑就可以.
# 停止之前的docker container
docker stop house-web;
# 刪除這個container
docker rm house-web;
docker pull 你的阿里雲鏡像地址;
# 把剛剛build出來的鏡像跑起來
docker run --restart=always --name 你的contianer名稱 你的阿里雲鏡像地址;
總結一下我們做了什么
- 搭建jenkins
- 編寫Dockerfile文件,直接編譯發布+打包成docker鏡像+部署腳本
- 使用阿里雲-容器構建服務構建docker鏡像,構建成功后使用webhook通知jenkins
- 配置jenkins webhook觸發器,觸發部署腳本
- 完事...