一、动态Jenkins-Slave解决方案上
1、基于Jenkins的Master-Slave模式实现CI-CD
1.1 痛点梳理
- 构建任务高峰期,Jenkins 服务频发不可用状态
- 服务虚拟机资源有限,不能随意调用空闲资源
- Jenkins服务器宕机后需要人工手动重启
1.2 思路分析
基于K8S动态Slave 模式
优势
- 基于云原生现有K8S集群解决问题,充分利用现有资源
- Slave 可构动态构建任务,工作结束后自动销毁,释放资源
- 通过K8S管理Jenkins调度策略,防止Slave调度分布不均匀
- 云原生控制器管理Jenkins配置,后期有利于维护、扩展
- Jenkins小概率意外宕机场景,通过K8S的机制可自愈
劣势
- 增加系统复杂度
- 有一定技术壁垒
- 实现需要时间
2、Master-Slave工作原理
2.1 基于K8S集群
Jenkins Master 接到构建任务后会动态在集群中的一个工作节点上启一个Jenkins Slave Pod工作,任务完成后释放Pod
2.2 设计优势
- 动态伸缩:合理的使用资源,每次运行Job时,会自动创建一个Jenkins Slave,Job完成后,Slave 自动注销并删除容器,资源自动释放,Kubernetes 会根据每个资源的使用情况,动态分配Slave 到空闲的节点创建
- 服务高可用:当Jenkins Master 出现故障,Kubernetes 会自动创建一个新的Jenkins Master 容器,并且将Volume分配给新创建的容器,保障数据不丢失
- 扩展性好:当Kubernetes 集群的资源严重不足而导致Job排队等待时,肯容易添加一个Node 到集群,实现扩展
3、Jenkins 部署
3.1 从github下载Jenkins Kubernetes mainifest files
# git clone https://github.com/scriptcamp/kubernetes-jenkins
正克隆到 'kubernetes-jenkins'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 16 (delta 1), reused 0 (delta 0), pack-reused 9
Unpacking objects: 100% (16/16), done.
# pwd
/root/k8s-Advanced/you_know_for_k8s-master/K8S_Advanced/4/kubernetes-jenkins
您在 /var/spool/mail/root 中有新邮件
[root@master-1-230 kubernetes-jenkins]# ll
总用量 28
-rw-r--r-- 1 root root 1441 12月 2 15:46 deployment.yaml
-rw-r--r-- 1 root root 230 12月 2 15:50 jenkins-pv-claim.yaml
-rw-r--r-- 1 root root 62 12月 2 11:15 namespace.yaml
-rw-r--r-- 1 root root 161 12月 2 11:15 README.md
-rw-r--r-- 1 root root 531 12月 2 11:15 serviceAccount.yaml
-rw-r--r-- 1 root root 336 12月 2 11:15 service.yaml
-rw-r--r-- 1 root root 624 12月 2 15:33 volume.yaml
3.2 为Jenkins创建Namespace
# kubectl create namespace devops-tools
namespace/devops-tools created
3.3 创建 serviceAccount.yaml
# kubectl apply -f serviceAccount.yaml
clusterrole.rbac.authorization.k8s.io/jenkins-admin created
serviceaccount/jenkins-admin created
clusterrolebinding.rbac.authorization.k8s.io/jenkins-admin created
3.4 创建jenkins-pv-claim.yaml
[root@master-1-230 kubernetes-jenkins]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 6d17h
nfs-storageclass k8s-sigs.io/nfs-subdir-external-provisioner Retain Immediate false 6d17h
rook-ceph-block (default) rook-ceph.rbd.csi.ceph.com Delete Immediate true 4d18h
rook-cephfs rook-ceph.cephfs.csi.ceph.com Delete Immediate true 4d18h
# kubectl apply -f jenkins-pv-claim.yaml
persistentvolumeclaim/jenkins-pv-claim created
3.5 创建deployment.yaml
# kubectl apply -f deployment.yaml
deployment.apps/jenkins created
[root@master-1-230 kubernetes-jenkins]# kubectl get pod -n devops-tools
NAME READY STATUS RESTARTS AGE
jenkins-56b6774bb6-kprfr 1/1 Running 0 27m
3.6创建service.yaml
# kubectl apply -f service.yaml
service/jenkins-service created
默认情况下,Jenkins生成代理是保守的
例如,队列中有两个构建,他不会立即生成两个执行器。它将生成一个执行器,并等待某个时间释放第一个执行器,然后再决定生成第二个执行器。Jenkins 确保生成的每个执行器都得到最多限度的使用
如果想覆盖这个行为,并生成一个为每个队列不等待的执行器,可以在Jenkins启动时添加下列参数:
- -Dhudson.slaves.NodeProvisioner.initialDelay=0
- -Dhudson.slaves.NodeProvisioner.MARGIN=50
- -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
Jenkins使用NFS做持久化:
# cat /etc/exports
/data/nfs/ *(insecure,rw,sync,no_root_squash)
查查看Jenkins初始化密码
[root@master-1-230 ~]# kubectl exec -it jenkins-56b6774bb6-kprfr -n devops-tools -- cat /var/jenkins_home/secrets/initialAdminPassword
47bb0ac4e5c94573b334c5adc138fd01
二、动态Jenkins-Slave解决方案中
4、 Jenkins 配置
4.1 插件安装
“系统管理”-->“插件管理”-->"可选插件"
4.2 全局凭据(unrestricted)
- git-auth-passwd,类型:Username with password
- Harbor,类型:Username with password
- kubeconfig,类型:Secret file
kubeconfig:如果是kubeadm部署的,配置文件路径:
cat /root/.kube/config
4.3 在Jenkins添加k8s
系统管理-->节点管理-->Configure Cloud
#kubernetes 地址采用kube的服务发现:
https://kubernetes.default.svc.cluster.local
#点击Test Connection,如果出现 “Connected to Kubernetes v1.27.6”的提示证明Jenkins已经可以和Kubernetes正常通信
#jenkins 地址
http://jenkins.devops.svc.cluster.local:8080
4.4 Slave Container 设计思路
基于K8S拉起的服务,都是一Pod形式存在,二Pod是容器组,最终服务实际是以Pod内的Container支撑运行。针对Slave的应用场景,Container 应该如何设计?
- Jenkins-Master在构建Job时,Kubernetes 会创建Jenkins-Slave 的Pod来完成Job的构建
- 运行Jenkins-Slave的镜像为官方推荐镜像:jenkins/jnlp-slave:latest。但是这个镜像没有Maven 环境,为了方便使用,需要自定义一个镜像
Dockerfile 内容如需爱
maven和settings.xml
[root@master-1-230 jenkins-slave-maven]# cat Dockerfile
FROM jenkins/jnlp-slave:latest
MAINTAINER k8s
# 切换到 root 账户进行操作
USER root
# 安装 maven
COPY apache-maven-3.3.9-bin.tar.gz .
RUN tar -zxf apache-maven-3.3.9-bin.tar.gz && \
mv apache-maven-3.3.9 /usr/local && \
rm -f apache-maven-3.3.9-bin.tar.gz && \
ln -s /usr/local/apache-maven-3.3.9/bin/mvn /usr/bin/mvn && \
ln -s /usr/local/apache-maven-3.3.9 /usr/local/apache-maven && \
mkdir -p /usr/local/apache-maven/repo
COPY settings.xml /usr/local/apache-maven/conf/settings.xml
USER jenkins
构建镜像:
# docker build -t jenkins-slave-maven:v1 .
上传到harbor仓库(公共镜像全部放在/library/下)
docker tag docker:stable harbor-local.kubernetes.cn/library/docker:stable
5、测试验证:
def git_address = "http://gitlab.kubernets.cn/demoteam/java_kubernetes.git"
def git_auth = "1cc6009e-fdfc-4b4b-9041-43d7487af929"
//创建一个Pod的模板,label为jenkins-slave
podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "harbor-local.kubernets.cn/library/jenkins-slave-maven:v1"
)
]
)
{
//引用jenkins-slave的pod模块来构建Jenkins-Slave的pod
node("jenkins-slave"){
stage('拉取代码'){
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
}
}
}
6、总结:
下面基于Master-Slave模式下jenkins的运行优势总结
- 负责均衡:Master-Slave模式让Jenkins可以在多台机器分布任务,从而提高Jenkins处理任务的能力
- 故障容错:Master-Slave 模式在Jenkins系统出现故障时能够提供更好的支持
- 扩展性:使用Master-Slave模式可以帮助Jenkins系统轻松扩展
- 分布式构建:在Master-Slave模式下,Jenkins可以在多个Slacve节点运行不同的任务,从而实现分布式
- 安全性:Master-Slave模式可以提供jenkins系统的安全性
三、动态Jenkins-Slave解决方案下
关于Master 版本与slave版本不一致的解决方案
- 降级jenkins 为初始版本,版本为jdk8
- 升级slave-jdk为11 版本
# cat 3Dockfile #FROM jenkins/jnlp-slave:latest FROM jenkins/jnlp-slave:4.13.3-1-jdk11 MAINTAINER k8s # 切换到 root 账户进行操作 USER root # 安装 maven COPY apache-maven-3.3.9-bin.tar.gz . RUN tar -zxf apache-maven-3.3.9-bin.tar.gz && \ mv apache-maven-3.3.9 /usr/local && \ rm -f apache-maven-3.3.9-bin.tar.gz && \ ln -s /usr/local/apache-maven-3.3.9/bin/mvn /usr/bin/mvn && \ ln -s /usr/local/apache-maven-3.3.9 /usr/local/apache-maven && \ mkdir -p /usr/local/apache-maven/repo COPY settings.xml /usr/local/apache-maven/conf/settings.xml USER jenkins
四、发布流程设计
1、发布流程设计
- 开发提交代码
- Jenkins 自动触发构建(代码拉取/编译/执行Dockerfile业务逻辑/镜像推送)
- 通过控制器./Helm部署应用到测试环境
- 测试验证后,通过Jenkins 再次构建发布到PROD环境
- 服务暴露/访问/验证
基于Kubernetes完整的DevOps流程
涉及技术栈
Gitlab、Jenkins、Harbor、Kubernetes(kubectl/Helm/Yaml/NFS/Ingress/LB)、Maven
小结:
使用Jenkins Pipeline实现自动化部署需要遵循以上几个步骤。通过Pipeline定义管道、定义步骤、定义触发条件、集成和自动化测试以及环境管理,我们实现一个标准化的自动化部署方案,
2、流水线自动发布微服务项目
2.1 将微服务项目自动化部署到K8S平台的需求
- 完全自动化部署,无需人工干预
- 可以选择部署/回滚某个微服务
- 部署/升级微服务时,可以对微服务做特性配置。如:namespace、branch、apptype、replicas、requests/limits
2.2 实现思路
在微服务架构中,会设计几个、几十个微服务,如果每个服务都创建一个item,会增加维护成本,因此需要编写一个通用的Pipeline项目。将差异化部分使用Jenkins参数,然后由人工交互确认发布微服务,构建完成稿使用邮件通知
研发只负责维护应用的Dockerfile,其余控制器文件指定一些列标准,使用Helm完成YAML文件的高效复用和微服务部署。
3、可观察性
3.1 基础设置
资源监控可以快速查看负载的CPU、存储、网络等指标
3.2 容器性能层
提供集群、容器的部分性能指标监控,并集成在容器服务控制台中
3.4应用性能层
武器如式应用探测
侵入式APM监控
3.4 用户业务层
日志观测/监控
域名拨测/核心接口探测/上下游业务监控
4、总结
基于K8S/Jenkins 平台的微服务发布解决方案可以实现自动化流程,提高发布效率和质量
标签:Slave,4.2,--,maven,jenkins,Jenkins,4.1,root From: https://www.cnblogs.com/pythonlx/p/17871302.html