基于K8s和docker的Jenkins 可伸缩持续集成系统

3 篇文章 0 订阅
2 篇文章 0 订阅

概述

本文档主要介绍Jenkins的可伸缩部署方式,一种是基于Docker(或者docker-swarm 集群)的部署方式,另外一种是基于kubernetes的部署方式。

由于基于kubernetes也是基于docker的,都需要用到docker进行通信和中转,因此使用同一的slave镜像将大大节省平台开发与维护成本,因此需要引入jenkins的另一个大插件pipeline。Pipeline也是jenkins 2.0以后的主要方向和升级。

Jenkins系统基于docker的应用

jenkins介绍及传统部署遇到的问题

Jenkins 是开源的一套持续集成框架,可以进行大规模的编译、测试和发布的工作,给软件开发团队带来极大的便利性。

Jenkins 的持续集成环境可以是集群化的,主要的运行模式为master-slave模式。

Jenkins 的master为Jenkins系统的控制节点,slave节点负责具体的项目编译测试等工作。

由于大公司里面需要进行编译的工程或者对象非常庞大,因此需要大量的物理节点作为slave,而且这些环节相对固定,可能很难适应其他项目的编译测试,一旦salve节点遭到破坏,需要人为的进行修复甚至重建,非常麻烦。

Docker 来解决问题

Docker的问世,为我们提供了解决方案,使用docker作为jenkins slave节点可以解决slave节点遭到破坏后遇到的问题, 而且大量的工程不是每时每刻同时运行的因此可以在需要时吧docker拉起来进行编译测试,这样就节约了大量的物理节点, 解决了上述问题。

然而使用docker 同样需要集群,因此要用到集群管理工具, swarm 或者kubernetes。Swarm 一般用在小集群上,而且swarm和docker本身的借口完全一致, 因此这里就简单介绍单点docker节点作为slave。 Kubernetes作为大的docker 集群管理工具,当jenkins的工程数量非常大的时候可以用kubernetes, kubernetes的运维相对比docker 和swarm的门槛要高一点。

Jenkins master也可以使用docker来运行或者使用kubernetes来提供高可用的jenkins master。本文不对jenkins master的安装和docker运行做过多的说明。


kubernetes 管理Jenkins slave

Kubernetes 主要是用来进行docker 调度运行的,同样因为这一点通过kubernetes插件的配置,不需要管slave节点是否在线,因为kubernetes帮你负责创建和连接。这样就可以做到没有任务的时候没有任务slave节点在线,做到完全的按需启动slave和调度slave。

使用kubernetes 部署管理的jenkins slave如下:


Jenkins master 的部署

简单说明 jenkins master的安装与运行

1)       物理机上的安装

以centos为例:

yuminstall –y java java-devel

由于centos自己的yum源并没有包含jenkins因此需要添加jenkins对应的源

wget -O /etc/yum.repos.d/jenkins.repohttp://pkg.jenkins-ci.org/redhat-stable/jenkins.repo

rpm--import http://pkg.jenkins-ci.org/redhat-stable/jenkins-ci.org.key

yum install –y Jenkins

修改jenkins 的配置文件 /etc/sysconfig/jenkins

systemctl enable jenkins.service

systemctl start jenkins.service

2)       使用docker来运行

自己制作镜像或者网上下载jenkins_master的镜像。(我这里是下载的镜像)

dockerrun –idt –v /home/jenkins:/home/jenkins -v /home/data:/var/jenkins_home  -p8080:8080 -p 50000:50000 jenkins-master

这样既可。

     https://hub.docker.com/_/jenkins/  可以下载到jenkins master镜像


Jenkinsmaster配置和插件安装

jenkins 系统初始化

这里以jenkins master运行在docker 中为例

1)        这里每次全新的jenkins初始化的时候都会有一个任意的密码,路径在/var/jenkins_home/secrets/initialAdminPassword,按 照提示解锁jenkins:


2)   解锁后,系统会根据网络情况提示安装一些插件:



3)   安装过程如下:


安装完成后设置系统管理员账户和密码。

然后登陆即可使用。

Jenkins Docker 插件安装与kubernetes 插件安装

1)   插件更新中心配置:

    登陆jenkins-->系统管理-->插件管理-->高级

 

首先配置涉及站点,默认的是 官方的:http://updates.jenkins-ci.org/update-center.json

也可以配置日本的或者俄罗斯的 http://mirror.esuni.jp/jenkins/updates/update-center.json

http://mirror.yandex.ru/mirrors/jenkins/updates/update-center.json

