侧边栏壁纸
博主头像
fastjrun博主等级

前大厂工程师,长期从事 Java 开发,架构设计,容器化等相关工作,精通java,熟练使用maven、jenkins等devops相关工具链,擅长容器化方案规划、设计和落地。

  • 累计撰写 47 篇文章
  • 累计创建 39 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

pipeline实例-构建支持多CPU架构docker镜像并推送到hub

fastjrun
2022-02-05 / 0 评论 / 0 点赞 / 190 阅读 / 6,838 字 / 正在检测是否收录...

收益

  • 不用再通过命令行发布
  • 发布环境稳定,可以重复执行
  • 多节点同步构建,提高效率

准备

  • 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架构IPdocker-versiondocker-Experimental
jenkins宿主机centos7.9arm6410.168.1.22019.03.8true
x86服务器centos7.7amd64192.168.99.24017.05.0-cefalse

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.
root@192.168.99.240'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在执行构建过程中可能会遇到一些其他问题,您参考网上的解决方案自行处理即可,本实践将不再赘述。

0

评论区