CICD04 Jenkins容器化CICD实现及分布式构建, 流水线Pipeline ubuntu使用

2.14.3 案例: 基于 Docker 插件实现自由风格任务实现 Docker 镜像 制作

不如前面的直接脚本编写灵活

2.14.3.2 安装插件 docker-build-step

jenkins上安装 docker-build-step 插件

#选择jenkins使用的docker服务
#左侧系统管理,右侧系统配置,Docker Builder下Docker URL输入
unix:///var/run/docker.sock    #unix://开头,后面套接字前面以对jenkins用户授权
#也可以配置成 tcp://localhost:2375
#点test测试,如报错可能是docker代理问题,把jenkins全局安全配置跨站请求伪造保护启动代理兼容
#注:sock是本地连接,如果要使用远程机器docker,输入 tcp://10.0.0.152:2375

#jenkins通过插件连接harbor,需要建一个凭据(使用的docker服务不用事先登录harbor)
#jenkins左侧系统管理,右侧凭据管理,添加凭据,用户名密码类型,输入harbor用户名密码
#ID,描述输入 harbor-xiaoming-password


#创建自由风格项目,输入git仓库,分支
#Build Steps下选执行shell,先进行编译
mvn clean package -Dmaven.test.skip=true

#然后,Build Steps下选Execute Docker command,选create/build image
#Build context folder(dockerfile路径) 填 
$WORKSPACE   #项目目录下,如果有子目录就往下写
#Tag of the resulting docker image(构建标签) 填  (后续要上传镜像)
harbor.wang.org/example/$JOB_NAME:$BUILD_NUMBER

#Build Steps下选Execute Docker command,选Push image
#Name of the image to push (repository/image) 填
example/$JOB_NAME
#Tag(标签) 填 $BUILD_NUMBER
#Registry 填 harbor.wang.org
#Docker registry URL 填 http://harbor.wang.org
#Registry credentials(凭据) 选 上面创建的harbor凭据

#Build Steps下选执行shell,目标机器运行容器
#!/bin/bash
REGISTRY=harbor.wang.org
HOSTS="
10.0.0.153
10.0.0.154"
#目标服务器docker要允许远程连接
for i in $HOSTS;do
     #ssh root@$i docker rm -f $JOB_NAME
     #ssh root@$i docker run -d -p 80:8888 --name $JOB_NAME harbor.wang.org/example/$JOB_NAME:$BUILD_NUMBER
    docker -H $i rm -f $JOB_NAME || true
    docker -H $i run -d -p 80:8888 --name $JOB_NAME ${REGISTRY}/example/$JOB_NAME:$BUILD_NUMBER
done

#保存任务,并构建

 

3 Jenkins 的高级功能

3.1 Jenkins 分布式

 agent通过标签来分来,master上的任务通过标签去找对应的agent执行

 3.1.1.2 Jenkins 主从架构图

 3.1.1.3 节点标签 Label

