day10 动态Jenkins-Slave解决方案-发布流程设计 (4.1.1-4.2)

发布时间 2023-12-02 17:29:38作者: ikubernetesi

一、动态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的运行优势总结

  1. 负责均衡:Master-Slave模式让Jenkins可以在多台机器分布任务,从而提高Jenkins处理任务的能力
  2. 故障容错:Master-Slave 模式在Jenkins系统出现故障时能够提供更好的支持
  3. 扩展性:使用Master-Slave模式可以帮助Jenkins系统轻松扩展
  4. 分布式构建:在Master-Slave模式下,Jenkins可以在多个Slacve节点运行不同的任务,从而实现分布式
  5. 安全性:Master-Slave模式可以提供jenkins系统的安全性

三、动态Jenkins-Slave解决方案下

关于Master 版本与slave版本不一致的解决方案

  1. 降级jenkins 为初始版本,版本为jdk8
  2. 升级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、发布流程设计

  1. 开发提交代码
  2. Jenkins 自动触发构建(代码拉取/编译/执行Dockerfile业务逻辑/镜像推送)
  3. 通过控制器./Helm部署应用到测试环境
  4. 测试验证后,通过Jenkins 再次构建发布到PROD环境
  5. 服务暴露/访问/验证

基于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 平台的微服务发布解决方案可以实现自动化流程,提高发布效率和质量