65-CICD持续集成工具-Jenkins分布式架构及部署全过程

时间:2023-02-20 17:14:27

Jenkins 分布式相关概念

Jenkins官方提供了 Jenkins 分布式构建,将众多job分散运行到不同的 Jenkins slave节点,大幅提高并行job的处理能力。除此之外,还可以针对不同的开发环境分配至不同的Slave实现编译部署。比如:Java程序分配至Slave1,Go程序的编译分配给Slave2,Nodejs程序分配给Slave3

采用 master/agent 架构,因而其节点可划分主节点(master)和代理节点(agent)两种类型,主节点负责提供UI、处理HTTP请求及管理构建环境等,而代理节点则主要负责执行构建任务代理节点也被称为从节点(slave)

主从架构图

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 主节点Master/Controller: Jenkins的一个部署实例的核心控制系统,它能够完全访问所有Jenkins配置的选项和任务(job)列表,而且,若不存在其他代理节点,主节点也是默认的任务执行节点
  • 代理节点Agent/Slave:在早先版本的Jenkins中,代理节点 (agent)也被称为从节点(slave),它代表着所有的非主节点。这类节点由主节点管理,按需分配或指定执行特定的任务,例如不同的构建任务或测试脚本式流水线中,节点特指一个运行代理节点的系统,而在声明式流水线中,它则是分配的一个作为代理节点的特定节点。可以分为静态和动态两种:
  • 静态Agent:
  • 以daemon形式运行的Jenkins;每个Agent可以存在多个Executor,具体的数量应该根据Agent所在主机的系统资源来设定
  • (1) Linux Jenkins
  • (2) Windows Jenkins
  • (3) Jenkins Container
  • 注意:很多的构建步骤,有可能会通过运行shell命令进行,于是此时要确保在Container内部有可用的命令
  • 动态Agent:
  • 由Controller按Job的运行需要临时创建,且Job运行结束后会删除;可以把每个Agent视作一个动态的Executor;
  • 依赖的环境:云,支持由Jenkins Controller通过API调用
  • Docker Plugin:基于配置的Docker Host,按需要创建容器运行Agent,需要事先配置好容器模板
  • Kubernetes Plugin:基于配置的Kubernets,按需要创建Pod运行Agent,需要事先配置Pod模板
  • Jenkins 自身既可以部署在k8s上,也完全可以运行在k8s外
  • 执行器(Executor):简单来说,Executor只是节点或代理节点用于执行任务的一个糟位
  • Executor的数量定义了该节点可以执行的并发任务量,一个节点上可以有任务数量的糟位,但也允行管理员按节点资源定义合适的数量
  • 在主节点将任务分配给特定节点时,该节点上必须有可用的Executor来立即执行该任务,否则、只能等到有空闲槽位可用

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 节点标签
  • Jenkins中的标签(tag)指的是节点上的标识符,而后可由pipeline中的agent指令等进行过滤和选择节点执行
  • 当Agent节点较多时,基于方便管理的目的,通常应该给这些节点添加能够体现其某种特性或功能的标签,以便于在构建任务中能基于标签过滤出符合条件的agent来
  • 一个 Agent 上可添加多个标签,一个标签也可以添加至多个 Agent
  • Jenkins 与 Agent之间的通信方式
  • JNLP-HTTP连接器。在agent上以手动或系统服务的方式经由JNLP协议触发双向连接的建立
  • 要求:Controller端额外提供一个套接字以接收连接请求,默认使用tcp协议的50000端口,也支持使用随机端口(安全,问题是会对服务端在防火墙开放该端口造成困扰),也可以使用websocket,基于默认8080端口建立集群通信连接。Controller jnlp server <-- Agent jnlp client
  • 在Controller上远程运行命令启动Agent(Launch agent via execution of command on thecontroller)
  • 以Docker 方式运行 Agent
https://hub.docker.com/r/jenkins/inbound-agent
https://hub.docker.com/r/jenkins/ssh-agent

案例:实现 Jenkins 分布式部署JAVA程序

案例架构

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • Slave 节点安装 Java 等环境确保和 Master 环境一致
  • #注意确保环境变量一致,否则在执行ssh远程命令时会有不生效的情况发生。如果不一致:
  • 可以将环境变量添加到/etc/bashrc或者/etc/profile中。
  • 也可以将该环境变量做链接指向一个通用文件夹内,比如 ln -s 环境变量 /usr/local/sbin
#Slave 节点通过从Master节点自动下载的基于 JAVA 的 remoting.jar 程序包实现,所以需要安装JDK
[root@jenkins-master ~]#java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
[root@jenkins-master ~]#which java
/usr/bin/java


[root@jenkins-slave1 ~]#apt -y install openjdk-11-jdk
[root@jenkins-slave1 ~]#java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
[root@jenkins-slave1 ~]#which java
/usr/bin/java