一个 Agent 上可添加多个标签,一个标签也可以添加至多个 Agent, 可以在作业中通过标签表达式实现Agent的过滤
标签名称不允许使用空白字符,也不允许使用标签表达式中预留的关键字,例如: !、&、|、<、>、) 和( 等
常用的标签纬度有如下几个
1.操作系统类型: Linux、Windows、MacOS
2.操作系统位数: 32bit、64bit
3.集成的工具链: jdk、Go、Python、Nodejs等

标签表达式(label expressions)支持如下操作符 (了解)
1.!expression:表达式条件取反
2.a && b:表达式间“与” 关系
3.a || b:表达式间“或” 关系
4.a -> b:表示如果满足a表达式,则同时必须满足b表达式,但是如果不满足a,则不要求满足b,等同于“!a || b”
示例: linux -> x64,意味着,如果操作系统为linux,则它也必须是x64的系统环境,如果不是
linux,则无要求必须是x64
5.a<->b:表示两个条件要么同时满足,要么同时都不满足,即等同于 “a && b || !a && !b”
6.(expression):表达式分组,常在需要改变操作符间的优先级顺序时使用

3.1.1.4 Jenkins Master 与 Agent之间的通信方式

3.1.1.5 Agent 分类

Agent 可以分为静态和动态两种

静态Agent: 长时间存在(服务方式启动)

动态Agent: 用完就销毁(容器方式运行)

3.1.2 实战案例: 基于 SSH 协议实现 Jenkins 分布式

#jenkins主机上安装插件 SSH Build Agents

#agent程序基于java,jenkins会传jar包到agent机器进行启动。
#两台agent机器环境需要安装和jenkins相同版本的java
[root@ubuntu ~]#apt update && apt -y install openjdk-11-jdk

#创建agent是在jenkins主机系统管理下的节点和云管理中创建的
#点击New Node,节点名称填 jenkins-agent01,固定节点, create
#Number of executors执行器,允许并发构建数,这里写 2(一般同cpu数量,最多为2倍cpu数量)
#远程工作目录填 /var/lib/jenkins (最好和jenkins master的目录相同,会自动创建)
#标签,可以写多个,空格隔开,jenkins根据标签分派任务,填 
java agent01 linux
#用法 选 只允许运行绑定到这台机器的Job (也就是匹配标签才执行)
#启动方式选 Launch agents via SSH  (走SSH协议)
#主机 填 10.0.0.156   (可填能解析的域名)
#Credentials 这里创建凭据,可以基于用户名密码 root/admin123
#(注:也可创基于SSH key验证的凭据SSH Username with private key,用户名root,填入私钥)
#ID和描述填 jenkins-agent-root-password
#选中前面创建的凭证
#Host Key Verification Strategy选Non veritying verification strategy(不用ssh验证yes)
#可用性 这里可以选  尽量保持代理在线
#节点属性下工具位置可以安装工具,这里不安装
#保存

#jenkins系统管理下节点列表显示节点没×表示连接成功,会显示内存等信息
#可以看到agent机器上运行了java应用

#再创建另一个节点
#点击New Node,节点名称填 jenkins-agent02,复制现有节点jenkins-agent01, create
#标签,可以写多个,空格隔开,jenkins根据标签分派任务,填 
golang agent02 linux
#主机 填 10.0.0.157   (可填能解析的域名)
#保存

#在一台专门java编译的agent上安装mvn
]#apt install -y maven

#jenkins master上创建任务测试agent
#创建自由风格任务,git输入java项目地址,分支
#General下点限制项目的运行节点,标签表达式(选择机器标签)输入  java
#Build Steps,执行shell
bash -x /data/jenkins/scripts/spring-boot-helloworld.sh
#保存

[root@jenkins scripts]#cat spring-boot-helloworld.sh
#!/bin/bash
APP_PATH=/data/spring-boot-helloworld
HOST_LIST="
10.0.0.153
10.0.0.154
"
mvn clean package -Dmaven.test.skip=true

for host in $HOST_LIST;do
    ssh root@$host killall -9 java &> /dev/null
    scp target/spring-boot-helloworld-*-SNAPSHOT.jar root@$host:${APP_PATH}/spring-boot-helloworld.jar
    #ssh root@$host "java -jar ${APP_PATH}/spring-boot-helloworld.jar --server.port=8888 &"
    ssh root@$host "nohup java -jar  ${APP_PATH}/spring-boot-helloworld.jar --server.port=8888 &>/dev/null & "&
done

#把执行脚本拷贝到agent机器上保持一致
[root@jenkins scripts]#scp -r /data/ 10.0.0.156:/
[root@jenkins scripts]#scp -r /data/ 10.0.0.157:/

#别忘了把新的2台agent机器和目标机器做免ssh的key验证
#构建任务

3.1.3 实战案例: 基于docker-compose 通过SSH 实现 Jenkins 分布 式