配置完以后必须点右下角的立即获取

也可以在可选插件哪个页面的下面点击获取。

 

2) 安装需要的插件:

在可选插件页面勾选需要安装的插件,点击直接安装即可。

例如选择smartjenkins插件:

   

我们这里需要找的是kubernetes的插件和docker的插件进行安装,如果安装过程中有些插件安装失败,则手动下载插 件然后再高级里面选择上传插件进行安装:

   

直到安装完成所有需要的插件。

注:pipeline的插件在一开始初始化的时候安装完成了。


使用docker运行jenkins slave并连接到master 

Jenkins master 连接slave 有两种模式,一直是master主动发起连接,主要通过ssh 来进行连接,另外一种是slave 主动连接master,使用的jnlp协议。

我们使用docker来运行jenkins slave 都可以,但是要做到没有任务在编译测试的时候没有slave在线则只能通过 jnlp来进行连接而去必须使用kubernetes来调度。

我们这里讨论的是使用单独的或者几个slave长期在线,进行项目的编译测试,都是由master发起连接的。

https://hub.docker.com/u/jenkinsci/    slave镜像下载地址上


docker 运行jenkins slave (ssh 模式)

这种模式docker 运行一个slave 容器跟普通物理机使用完全一致,这里不做说明。

同样可以再在同一个slave节点(docker 容器)上绑定很多个工程或者任务。

docker 运行jenkins slave (jnlp 模式)

Jnlp 模式的则相对应用的比较少,jnlp 是由jenkins slave节点(物理节点,虚机或者容器均可)发起连接的, 会根据配置的jenkins master的url , Jenkins连接的token和jenkins slave name( lable)来进行进行连接。


举个例子:

登录jenkins-->系统管理-->节点管理-->新建节点

那么slave 进行运行连接的时候4个参数是:

1.        –url

2.        http://172.25.8.10:9080

	  3.   54cf091374806d8db7b9cd3977e23d080c955fa6fa33dd6c33dd594aa7b79350
	  4.   jnlp_test
	  command as : Jenkins-slave –url http://172.25.8.10:8090 54cf091374806d8db7b9cd3977e23d080c955fa6fa33dd6c33dd594aa7b79350 jnlp_test

之后的编译跟ssh 模式一模一样

如何做到方便高效已经保持少量的slave在线

上面介绍的这两种方式都是使用一个slave进行任务的编译测试,跟传统的部署方式对比仅仅只是增加了编译环境的数 量,但是每个编译环境跟物理机基本一致。


而且由于docker 环境需要进行调试和连接master,也比较麻烦,作为代码开发者一般只管理工程代码怎样编译,可能 根本不懂jenkins,怎么办?


大量的jenkins-slave(dokcer)在线jenkinsmaster的管理效率低下,而且可能由于slave(docker)在线,某些任务的编 译资源被挤占,编译效率下降,怎么办?

 

这些问题的解决办法是使用docker in docker 来处理。

每个物理节点上长时间的只有一个jenkins-slave(进程或者docker容器都行,最好是容器—无状态,可重新来,降低运 维成本),所有的任务绑定到这几个slave上,每个任务的编译过程是启动自己的容器——下载代码——编译——测试等。


把编译过程写成脚本:

docker pull

docker run

docker exec *** git clone

docker exec build

***

那么什么是docker in docker

 

使用docker in docker 来进行CI 

Dockerin docker 就是在docker中运行docker, 单实质上是将host的docker.sock 挂载到容器中,然后再容器中创建的容器,其实是运行在host机器上呢。

使用docker in docker 来进行CI

Docker in docker其实就是让一个物理机上只有一个jenkins slave在运行,这个jenkinsslave 仅仅只负责任务转发,相当于是一个标准接口, 这样开发人员只需要知道自己的软件需要什么样的docker环境进行编译,而不用关注这个docker 容器怎样跟jenkins master连接。

这时候 Jenkins slave的运行如下:

docker run -it -u root -v /var/run/docker.sock:/var/run/docker.sock my_jnlp_test:0.1  -url http://172.25.8.10:9080 54cf091374806d8db7b9cd3977e23d080c955fa6fa33dd6c33dd594aa7b79350 jnlp_test

项目配置跟原来一样。

同样带来一些问题,例如 docker 脚本的编写,docker状况的监控,编译构建结果的查看与测试等等。

Docker 插件和pipeline 插件帮你搞定这些。

pipeline 来解决docker in docker带来的问题