[root@jenkins-slave2 ~]#apt -y install openjdk-11-jdk
[root@jenkins-slave2 ~]#java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
[root@jenkins-slave2 ~]#which java
/usr/bin/java
  • Slave服务器需要创建与Master相同的数据目录,因为脚本中调用的路径只有相对于Master的一个路径,此路径在master与各node节点应该保持一致。任务中执行的脚本存放的路径和master也必须一致.如果Slave需要执行编译或执行特定的job,则也需要配置Java或其它语言环境,安装 git、maven、go、ansible等与master相同的基础运行环境
#创建数据目录,可以不创建,会自动创建
[root@jenkins-master ~]#ll /var/lib/jenkins
[root@jenkins-slave1 ~]#mkdir -p /var/lib/jenkins
[root@jenkins-slave2 ~]#mkdir -p /var/lib/jenkins

#如果需要执行特定任务,还需要安装相关的工具
[root@jenkins-master ~]#apt -y install git maven golang ansible
[root@jenkins-slave1 ~]#apt -y install git maven golang ansible
[root@jenkins-slave2 ~]#apt -y install git maven golang ansible
#maven做编译加速
[root@jenkins-master and slave1-2 ~]#vim /etc/maven/settings.xml
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
  • 名称解析要和jenkins服务器一致
[root@jenkins-slave1 ~]#vim /etc/hosts
[root@jenkins-slave1 ~]#cat /etc/hosts
...
192.168.11.200 gitlab.mooreyxia.org
192.168.11.201 jenkins.mooreyxia.org
[root@jenkins-slave1 ~]#resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (eth0)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
DNS Servers: 192.168.11.200
DNS Domain: mooreyxia.com mooreyxia.org

[root@jenkins-slave2 ~]#vim /etc/hosts
[root@jenkins-slave2 ~]#cat /etc/hosts
...
192.168.11.200 gitlab.mooreyxia.org
192.168.11.201 jenkins.mooreyxia.org
[root@jenkins-slave1 ~]#resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (eth0)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
DNS Servers: 192.168.11.200
DNS Domain: mooreyxia.com mooreyxia.org
  • 主从节点与部署对象服务器之间相互打通ssh验证
#思路:
Master:ssh-keygen ssh-copy-id salve
Master:ssh-keygen ssh-copy-id 部署对象服务器
salve:ssh-keygen ssh-copy-id 部署对象服务器

注意:为了防止Jenkins做ssh远程连接时出现ssh连接确认的yes验证,最好关闭/etc/ssh/ssh_config中的StrictHostKeyChecking,或者手动先建立连接
  • 主从节点公钥复制到Gitlab相关账户
#实例:从节点复制公钥到Gitlab,其他节点都参照此方式即可
#将上一步[root@jenkins-slave1 ~]#ssh-keygen 时生成的公钥复制出来
[root@jenkins-slave1 ~]#cat ./.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDENNshiRPKauMEPKlF5z+vrKH+Tc8EUWw7rxauMRQ2tFmzhgcohzhsOCxkmASlsXgvH82i9iQXUTLEEkDvsTU27nCZjqpYGC6qjFHwcgVdy3so/Wtyn25FEUKXz6x04y+OkrFxPMTArk4VgXUIW700VqFEtkQkQ+d2DIueFh0woCR04gDprCD2sX+lXU5j2WBhBdQQuBjL/8KqQRSr06hOVK6M9efzNY2voBMSD5XucVXinnT2QSutgmGS6ZTMnVABTrCYcVmgjbYuY7LnTnnM3Gby5WSDZ9TjF8aARbJM9l/K6yL7t8uRwO6sDjlRDaknhYkb3N+ElN+CBOnLph0zn/XhSQ985z32IEX79YYk3I7OVoYaVn1ycNEYf2GIG29ledtV4zXFJYUQ/jbz/8inpxiokewspvohTu65dLad0TMQWA0VN0M/+bKjQjNfNXiNeYM+4oHJbsx87GxKLN4W+uJMMH8bB5geNfzCIdXjPb20vmuUBzxlgwNNZxu9qLc= root@jenkins-slave1

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • Master 节点安装插件

插件安装前更换下载源

[root@jenkins-master ~]#sed -i.bak 's#updates.jenkins.io/download#mirror.tuna.tsinghua.edu.cn/jenkins#g' /var/lib/jenkins/updates/default.json
[root@jenkins-master ~]#sed -i 's#www.google.com#www.baidu.com#g' /var/lib/jenkins/updates/default.json

安装插件,实现 ssh 连接代理

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 添加 Master 访问 Slave 认证凭据
  • 用于 Master 连接 Slave 节点的凭据
  • 可以是用户密码的凭据,也可以配置Master节点到Slave节点SSH key 验证
  • 以root 身份连接 Agent

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 添加凭证 - 填写从节点的账户和密码

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 保存上述设置,从节点配置完成

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