#准备docker-compose环境
[root@ubuntu2204 ~]#apt update && apt -y install docker-compose
[root@ubuntu2204 ~]#vim docker-compose.yaml
version: '3.6'

volumes:
  ssh_agent01_data: {}
  ssh_agent02_data: {}
networks:
  jenkins_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.27.0.0/24
services:
  ssh-agent01:
    image: jenkins/ssh-agent:jdk11
    hostname: ssh-agent01.wang.org
    #user: jenkins
    environment:
      TZ: Asia/Shanghai
      #JENKINS_AGENT_HOME: /home/jenkins
      JENKINS_AGENT_SSH_PUBKEY: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5krPWvOcWvQTP++JNkdBACy46vKnpcnIrNuv85NFIVFOGsvnvAZHCp2DRjXS7Q0GngipZ27XyTF99SEZnxZbS01ZgRSqldYaSHt+1poj4YSB+0tdP9+FO7u3NNyQ7qZ3NB4OzT21SFHIWm3ToA0Yjen8o8V3Dk87GdhE1O+8mWBYGyEQVN8QNveMFvI0dArWDwFjO/7Fu5zDS1/B6Sx4TLNBCoPE0gJ/A02pcpdDXk7pDdeAwC3SIqpOj2IuuoAQA4fNue1sx18av6DHKdkONf+fzJAVRJc+hgIsxqv94bP28HElbyE+1pdj0KBVU8FIGGJvvfL5RC2bk8NwPCsjEwYReL3nWDYPqQTjL4CCGjM6dpAgiM1UyYdcIQ499PEq/JAshktFEKn8LaVXl7nigi09AOQyTZ9l7D7de2gwcnKL26sbZ3gaB1O1cj3RCp1HjFvFS75py9F8flBYVNooRu7zMn4lnbA5pojSJXPsVs+4I821BmuRSZDVbsWRG2r8= root@jenkins
      # SSH PRIVATE KEY and PUBLIC KEY 需要手动生成,利用private key 创建凭据,此处写入public key
    networks:
      jenkins_net:
        ipv4_address: 172.27.0.21
        aliases:
          - ssh-slave01
          - ssh-agent01
    ports:
      - "22022:22"
    #restart: always

  ssh-agent02:
    image: jenkins/ssh-agent:jdk11
    hostname: ssh-agent02.wang.org
    #user: jenkins
    environment:
      TZ: Asia/Shanghai
      #JENKINS_AGENT_HOME: /home/jenkins
      JENKINS_AGENT_SSH_PUBKEY: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5krPWvOcWvQTP++JNkdBACy46vKnpcnIrNuv85NFIVFOGsvnvAZHCp2DRjXS7Q0GngipZ27XyTF99SEZnxZbS01ZgRSqldYaSHt+1poj4YSB+0tdP9+FO7u3NNyQ7qZ3NB4OzT21SFHIWm3ToA0Yjen8o8V3Dk87GdhE1O+8mWBYGyEQVN8QNveMFvI0dArWDwFjO/7Fu5zDS1/B6Sx4TLNBCoPE0gJ/A02pcpdDXk7pDdeAwC3SIqpOj2IuuoAQA4fNue1sx18av6DHKdkONf+fzJAVRJc+hgIsxqv94bP28HElbyE+1pdj0KBVU8FIGGJvvfL5RC2bk8NwPCsjEwYReL3nWDYPqQTjL4CCGjM6dpAgiM1UyYdcIQ499PEq/JAshktFEKn8LaVXl7nigi09AOQyTZ9l7D7de2gwcnKL26sbZ3gaB1O1cj3RCp1HjFvFS75py9F8flBYVNooRu7zMn4lnbA5pojSJXPsVs+4I821BmuRSZDVbsWRG2r8= root@jenkins
      # SSH PRIVATE KEY and PUBLIC KEY 需要手动生成,利用private key 创建凭据,此处写入:public key,和上面一样
    networks:
      jenkins_net:
        ipv4_address: 172.27.0.22
        aliases:
          - ssh-slave02
          - ssh-agent02
    ports:
      - "22122:22"
    #restart: always


