首页 > 其他分享 >Jenkins主从架构的实现

Jenkins主从架构的实现

时间:2023-07-17 20:33:46浏览次数:47  
标签:kind Slave slave name 架构 jenkins Jenkins 主从

一、概要

提到K8S环境下的CI/CD,可以使用的工具有很多,比如Jenkins、Gitlab CI、新兴的drone等,考虑到大多公司在VM环境下都采用 Jenkins 集群来搭建符合需求的 CI/CD 流程,这里先给介绍大家下Kubernetes+Jenkins的CI/CD方案。
Jenkins是一款开源 CI&CD 系统,用于自动化各种任务,包括构建、测试和部署。
Jenkins官方提供了镜像:https://hub.docker.com/r/jenkins/jenkins

1、Jenkins架构


Jenkins Master 和 Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上,Master是常驻服务,所有的配置数据都存储在一个 Volume 中,Slave 不是一直处于运行状态,它会按照需求动态的创建并自动删除。

2、工作原理

当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Pod 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且这个 Pod 也会自动删除,恢复到最初状态。

3、优势

相对于部署在虚拟机环境下的Jenkins 一主多从架构,将Jenkins部署到K8S会带来以下好处:

  • 服务高可用: 当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master 容器,并且将 Volume 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用。

  • 动态伸缩: 合理使用资源,每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配 Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。

  • 扩展性好: 当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。

二、部署Jenkins

使用Deployment来部署这个镜像,会暴露两个端口:8080 Web访问端口,50000 Slave通信端口,容器启动后Jenkins数据存储在/var/jenkins_home目录,所以需要将该目录使用PV持久化存储。

1、配置静态PV持久化存储:

1.1 部署NFS共享服务器

在所有节点安装NFS软件包:yum install nfs-utils -y

1.2 找一个节点作为NFS共享存储服务器

mkdir -p /ifs/kubernetes/jenkins-data
vi /etc/exports
  /ifs/kubernetes 192.168.200.0/24(rw,no_root_squash)
systemctl start nfs && systemctl enable nfs

1.3 为Jenkins准备PV

apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
spec:
  capacity:
    storage: 5Gi
  accessModes: ["ReadWriteOnce"]
nfs:
  path: /ifs/kubernetes/jenkins-data
  server: 192.168.200.31

1.4 编写相应yaml

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: ops
  labels:
    name: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      name: jenkins 
  template:
    metadata:
      name: jenkins
      labels:
        name: jenkins
    spec:
      serviceAccountName: jenkins
      containers:
        - name: jenkins
          image: jenkins/jenkins
          ports:
            - containerPort: 8080
            - containerPort: 50000
          resources:
            limits:
              cpu: 2
              memory: 4Gi
            requests:
              cpu: 1
              memory: 1Gi
          env:
            - name: LIMITS_MEMORY
              valueFrom:
                resourceFieldRef:
                  resource: limits.memory
                  divisor: 1Mi
            - name: JAVA_OPTS
              value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
          volumeMounts:
            - name: jenkins-home
              mountPath: /var/jenkins_home
      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkins-home
        persistentVolumeClaim:
          claimName: jenkins
---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins
  namespace: ops
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

rbac.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: ops

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins
  namespace: ops