Pipeline是jenkins 2.0 的主要升级。其主要是用来定义工作流的,这里结合docker来更好管理docker in docker 的编译。

同样对于多个依赖关系的任务进行更好的CI 管理,同时其stage view 更直观的反应CI运行的状况。

Pipeline工程的创建和配置:

Jenkins-->新建-->需要选择pipeline


项目配置中仅仅需要配置pipeline部分


写一段pipeline script 就可以进行构建了

node('jnlp_test1'){

    stage "Container Prep"

    docker.image('my_docker:0.1').inside{

        stage 'Checkout'

        git url:'http://101.71.10.3:15480/chenmiao/dhcAPI.git'

        stage 'Build'

        sh "mvn clean package"

    }

}

Node 用来制定在哪一个slave节点上进行构建

Stage 用来给任务分段

这些具体的得看自己学习啦,我这里也是简单的一个例子。

编译的效果如下:


比较清晰的显示出每一个阶段用了多长时间,哪个阶段失败了。

这个到目前为止解决了基于固定的物理服务器,尽可能少的在线编译问题,但不能解决占用冲突—即可能1000个任务中只有20个在线,但这20个在线的任务是同一个物理服务器上的,结果是编译依旧非常低效。

kubernetes进行按需创建slave

kubernetes 的引入是为了高效平衡的对docker进行调度,可以有效解决上述的问题。

Jenkins环境上kubernetes的配置:

登录Jenkins-->系统管理-->系统设置:

搜索“云” -->增加一个云-->kubernetes


然后配置kubernetes:

这里必配项有:Name、Kubernetes URL、kubernetesNamespace、 Jenkins URL 以及 Kubernetes Pod Template(大项,这一项最少需要一个,否则不能使用kubernetes)


再来配置jenkins-slave 对应的docker的信息,由于kubernetes是报docker封装成Pod来管理,即配置kubernetes Pod Template:


这里需要名却的是第一处的Name  就是子啊项目配置时的slave节点,label 是kubernetes进行管理用的。其余的配置项为slave容器需要的配置。

Jenkins ci工程的配置

Pipeline Test1 for example:


这里只需要指定node为kubernetes Pod配置的哪个名字即可。

自由风格的工程配置一样:


这样既可以在对应的docker 里面进行项目CI。

在没有任务运行的时候,系统上是没有slave的:


Kubernetes get pod的结果也一样没有jnlp-slave的Pod

root@debian:/home/Daniel/jnlp_slave# kubectl -s 172.25.5.150:8080 get pod --all-namespaces -o wide

NAMESPACE     NAME                                   READY     STATUS    RESTARTS   AGE       NODE

default       kube-apiserver-172.25.5.150            1/1       Running   3          14d       172.25.5.150

default       kube-controller-manager-172.25.5.150   1/1       Running   0          14d       172.25.5.150

default       kube-scheduler-172.25.5.150            1/1       Running   0          14d       172.25.5.150

kube-system   kube-ui-v1-1dn43                       1/1       Running   0          10d       172.25.5.155

运行任务时:


Kubernetes got pod 中有jnlp-slave 的pod

root@debian:/home/Daniel/jnlp_slave# kubectl -s 172.25.5.150:8080 get pod --all-namespaces -o wide

NAMESPACE     NAME                                   READY     STATUS    RESTARTS   AGE       NODE

default       kube-apiserver-172.25.5.150            1/1       Running   3          14d       172.25.5.150

default       kube-controller-manager-172.25.5.150   1/1       Running   0          14d       172.25.5.150

default       kube-scheduler-172.25.5.150            1/1       Running   0          14d       172.25.5.150

jenkins       jnlp-slave-4eeed2fbc128e               0/1       Running   0          3s        172.25.5.155

kube-system   kube-ui-v1-1dn43                       1/1       Running   0          10d       172.25.5.155

问题记录

1. 我们使用的kubernetes版本不支持Pod name 和lable中使用下划线,因此前期Pod一直创建不成功。

2. Kubernetes Pod template 中Container的配置项 Commandto run slave agent 以及Arguments topass to the command配置一直有错误:Command 最好使用全路径, Arguments 最好用括号


3. Jenkins master 和jenkins slave 运行的时候需要挂载卷,这些卷如果是host上的目录需要将其的所有者改为jenkins 里面运行的用户,而且容器里面的卷也需要修改其所有者。

chown Jenkins:Jenkins/home/Jenkins   为例

4. Jenkins maste 和jenkins slav镜像需要进行定制,网上下载的镜像仅保证最简单的连接。



  • 13
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值