1、Jenkins CI/CD 背景介绍

持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 Jenkins 集群来搭建符合需求的 CI/CD 流程,然而传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如:主 Master 发生单点故障时,整个流程都不可用了;每个 Slave 的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲;资源分配不均衡,有的 Slave 要运行的 job 出现排队等待,而有的 Slave 处于空闲状态;最后资源有浪费,每台 Slave 可能是实体机或者 VM,当 Slave 处于空闲状态时,也不会完全释放掉资源。

由于以上种种痛点,我们渴望一种更高效更可靠的方式来完成这个 CI/CD 流程,而 Docker 虚拟化容器技术能很好的解决这个痛点,下图是基于 Kubernetes 搭建 Jenkins 集群的简单示意图。

从图上可以看到 Jenkins Master 和 Jenkins Slave 以 Docker Container 形式运行在 Kubernetes 集群的 Node 上,Master 运行在其中一个节点,并且将其配置数据存储到一个 Volume 上去,Slave 运行在各个节点上,并且它不是一直处于运行状态,它会按照需求动态的创建并自动删除。

这种方式的工作流程大致为:当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Docker Container 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且 Docker Container 也会自动删除,恢复到最初状态。

这种方式带来的好处有很多:

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

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

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

2、环境、软件准备

1.centos 7

2.k8s集群

3、部署 Jenkins Server 到 Kubernetes

文件在GitHub上

https://github.com/wenpengfan/k8s-jenkins-CI-CD

说明一下:这里 Service 我们暴漏了端口 8080 和 50000,8080 为访问 Jenkins Server 页面端口,50000 为创建的 Jenkins Slave 与 Master 建立连接进行通信的默认端口,如果不暴露的话,Slave 无法跟 Master 建立连接。这里使用 NodePort 方式暴漏端口,并未指定其端口号,由 Kubernetes 系统默认分配,当然也可以指定不重复的端口号(范围在 30000~32767)。

接下来,通过 kubectl 命令行执行创建 Jenkins Service。

kubectl create -f jenkins-deployment.yaml

kubectl create -f jenkins-service.yaml

kubectl create -f service-account.yml

#当使用pvc持久化数据时,可能容器会起不来报错(我这里没有做持久化)

https://github.com/wenpengfan/k8s-jenkins-CI-CD

如报错Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

是因为默认的镜像使用的是 jenkins 这个用户,而我们通过 PVC 挂载到 nfs 服务器的共享数据目录下面却是 root 用户的,所以没有权限访问该目录,要解决该问题,也很简单,我只需要在 nfs 共享数据目录下面把我们的目录权限重新分配下即可:

$ chown -R 1000 /data/k8s/jenkins

查看状态

访问jenkins

http://192.168.30.147:30002

注意: 初始化过程中,让输入 /var/jenkins_home/secret/initialAdminPassword 初始密码时,因为我们没有挂载到外部路径,可以进入到容器内部进行获取。

$ kubectl exec -it jenkins-960997836-fff2q cat /var/jenkins_home/secrets/initialAdminPassword

4、Jenkins 配置 Kubernetes Plugin

管理员账户登录 Jenkins Master 页面,点击 “系统管理” —> “管理插件” —> “可选插件” —> “Kubernetes plugin” 勾选安装即可。

安装完毕后,点击 “系统管理” —> “系统设置” —> “新增一个云” —> 选择 “Kubernetes”,然后填写 Kubernetes 和 Jenkins 配置信息。

说明一下:

kubernetes地址:https://kubernetes.default.svc.cluster.local

注意 namespace,我们这里填 kube-ops,然后点击Test Connection,如果出现 Connection test successful 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了,然后下方的 Jenkins URL 地址:http://jenkins.kube-ops.svc.cluster.local:8080,这里的格式为:服务名.namespace.svc.cluster.local:8080

另外需要注意,如果这里 Test Connection 失败的话,很有可能是权限问题,这里就需要把我们创建的 jenkins 的 serviceAccount 对应的 secret 添加到这里的 Credentials 里面。

5、测试并验证

好了,通过 Kubernetes 安装 Jenkins Master 完毕并且已经配置好了连接,接下来,我们可以配置 Job 测试一下是否会根据配置的 Label 动态创建一个运行在 Docker Container 中的 Jenkins Slave 并注册到 Master 上,而且运行完 Job 后,Slave 会被注销并且 Docker Container 也会自动删除吧!

在不填写pod template的情况下,jenkins slave会默认使用jenkins/jnlp-slave:alpine镜像

5.1、pipeline 类型支持

创建一个 Pipeline 类型 Job 并命名为 my-k8s-jenkins-pipeline,然后在 Pipeline 脚本处填写一个简单的测试脚本如下:

def label = "mypod-${UUID.randomUUID().toString()}"

podTemplate(label: label, cloud: 'kubernetes') {

node(label) {

stage('Run shell') {

sh 'sleep 130s'

sh 'echo hello world.'

}

}

}

6, 配置 Pod Template

配置 Pod Template,其实就是配置 Jenkins Slave 运行的 Pod 模板,命名空间我们同样是用 kube-ops,Labels 这里也非常重要,对于后面执行 Job 的时候需要用到该值,然后我们这里使用的是 cnych/jenkins:jnlp 这个镜像,这个镜像是在官方的 jnlp 镜像基础上定制的,加入了 kubectl 等一些实用的工具。

