收益
- 不用再通過命令行發佈
- 發佈環境穩定,可以重複執行
- 多節點同步構建,提高效率
準備
- linux服務器已安裝jenkins、git、openjdk8和maven3.5+已就緒
- git服務
- 一個已經能夠構建支持多CPU架構docker鏡像的Dockerfile
- 一臺已經安裝docker環境的同jenkins宿主機不同架構的linux服務器
jenkins和git服務可參考樹莓派4B基於docker搭建devops平臺進行準備。
本實踐環境中使用的jenkins就是參考樹莓派4B基於docker搭建devops平臺進行搭建的,參考文檔中使用的jenkins鏡像使用root用戶啓動jenkins,方便掛載宿主機的docker運行環境,無權限問題執行docker命令,該鏡像同時支持樹莓派和普通x86服務器; apiworld-codeg是一個快嘉腳手架項目,本實踐我們選擇的Dockerfile就是該項目提供的,基於該Dockerfile我們可以同時構建支持arm64和x86架構CPU的docker鏡像。如您也準備好了一個已經能夠構建支持多CPU架構docker鏡像的Dockerfile,可以將它 push到搭建好的git服務器,如gogs;或者任何可選的代碼託管平臺,如github、gitee、codeup、coding等等。
本實踐環境中的jenkins部署在一臺樹莓派4B上,另外的一臺linux服務器是x86服務器,已經安裝docker環境。具體信息如下
服務器名稱 | 操作系統 | CPU架構 | IP | docker-version | docker-Experimental |
---|---|---|---|---|---|
jenkins宿主機 | centos7.9 | arm64 | 10.168.1.220 | 19.03.8 | true |
x86服務器 | centos7.7 | amd64 | 192.168.99.240 | 17.05.0-ce | false |
pipeline設計與實現
步驟
- 下載源碼
- jenkins宿主機和x86服務器分別構建鏡像、推送hub鏡像
- jenkins宿主機創建manifest
- jenkins宿主機圖送hub manifest
docker配置
開啓實驗屬性 本實踐中我們開啓宿主機的docker實驗屬性,以便支持manifest。 docker實驗屬性需要同時開啓server端和client端 我們先開啓server端,宿主機新建文件/etc/docker/daemon.json,內容如下
{
"experimental": true,
"insecure-registries": ["10.168.1.220:8082","10.168.1.220:8083"],
"log-driver":"json-file",
"log-opts": { "max-size": "100m", "max-file": "5" },
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
重啓docker,jenkins也會自動重啓
systemctl restart docker
再開啓client端,這個本來需要在jenkins容器裏執行,不過我們已經通過mount將/root目錄直接掛載在宿主機的/opt/server/jenkins/data,所以我們可以直接在宿主機操作 宿主機新建文件/opt/server/jenkins/data/.docker/config.json,內容如下
{
"experimental": "enabled"
}
這時候再進入jenkins容器,發現docker的實驗屬性已經開啓
[root@pi155 ~]# docker exec -it jenkins bash
bash-4.2# docker version
Client: Docker Engine - Community
Version: 19.03.8
API version: 1.40
Go version: go1.12.17
Git commit: afacb8b
Built: Wed Mar 11 01:27:06 2020
OS/Arch: linux/arm64
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 19.03.8
API version: 1.40 (minimum version 1.12)
Go version: go1.12.17
Git commit: afacb8b
Built: Wed Mar 11 01:25:44 2020
OS/Arch: linux/arm64
Experimental: true
containerd:
Version: 1.4.12
GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
Version: 1.0.2
GitCommit: v1.0.2-0-g52b36a2
docker-init:
Version: 0.18.0
GitCommit: fec3683
容器中保存docker登錄憑證
[root@pi155 ~]# docker exec -it jenkins bash
bash-4.2# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: fastjrun
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
這樣登錄憑證就保存在容器中的/root/.docker/config.json,後續我們就可以直接使用jenkins推送docker鏡像至hub了。
jenkins設置
jenkins容器內生成ssh-key,並ssh登錄x86服務器
[root@pi155 .m2]# docker exec -it jenkins bash
bash-4.2# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:LMv7Hr/uqumnPDAOkgIeBlGekEPEyrMi7Ct+dG/F2NQ root@0cab68699043
The key's randomart image is:
+---[RSA 2048]----+
|**. |
|++ . |
|+.o . |
|o= . . E |
|=.+ . S |
|*+..oo + + |
|=..o.o+ o |
|.. ....=.o |
|ooo .OB++=. |
+----[SHA256]-----+
bash-4.2# ssh 192.168.99.240
The authenticity of host '192.168.99.240 (192.168.99.240)' can't be established.
ECDSA key fingerprint is SHA256:moZlvJwOjMx9Yybd1/0uebewfcHlA0b1zPYXp78H6rc.
ECDSA key fingerprint is MD5:3b:90:d4:c0:16:07:69:4f:e3:2b:95:6f:bc:c6:e6:d6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.99.240' (ECDSA) to the list of known hosts.
[email protected]'s password:
配置x86服務器爲jenkins的一個agent,標籤設置爲amd64
jenkins控制檯點"Manage Jenkins"
點“Manage nodes and clouds”
新建節點
輸入節點名稱,選中Permanent Agent後,點“Create”按鈕,繼續編輯該節點信息
這一頁需要調整的有節點名字、Number of executors、遠程工作目錄、標籤、用法和啓動方式,其他採用默認值即可。節點名字隨意;Number of executors默認值爲1,可調整爲2;遠程工作目錄要保證確實存在;標籤至少設置一個iamd64,如果有多個,可以用空格分隔;用法有2個選項,這裏我們選擇“Only build jobs with label expressions matching this node”
啓動方式有3個選項,這裏我們選擇"Launch agents via SSH"
啓動方式選擇"Launch agents via SSH"後,會顯示主機輸入框和用戶憑證下拉選擇框,我們輸入IP和登錄憑證後,點“保存”按鈕。 返回“Manage nodes and clouds”頁面,當jenkins檢測到從節點後,顯示如下
腳本
node {
stage('git chekout') {
git branch: "master", url: 'https://gitee.com/fastjrun/apiworld-codeg.git'
}
stage('package') {
sh 'sh build.sh package_mock_server'
}
stage('prepare docker') {
sh 'rm -rf output && mkdir output'
sh 'cp apiworld-mock-server/target/apiworld-mock-server.jar output'
dir( 'output' ) {
stash 'output'
}
}
stage('parallel docker build && push') {
parallel (
'docker build && push': {
sh 'cd output && docker build . -t pi4k8s/apiworld-mock-server-arm64:1.4'
sh 'docker push pi4k8s/apiworld-mock-server-arm64:1.4'
},
'docker build && push amd64': {
node('amd64') {
dir( 'output' ) {
unstash 'output'
}
sh 'cd output && docker build . -t pi4k8s/apiworld-mock-server-amd64:1.4'
sh 'docker push pi4k8s/apiworld-mock-server-amd64:1.4'
}
}
)
}
stage('manifest'){
try {
sh 'docker manifest rm pi4k8s/apiworld-mock-server:1.4'
}catch(exc){
echo "some thing wrong"
}
sh 'docker manifest create pi4k8s/apiworld-mock-server:1.4 pi4k8s/apiworld-mock-server-amd64:1.4 pi4k8s/apiworld-mock-server-arm64:1.4'
sh 'docker manifest annotate pi4k8s/apiworld-mock-server:1.4 pi4k8s/apiworld-mock-server-amd64:1.4 --os linux --arch amd64'
sh 'docker manifest annotate pi4k8s/apiworld-mock-server:1.4 pi4k8s/apiworld-mock-server-arm64:1.4 --os linux --arch arm64'
sh 'docker manifest push pi4k8s/apiworld-mock-server:1.4'
}
stage('cleanWs'){
parallel (
'arm64': {
cleanWs()
},
'amd64': {
node('amd64') {
cleanWs()
}
}
)
}
}
#!/bin/bash
echo "build ..."
if [ "install_all" = $1 ]; then
mvn compile -pl apiworld-api -am -Dapigc.skip=false
mvn compile -pl apiworld-bundle -am -Dbdgc.skip=false
mvn compile -pl apiworld-client -am -Dclientgc.skip=false
mvn clean install -U
elif [ "deploy_all" = $1 ]; then
mvn compile -pl apiworld-api -am -Dapigc.skip=false
mvn compile -pl apiworld-bundle -am -Dbdgc.skip=false
mvn compile -pl apiworld-client -am -Dclientgc.skip=false
mvn clean deploy -U
elif [ "package_mock_server" = $1 ]; then
mvn clean package -U -pl apiworld-mock-server -am -Dbdmgc.skip=false
elif [ "clean_all" = $1 ]; then
mvn clean
rm -rf *-api/src
rm -rf *-client/src
rm -rf *-bundle/src
rm -rf *-bundle-mock/src
fi
echo "build done."
pipeline執行
配置任務
jenkins控制檯新建item
輸入任務名稱apiworld-mock-server-image,選擇Pipeline後,點“確定”按鈕,進入配置任務頁面
選擇Pipeline script from SCM後,顯示SCM下拉選擇框如下
選擇Git後,顯示Repository標籤和Repository URL輸入框如下
Repository URL輸入https://gitee.com/fastjrun/apiworld-codeg.git
腳本路徑輸入docker.groovy
點“保存”按鈕後,這個構建支持多CPU架構docker鏡像並推送到hub的任務就配置好了
任務執行
以參考樹莓派4B基於docker搭建devops平臺首次部署的jenkins在不增添任何plugin的情況下執行本任務,是可以成功執行的。
Blue Ocean
安裝Blue Ocean插件後,可以更直觀看到本流水線執行的效果。
總結
參考樹莓派4B基於docker搭建devops平臺進行搭建的jenkins已經解決了很多潛在問題,如果參考其他方案搭建的jenkins在執行構建過程中可能會遇到一些其他問題,您參考網上的解決方案自行處理即可,本實踐將不再贅述。