pipeline實例-構建支持多CPU架構docker鏡像並推送到hub

收益

  • 不用再通過命令行發佈
  • 發佈環境穩定,可以重複執行
  • 多節點同步構建,提高效率

準備

  • 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設計與實現

步驟

  1. 下載源碼
  2. jenkins宿主機和x86服務器分別構建鏡像、推送hub鏡像
  3. jenkins宿主機創建manifest
  4. 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()
                    }
                }
        )
    }
}

build.sh

#!/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在執行構建過程中可能會遇到一些其他問題,您參考網上的解決方案自行處理即可,本實踐將不再贅述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章