#把上面公钥对应的私钥.ssh/id_rsa,在jenkins master中创创建凭据
#jenkins系统管理下,凭据管理,Add Credentials
#类型 SSH Username with private key,用户名(可能是jenkins启动用户)写 jenkins
#Private Key填入私钥
#ID和描述写 jenkins-agent-ssh-privatekey

#拉起容器
[root@ubuntu ~]#docker-compose up
#起来了2个容器
[root@ubuntu ~]#docker ps
CONTAINER ID   IMAGE                     COMMAND        CREATED          STATUS          PORTS                                     NAMES
b95d341fe35d   jenkins/ssh-agent:jdk11   "setup-sshd"   11 minutes ago   Up 11 minutes   0.0.0.0:22122->22/tcp, :::22122->22/tcp   root_ssh-agent02_1
e5322fa9b0d0   jenkins/ssh-agent:jdk11   "setup-sshd"   11 minutes ago   Up 11 minutes   0.0.0.0:22022->22/tcp, :::22022->22/tcp   root_ssh-agent01_1


#jenkins系统管理,节点和云管理,创建新的agent
#名称 jenkins-ssh-agent03, 固定节点
#远程工作目录(容器里面已经定义好了)  /home/jenkins
#标签  ssh
#用法  尽可能使用
#启动方式  Launch agents via SSH
#主机   10.0.0.156
#点高级,端口  22022
#Credentials凭据选前面创建的  jenkins-agent-ssh-privatekey
#Host Key Verification Strategy选 Non verfiying verification strategy
#保存,即可在从库列表看到节点对应状态

#jenkins系统管理,节点和云管理,创建新的agent,复制上面那个
#名称 jenkins-ssh-agent04, 复制现有节点jenkins-ssh-agent03
#点高级,端口  22122
#保存,即可在从库列表看到节点对应状态


#这两个镜像可能也有缺陷,比如没有maven,可以用他们作为父镜像,做子镜像

#jenkis执行任务测试这两个容器agent
#标签表达式ssh,git通过http方式,执行命令hostname -I
#注:如git用ssh失败,要先进容器,git clone手动信任主机,就能用这种方式了
#也可在jenkins系统管理/全局安全配置/Git Host Key Verification Configuration选No verification

3.1.4 实战案例:基于 JNLP协议的 Java Web 启动代理

Launch agent by connecting it to the controller 也称为 通过 Java Web 启动代理

此方式无需安装插件,即可实现

#jenkins系统管理/全局安全配置/代理 改成指定端口 50000

3.1.4.2 创建代理Agent节点

#jenkins系统管理/节点和云管理,创建节点 jenkins-jnlp-agent01,固定节点
#Number of executors 2
#远程工作目录  /var/lib/jenkins
#标签 jnlp agent01
#用法 只允许运行绑定到这台机器的ob
#启动方式  通过Java Web启动代理
#保存,点击该节点名称,有2条运行指令 Run from agent command line: (Unix)下

#在agent机器上执行上面2步,注意:要提前装java
[root@ubuntu2204 ~]#apt update && apt -y install openjdk-11-jdk
curl -sO http://10.0.0.152:8080/jnlpJars/agent.jar
[root@ubuntu2204 ~]#ls -l agent.jar 
-rw-r--r-- 1 root root 1371733  1月  1 17:07 agent.jar
#启动Agent
[root@ubuntu2204 ~]#java -jar agent.jar -url http://10.0.0.152:8080/ -secret b3cb19d89c6d22a0a4457d01f2efaf10233a3b55779dcc0efa160e32c3201539 -name "jenkins-jnlp-agent01" -workDir "/var/lib/jenkins"
...
INFO: Connected

#jenkins从库列表看到节点对应状态