另外需要注意我们这里需要在下面挂载两个主机目录,一个是 /var/run/docker.sock,该文件是用于 Pod 中的容器能够共享宿主机的 Docker,这就是大家说的 docker in docker 的方式,Docker 二进制文件我们已经打包到上面的镜像中了,另外一个目录下 /root/.kube 目录,我们将这个目录挂载到容器的 /home/jenkins/.kube 目录下面这是为了让我们能够在 Pod 的容器中能够使用 kubectl 工具来访问我们的 Kubernetes 集群,方便我们后面在 Slave Pod 部署 Kubernetes 应用。

另外还有几个参数需要注意,如下图中的Time in minutes to retain slave when idle,这个参数表示的意思是当处于空闲状态的时候保留 Slave Pod 多长时间,这个参数最好我们保存默认就行了,如果你设置过大的话,Job 任务执行完成后,对应的 Slave Pod 就不会立即被销毁删除。

到这里我们的 Kubernetes Plugin 插件就算配置完成了。

echo "测试 Kubernetes 动态生成 jenkins slave"

echo "==============docker in docker==========="

docker info

echo "=============kubectl============="

kubectl get pods

现在我们直接在页面点击做成的 Build now 触发构建即可,然后观察 Kubernetes 集群中 Pod 的变化

同样也可以查看到对应的控制台信息:

到这里证明我们的任务已经构建完成,然后这个时候我们再去集群查看我们的 Pod 列表,发现 kube-ops 这个 namespace 下面已经没有之前的 Slave 这个 Pod 了。

到这里我们就完成了使用 Kubernetes 动态生成 Jenkins Slave 的方法。下节课我们来给大家介绍下怎么在 Jenkins 中来发布我们的 Kubernetes 应用

动态jenkins slave相关推荐

  1. 基于K8s的动态Jenkins Slave构建实践

    前言 源于这篇文章分享的经验 基于 Kubernetes 的 Jenkins 构建集群实践,这里记录一下实践落地过程. 环境 这里Jenkins Master的安装没有采用容器镜像的方式,直接就是rp ...

  2. Jenkins+k8s部署Jenkins slave

    一.构建镜像 下载基础镜像,这里使用openvz的包,下载centos7的镜像 1.1 下载镜像后导入到本地 JENKINS VERSION为: 2.222.4 ------------------- ...

  3. 使用动态jenkins从节点和kubernetes进行实时滚动更新的Web服务器

    The main motive of this article is to solve real-world problems. Can you imagine the loss of Instagr ...

  4. jenkins slave在master显示和运行问题

    jenkins slave在master显示和运行问题 1.工作空间的中文文件显示乱码 2.运行一些插件报错如下 java.nio.file.InvalidPathException: Malform ...

  5. windows下jenkins slave 搭建

    一 创建新的Slave 注意Jenkins中slave称为note. 所以下面文章中的slave和node指的是一回事. 1)在Manage Jenkins-->Manage Nodes --& ...

  6. jenkins slave problem :Unsupported major.minor version 52.0

    2019独角兽企业重金招聘Python工程师标准>>> jdk发生变化,有原来高版本oracle jdk8降低为openjdk7 ubuntu 本地安装东西将默认jdk更换为open ...

  7. Jenkins slave 节点配置

    准备工作 插件安装 SSH Build Agents,允许使用 SSH 协议的 Java 实现通过 SSH 启动代理. Jenkins master 节点机器 Jenkins slave 从节点机器 ...

  8. java中的slave_java – Jenkins slave在构建过程中脱机

    jenkins奴隶在建设期间离线.我如何解决这个问题,我在SO和Jenkins问题上看到很多相关问题,但没有人解决. 我的配置: jenkins版1.651.1, Zuul版本2.1.1.dev393 ...

  9. 搭建(增加) jenkins slave 机器

    sonar-jenkins-slave 10.37.77.120/********* 这是其中集群中的一台slave,直接从这个slave机器上copy 安装的jdk,slave.jar等信息.用sh ...

最新文章

  1. 中国科学院院士梅宏:云计算这十年
  2. Python借助队列实现进程通信
  3. numpy(5)-astype
  4. android获取文件上级目录,Android 文件存储
  5. Material Design综合实例
  6. 教你消灭 Java 代码的“坏味道”
  7. 用户不在sudoers文件中,此事将被报告
  8. 什么是epoll的水平触发与边缘触发?两段代码彻底理解
  9. sql server死锁_如何解决SQL Server中的死锁
  10. linux 解压缩指令
  11. linux echo 当前时间,linuxecho
  12. Cplex的安装和使用实例
  13. HEVC SAO技术阅读
  14. h5(html5)+css3+移动端前端
  15. 如何在java中实现小数点自增_java保留小数的四种实现方法
  16. 静态单赋值(二)—gcc中的SSA化算法
  17. 两款程序员的好帮手——BitNami,Hoo WinTail
  18. sql中interval用法总结
  19. ajax提交验证非空,5.验证用户名是否已经被注册:AJAXC请求
  20. 学完计算机专业英语感受,计算机专业英语感想

热门文章

  1. Spring同一个类事务处理
  2. 【计算机组成原理】实验1:运算器
  3. 2019-9-2-自动机
  4. 写给在工厂上班的一封信
  5. Linux之代理服务器squid安装和使用
  6. Confluence和JIRA区别
  7. t420i升级固态硬盘提升_固态硬盘优化神器,一键提升固态硬盘性能和使用寿命...
  8. 高斯金字塔和拉普拉斯金字塔实现图像融合
  9. 计算波特率波特率的方法
  10. Kali安装中文输入法ibus