rules:
- apiGroups: [""]
  resources: ["pods","events"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get","list","watch"]
- apiGroups: [""]
  resources: ["secrets","events"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: jenkins
  namespace: ops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins

service.yml

apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: ops
spec:
  selector:
    name: jenkins
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
      nodePort: 30008
    - name: agent
      port: 50000
      protocol: TCP

1.4 运行相应yml

kubectl apply -f deployment.yml -f rbac.yml -f service.yml

  • Git:拉去代码
  • Git Parameter:Git参数化构建
  • Pipeline:流水线
  • kubernetes:连接Kubernetes动态创建Slave代理
  • Config File Provider:存储配置文件
  • Extended Choice Parameter:扩展选择框参数,支持多选

2、Jenkins主从架构

2.1 安装相应插件

管理Jenkins --> 系统配置 --> 管理插件 --> 分别搜索 Git/Git Parameter/Pipeline/kubernetes/Config File Provider/Extended Choice Parameter
配置插件: 管理Jenkins --> 管理Node和云 --> 管理云 --> 添加Kubernetes

2.2 自定义Jenkins-Slave镜像

FROM centos:7
LABEL maintainer Xin
RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins

COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave

ENTRYPOINT ["jenkins-slave"]

Dockerfile涉及的六个文件:

构建并推送到镜像仓库:

docker build -t 192.168.200.10/library/jenkins-slave-jdk:1.8 .
docker push 192.168.200.10/library/jenkins-slave-jdk:1.8

2.3 测试主从架构是否正常

新建项目 --> 流水线 --> Pipeline脚本

```yaml
pipeline {
  agent {
    kubernetes {
      label "jenkins-slave"
      yaml '''
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
spec:
  containers:
  - name: jnlp
    image: "192.168.200.10/library/jenkins-slave-jdk:1.8"
'''
    }
  }
    stages {
      stage('Main'){
        steps {
          sh 'hostname'
        }
      }
    }
}
重启Jenkins,在Jenkins域名后+ /_restart
kubectl get pods -n ops

标签:kind,Slave,slave,name,架构,jenkins,Jenkins,主从
From: https://www.cnblogs.com/superingXin/p/17561131.html

相关文章

  • Java从零基础到架构师再到运维的学习路线
    Java从零基础到架构师再到运维的学习路线1.Java基础知识:-Java语法和基本数据类型-面向对象编程概念:类、对象、继承、封装、多态等-流程控制和循环:条件语句、循环语句-异常处理:异常类型、try-catch-finally块-集合框架:-数组:一维数组和多维数组,数组的操......
  • LNMP架构和LAMP架构对比
    Linux+Nginx+MySQL+PHPLinux+apache+mysql+php图解: ......
  • docker分布式存储之哈希槽3主3从redis集群配置+主从扩容缩容
    创建开启六台redis容器systemctlrestartdockerdockerpullredis:6.0.8根据需求下载redis的镜像版本配置3主3从开启六台redis容器分别用node-1~node-6来区分dockerrun-d--nameredis-node-1--nethost--privileged=true-v/tmp/redis/share/redis-node......
  • Scrapy框架架构
    ENGINE:引擎,负责各个组件的管理。SPIDERS:各个爬虫文件类。(我们一般要写的代码就是这个)。SCHEDULER:调度器,ENGINE将爬虫任务分发给该组件,由该组件调度爬虫任务。DOWNLOADER:下载器,用于接收SCHEDULER的任务,并向指定的URL发起请求然后返回响应数据给SPIDERS组件,交给SPIDER组件进一......
  • 【.Net Core】生成项目处理器架构MSIL与目标项目架构 "AMD64" 不一致
    修复方法在当前项目的项目文件中<PropertyGroup>标签中添加架构(按照需要,可以只需要保留一个):<PropertyGroup><Platforms>AnyCpu;x64</Platforms></PropertyGroup>在编译配置中,修改当前项目(或者目标项目)的编译架构:注意,Debug和Release都需要修改......
  • Java开发大型互联网-架构师必须掌握的分布式技术
    Java开发大型互联网-架构师必须掌握的分布式技术摘要:在当今互联网行业,随着用户量和业务的不断增长,大型互联网系统的设计和开发已经成为了一项头等重要的任务。作为架构师,要能够应对这样的挑战,就必须掌握一些关键的分布式技术。本文将介绍Java开发大型互联网系统时,架构师必须要掌......
  • 高级java高并发,高性能,分布式,高可用,负载均衡,系统架构实战
    提到锁,大家肯定想到的是sychronized关键字。是用它可以解决一切并发问题,但是,对于系统吞吐量要求更高的话,我们这提供几个小技巧。帮助大家减小锁颗粒度,提高并发能力。初级技巧-乐观锁乐观锁使用的场景是,读不会冲突,写会冲突。同时读的频率远大于写。悲观锁的实现: 悲观的认为所......
  • redis 无法开启主从
    Redis无法开启主从简介Redis是一种内存数据库,它支持主从复制。通过主从复制,我们可以将Redis的数据复制到多个节点上,实现数据的高可用和负载均衡。但是,在实际应用中,我们可能会遇到一些问题,其中一个常见的问题是无法开启主从复制。本文将探讨一些可能导致Redis无法开启主从......
  • Jenkins 系列3 --- pipeline
    一、概要1.承上启下Jenkins系列2.概念Pipeline用于顺序执行应用部署所需的任务,比如Build(编译)、Test(编译)和Deploy(部署)等。Pipeline是Jenkins的核心组成部分。Pipeline定义在Jenkinsfile中,它支持两种语法定义,一种是DeclarativePipelinesyntax(声明式管道语法),另一种......
  • mysql主从复制
    1.MySQL主从复制介绍  主从复制实现的原理:(同步二进制日志文件)  主服务器开启二进制日志功能,当mysql进行操作同时生成一条操作事件日志,  并写入二进制日志文件中,从服务器通过同步二进制日志文件,并在从服务器  重新执行该事件,从而实现主从复制。2.主从服务器配置 ......