#jenkins系统管理/节点和云管理,创建另一个节点 jenkins-jnlp-agent02,复制上面的节点
#标签  jnlp agent02
#保存
#另一台agent机器同样执行从节点给出的2步

#验证,jenkins自由风格任务,标签表达式 jnlp

3.1.5 实战案例:基于docker-compose实现通过JNLP协议的 Java Web 启动代理

3.1.5.2 启动 Docker Compose 容器的 Jenkins Agent

#jenkins上先创建从节点jenkins-jnlp-agent01,方法同上
#远程工作目录(镜像定义的)  /data/jenkins/
#记录生成创建命令中的秘钥,如下命令为 b3cb19d89c...01539
java -jar agent.jar -url http://10.0.0.152:8080/ -secret b3cb19d89c6d22a0a4457d01f2efaf10233a3b55779dcc0efa160e32c3201539 -name "jenkins-jnlp-agent01" -workDir "/var/lib/jenkins"
#替换下面docker-compose中的JENKINS_SECRET
#再生成一个从节点jenkins-jnlp-agent02,复制现有节点,方法同上

[root@ubuntu2204 ~]#cat docker-compose.yaml
version: '3.6'
volumes:
  agent01_data: {}
  slave02_data: {}
networks:
  jenkins_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.27.0.0/24
services:
  agent01:
    image: jenkins/inbound-agent:alpine-jdk11
    hostname: agent01.wang.org
    user: root
    environment:
      TZ: Asia/Shanghai
      JENKINS_URL: http://jenkins.wang.org:8080
      JENKINS_AGENT_NAME: jenkins-jnlp-agent01  #指定和Jenkins的Agent的名称相同
      JENKINS_AGENT_WORKDIR: /data/jenkins/
      #秘钥用jenkins创节点给的命令中的秘钥
      JENKINS_SECRET: 
3aef4f69d569d9f3b48e2daf91c3a80b1c8d8bcb310462859950dacc1b202cbc
      # 此处的JENKINS_SECRET需要用创建agent时生成的Secret替代
    volumes:
      - agent01_data:/data/jenkins/
    networks:
      jenkins_net:
        ipv4_address: 172.27.0.11
        aliases:
          - slave01
          - agent01
    #extra_hosts:
    # - "jenkins.wang.org:${JENKINS_HOST_IP}"
    #restart: always
  agent02:
    image: jenkins/inbound-agent:alpine-jdk11
    hostname: agent02.wang.org
    user: root
    environment:
      TZ: Asia/Shanghai
      JENKINS_URL: http://jenkins.wang.org:8080
      JENKINS_AGENT_NAME: jenkins-jnlp-agent02   #此处指定Jenkins的Agent的名称相同
      JENKINS_AGENT_WORKDIR: /data/jenkins/
      JENKINS_SECRET: 
fb52f831107fd9a7de8051ca8aa506dc4836056231d21aab7e82138febf83231
      # SECRET is automatically generated by the master when adding agent02.
    volumes:
      - agent01_data:/data/jenkins/
    networks:
      jenkins_net:
        ipv4_address: 172.27.0.12
        aliases:
          - slave02
          - agent02
    #extra_hosts:
    # - "jenkins.wang.org:${JENKINS_HOST_IP}"
    #restart: always
    
#拉起容器
[root@ubuntu ~]#docker-compose up
#jenkins上节点列表查看,连接成功

3.1.6 实战案例:基于Docker的动态Agent

这种用的很少, 性能一般。

3.1.6.1 准备 Docker Engine 主机

准备一台新的主机,安装 Docker Engine ,上此主机上运行Agent容器

[root@ubuntu2204 ~]#apt update && apt -y install docker.io

#如果需要远程 Docker 连接,需要修配下面配置
[root@ubuntu2204 ~]#vim /lib/systemd/system/docker.service
[Service]
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375

[root@ubuntu2204 ~]#systemctl daemon-reload && systemctl restart docker.service
#另一台机器上确认2375是否可以连接
]#curl -s 10.0.0.156:2375/version