接下来复制一个从节点即可

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

至此主从配置完成

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 确认主从配置成功
  • 主节点的22端口连接两个从节点主机
[root@jenkins-master ~]#ss -nt|grep 22
ESTAB 0 0 192.168.11.201:22 192.168.11.5:1503
ESTAB 0 0 [::ffff:192.168.11.201]:46224 [::ffff:192.168.11.207]:22
ESTAB 0 0 [::ffff:192.168.11.201]:36406 [::ffff:192.168.11.206]:22
  • 从节点运行着一个remoting.jar的线程,是主节点远程推送过来建立连接的程序
[root@jenkins-slave1 ~]#ps aux|grep jenkins
root 4774 1.8 5.9 3059828 120600 ? Ssl 04:57 0:10 java -jar remoting.jar -workDir /var/lib/jenkins -jar-cache /var/lib/jenkins/remoting/jarCache
root 4823 0.0 0.0 4020 1996 pts/0 S+ 05:07 0:00 grep --color=auto jenkins
[root@jenkins-slave1 ~]#ls /var/lib/jenkins
remoting remoting.jar

[root@jenkins-slave2 ~]#ps aux|grep jenkins
root 4774 1.8 5.9 3059828 120600 ? Ssl 04:57 0:10 java -jar remoting.jar -workDir /var/lib/jenkins -jar-cache /var/lib/jenkins/remoting/jarCache
root 4823 0.0 0.0 4020 1996 pts/0 S+ 05:07 0:00 grep --color=auto jenkins
[root@jenkins-slave2 ~]#ls /var/lib/jenkins
remoting remoting.jar
  • 查看Jenkins Slave 创建日志

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • Jenkins创建任务并指派给从节点执行即可

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

限制项目运行节点,这里测试第一个从节点

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

指定运行节点后可以在节点信息界面看到相关任务

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

接着配置项目源

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程


#从节点需要配置主节点相同的执行文件
[root@jenkins-master ~]#scp -r /data/script/ 192.168.11.206:/data/script/
[root@jenkins-master ~]#scp -r /data/script/ 192.168.11.207:/data/script/

[root@jenkins-master ~]#vim /data/script/spring-boot-helloworld.sh
[root@jenkins-master ~]#cat /data/script/spring-boot-helloworld.sh
#!/bin/bash
#
APP_PATH=/data/spring-boot-helloworld/

HOST_LIST="
192.168.11.204
192.168.11.205
"

mvn clean package -Dmaven.test.skip=true

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

----------------------------------------------------------
#部署对象服务器的java环境要与Jenkins
[root@204 ~]#mkdir -p /data/spring-boot-helloworld/
[root@204 ~]#java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)

[root@205 ~]#mkdir -p /data/spring-boot-helloworld/
[root@205 ~]#java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
  • 保存构建配置,开始构建并确认结果

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程


[root@ubuntu204 ~]#ps aux|grep java
root 3238 5.3 8.9 3084028 181836 ? Sl 05:37 0:10 java -jar /data/spring-boot-helloworld//spring-boot-helloworld.jar --server.port=8888
root 3350 0.0 0.1 4020 2024 pts/0 S+ 05:40 0:00 grep --color=auto java

[root@ubuntu205 ~]#ps aux|grep java
root 3275 4.4 9.1 3084028 184748 ? Sl 05:37 0:09 java -jar /data/spring-boot-helloworld//spring-boot-helloworld.jar --server.port=8888
root 3313 0.0 0.1 4020 2044 pts/0 S+ 05:41 0:00 grep --color=auto java

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

  • 尝试进行代码升级
#更改到3.0
[root@gitlab spring-boot-helloworld]#vim src/main/java/com/neo/controller/HelloWorldController.java
[root@gitlab spring-boot-helloworld]#cat src/main/java/com/neo/controller/HelloWorldController.java
package com.neo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

@RequestMapping("/")
public String index() {
return "Hello Spring Boot 3.0!";
}
.....
[root@gitlab spring-boot-helloworld]#git commit -am 'v3.0'
[main afaf84a] v3.0
Committer: root <root@gitlab.mooreyxia.org>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:

git config --global --edit

After doing this, you may fix the identity used for this commit with:

git commit --amend --reset-author

1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab spring-boot-helloworld]#git push
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 2 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 657 bytes | 219.00 KiB/s, done.
Total 9 (delta 2), reused 0 (delta 0), pack-reused 0
To gitlab.mooreyxia.org:myprj/spring-boot-helloworld.git
f08accf..afaf84a main -> main

指派给第二个从节点执行部署任务

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

65-CICD持续集成工具-Jenkins分布式架构及部署全过程

以上就是分布式部署Jenkins全过程。

我是moore,欢迎技术交流。大家一起加油!!!