3.1.6.2 安装 Docker 插件

jenkins安装Docker插件

3.1.6.3 创建 Cloud

#jenkins系统管理下,Clouds创建new cloud
#云名称  mydocker

#Docker Cloud details下 Docker Host URI(docker主机地址)
tcp://10.0.0.156:2375
#点击test查看能不能连上,点击Enabled,表示启用

#Docker Agent templates下, 点击添加模板
#Labels  jnlp ,点Enabled
#Name  docker-jnlp-agent
#Docker Image 镜像这里选走jnlp协议的,推荐 jenkins/inbound-agent:alpine-jdk11
#上面镜像小些,也可以jenkins/inbound-agent:jdk11

#Registry Authentication如果公司内网拉取要凭证,这里从互联网拉就不用选了
#点Container settings,Extra Hosts就是配/etc/hosts,可多个(如果公司有dns就不需要配这个)
gitlab.wang.org:10.0.0.151
jenkins.wang.org:10.0.0.152        #因为主动找jenkins,需要对应的域名解析

#Remote File System Root(镜像定的)  /home/jenkins
#用法  只允许
#Connect method  这里选JNLP  (这次用的是JNLP的方法)
#Jenkins URL  http://jenkins.wang.org:8080

#Pull strategy拉取策略(每次拉/拉一次有更新再拉/只在本地找) 这里选2 Pull once and update latest

#别忘了系统管理/全局安全配置代理开50000端口

#再加一个模板(走SSH协议), 2个模板对应就是2个agent
#Labels  ssh ,点Enabled
#Name  docker-ssh-agent
#Docker Image(基于ssh的镜像)  jenkins/ssh-agent:jdk11
#点Container settings,Extra Hosts就是配/etc/hosts,可多个(如果公司有dns就不需要配这个)
gitlab.wang.org:10.0.0.151
#Remote File System Root(镜像定的)  /home/jenkins
#用法  只允许
#Connect method  这里选SSH
#SSH key 选Inject SSH key  自动注入ssh key就不用管了(也可以自己往里拷)
#User写 jenkins  (容器里jenkins账号运行)

#点save,没有构建任务,那2个agent不会启动,执行结束也会删

#jenkins上用自由风格任务进行调用
#限制项目运行节点标签写 jnlp或者ssh,会自动显示1个cloud匹配
#注意:如果要mvn编译,还得基于该模板创建新的镜像,里面装maven


用docker插件通过云创建指定docker容器(云在哪,容器创建在哪)
#在jenkins自由风格任务下,Build Steps选 Start/Stop Docker Containers
#Action to choose选 Run container
#Docker Cloud选择上面创建的云  mydocker
#Docker Image这里写   wangxiaochun/pod-test:v0.1
#保存,构建,在连接的docker服务器上创建对应的容器

 

3.2 Jenkins Pipeline

3.2.3 Pipeline 语法

当前 Jenkins 2.X 支持两种语法的流水线: 脚本式(命令式)和声明式
1.脚本式Scripted Pipeline语法    (老版本,淘汰)
2.声明式Declarative Pipeline语法 (新版,推荐)

3.2.3.2 脚本式流水线语法

node {  
   stage('Source') {
       //git clone 
   }
   stage('Build') {
          //mvn 
   }
   stage('Test') { 
       //mvn test
   }
   stage('Deploy') { 
       // scp 
       // java -jar 
   }
}
#特点:最外层是node {} 

3.2.3.3 声明式流水线语法

#声明式流水线是在"Pipeline plugin"的2.5版本添加到 Jenkins 流水线的 ,它在流水线子系统之上提供了 一种更简单,更常见的语法。 
#所有有效的声明式流水线必须包含在一个 pipeline 块中, 比如: 
pipeline {
   /* insert Declarative Pipeline here */
}

 

posted @ 2024-11-13 21:27  战斗小人  阅读(3)  评论(0编辑  收藏  举报