文章目录
Jenkins介绍
Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。
Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。
CI(Continuous integration持续集成)持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。
CD(Continuous Delivery持续交付) 是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中 。
安装
官方下载站:https://jenkins.io/zh/download/
国内镜像站:https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/
因为是java编写的所以需要安装jdk
[root@server2 ~]# yum install -y jdk-8u181-linux-x64.rpm
[root@server2 ~]# yum install -y jenkins-2.237-1.1.noarch.rpm
[root@server2 ~]# systemctl start jenkins #开启服务
访问
开启服务后,访问ip的8080端口
第一次访问会需要等待一段时间加载
初始登陆密码在这个文件里记录着:/var/lib/jenkins/secrets/initialAdminPassword
[root@server2 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
691381781e864453997cb4e1841a01d6
因为第一次登陆需要安装默认插件,而默认的安装路径在外网下载很慢而且很容易失败,所以修改为国内的插件源安装
[root@server2 ~]# vim /var/lib/jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
</site>
</sites>
当页面加载到这个状态时,先不要去输入密码,去将更新源更改完
使用sed批量更改,因为里面文件的内容台多了
[root@server2 ~]# cd /var/lib/jenkins/updates
[root@server2 updates]# sed -i.bak 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
[root@server2 updates]# sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
[root@server2 ~]# systemctl restart jenkins #重启服务
更改完后使用密码登陆去继续操作,在这个界面选择第一个推荐安装插件
在插件更新完后方可使用,更换了安装源明显会快很多
安装完插件,进入创建用户界面,这里使用管理员就可以,右下角有选择使用admin继续
然后的页面选择保存完成,开始jenkins即可进入jenkins。
如果想要更改密码,就在右上角小人图标点击进入,再选择Configure,就是设置admin的内容,里面有password可以去修改
建立项目
选择New item 新建项目
给你的项目起一个名字,选择Freestyle
下一步进行设置,这里在源码管理内容里,选择git添加
git仓库的路径可以使用上一篇博客里搭建的gitlab里的ssh克隆的链接添加进来,添加之后还是不可以连接的,是因为这里使用的链接方式是ssh,还需要添加ssh免密
在Credentials后面点击Add,选择Jenkins
里面的配置如下,kind类型选择ssh,username用的是root,然后去配置的git主机上将私钥粘贴过来,可以去链接gitlab,最后Add添加
出来后就可以选择root了,选择之前给server2主机里安装git命令,因为拉取都是需要git命令操作去gitlab上。
然后就可以看到没有报错了。
下来到Build Triggers构建触发器,选择使用Poll SCM轮询触发,也可以选择Build periodically定时任务。
Poll SCM里设置“* * * * *” 表示每分钟巡检一次,定义方式和定时任务设置方式一样
构建时,我们可以添加一个shell,让它执行一个任务
最后还有构建后执行的任务,可以根据需要进行设定,如发邮件通知等操作。
目前没有需要执行的操作,点击最后的save保存即可
完成后因为gitlab上有数据,可以看到第一抓取已经成功,可以选择控制台查看输出结果,看看具体的操作过程
使用容器方式构建
首先在jenkins主机里安装docker服务,可以使用阿里云开源镜像去安装docker-ce。
下来需要的操作就是,在通过git将dockerfile上传到gitlab上,由jenkins拉取过来通过插件自动部署到生产环境里。
安装jenkins里需要的docker插件
找到Manage Plugins,管理插件
在Available可选插件里搜索docker
里面有一款插件可以,满足我们自动构建镜像并能提取Dockerfile里执行的内容,勾选后在最下方选择Install without restart。
然后再回到我们建立的项目里,选择 Configure构建,删除之前执行的shell,重新添加Docker build Publish建立并推送
这里还需要一个docker仓库,需要搭建一个docker私有仓库,方法在docker的博客里有讲解
[root@server2 ~]# docker pull registry #下载仓库镜像
[root@server2 ~]# docker run -d -p 5000:5000 --name registry registry #运行私有仓库镜像
配置完私有仓库再去继续,里面的Docker Host URI后面写的路径,因为仓库和jenkins在同一台主机里,所以可以直接使用这个路径,要注意给docker.sock文件权限直接改为7777权限,因为实验环境不要顾虑太多
上传Dockerfile
配置完保存,再回到项目里,这时就需要我们去gitlab主机上去上传一个Dockerfile文件,文件里会写执行的命令
[root@server1 testgit]# vim Dockerfile #编写文件
FROM nginx #对于nginix
COPY index.html /usr/share/nginx/html/ #复制gitlab里的index.html文件放到nginx默认发布目录里
[root@server1 testgit]# cat index.html
www.redhat.com #index.html 的文件内容
[root@server1 testgit]# git add Dockerfile
[root@server1 testgit]# git commit -m "add Dockerfile"
[root@server1 testgit]# git push -u origin master #上传Dockerfile
在jenkins主机在docker里pull一个nginx镜像用来配合调用操作
因为前面设置的每分钟去检测一次,当我们将Dockerfile上传后就会自动去抓取过来,然后进行执行操作,如果你的nginx还没下载,就会导致执行失败。
可以在jenkins主页面里,看到显示项目的地方,最右边有个表一样的图标,点击就可以重新去执行,
执行成功会显示蓝色的圆豆,失败是红色
自动执行操作
在构建里刚才勾选了Skip Push跳过推送,现在前面的操作都没有问题了,取消勾选,来进行推送执行看结果
再去进行一次手动触发,可以看到jenkins里有触发里一次进程
[root@server2 ~]# curl localhost:5000/v2/_catalog #查看私有仓库,可以看到我们自己构建的镜像上传上来了
{"repositories":["nginxtest"]}
现在镜像也可以自动构建了,就需要在创建一个项目去运行我们构建的镜像
创建项目docker还是选Freestyle
构建里选择在test项目执行成功后在执行docker
在构建时,执行运行镜像的命令,因为时使用jenkins用户操作的,所以还需要对该用户进行权利下放
[root@server2 ~]# visudo #对jenkins用户进行权限提升
101 jenkins ALL=(ALL) NOPASSWD: ALL
因为test项目已经成功,创建完成后还是去执行手动触发docker
触发成功后去查看创建出来的容器的ip,并且去访问
[root@server2 ~]# docker inspect webserver | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
[root@server2 ~]# curl 172.17.0.3
www.redhat.com #成功访问到了
但是如果我们修改git里的index.html再去上传,docker就会报错
因为现在已经有了一个webserver,怎么能再创建一个同名呢
所以需要去修改以下docker项目的构建,先判定有没有webserver,有就删除,再创建,并且使它的端口映射到真机的80
保存构建设置
去更改index.html文件,重新去上传,jenkins会再去抓取更改的文件,test和docker再次执行
[root@server2 ~]# curl 172.25.254.2 #镜像启动成功,更改生效
www.redhat.com
www.redhat.com
www.redhat.com
jenkins自动构建docker镜像,并上传至harbor仓库
这里我们需要使用harbor仓库,所以使用另一台主机server3去搭建harbor,方法在harbor仓库部署有详细讲解
部署好harbor仓库之后,在我们jenkins的test项目里需要重新编写一下Configure。
进入test里的Configure,在最后的build设置里:
- Repository Name设置为harbor里library库里的自定义名称,因为启动harbor会自动生成一个公开的library项目,我们可以直接使用;
- Docker registry URL设置为https://reg.test.com,这是harbor构建时设置的hostname,非本机访问harbor都需要走https加密。所以需要在连接主机上配置证书,harbor博客里也有说明方法
- Registry credentials资格证书需要自行添加,点击Add,按照下图方法将harbor仓库用户名密码填入,因为没有设置其他用户,所以直接使用管理员来连接
还需要注意的一点是修改docker.sock权限,不然jenkins用户无法直接执行docker命令:在jenkins主机里执行
[root@server2 ~]# chmod 777 /var/run/docker.sock
手动触发jenkins推送
在harbor仓库里也就可以看到推送来的镜像了
gitlab自动触发jenkins
上面的测试我们是通过jenkens进行轮询检查去连接gitlab,但是这个时间是我们去设定的每分钟一次,因为是测试所以设置的这么频繁,正常的生产环境不会这么去消耗资源,这样就需要另一种方法,在jenkins里安装插件,是gitlab有更新使自动去触发jenkins,这样就相对方便了很多,只有在有需要的时候才会触发一次。
插件安装,还是找到插件管理界面
在里面可选插件里找到gitlab插件,直接安装
安装成功后,因为gitlab本身是不允许外发请求的,我们还需要在gitlab里打开外发请求,开启方式
第一步:点击上方的管理中心
第二步在左侧栏里选择用户设置里的网络,点击进入
第三步:展开外发请求,勾选允许Webhooks
第四步:回到项目里,在左侧栏里用户设置,选择Webhooks
在Webhooks里面可以看到需要URL和Secret Token
这两个内容会在jenkins里面找到,到jenkins项目里的Configure构建里的Build Triggers下,可以看到在安装完Gitlab插件后多了一条内容,“Build when a change is pushed to GitLab.。。。”
把它勾选,后面的URL
就是我们需要在gitlab里填写的:URL: http://172.25.254.2:8080/project/test
往下拉就可以看到Secret token,点击右边的Generate生成token,保存jenkins里的设置,把URL和Token复制到girlab里
并且在下面的Trigger触发事件里勾选需要可以触发的内容,常用的就是Push、Tag Push这些,勾选完在下方点击添加webhook
注意因为这里连接使用的方式是http所以我们需要取消勾选最后的Enable SSL verification,再添加就没问题了
第五步: 在girlab主机去更新提交内容,看jenkins会自动触发去拉取新的内容发送到harbor里
gitlab的主机server1
[root@server1 testgit]# vim index.html
bbs.redhat.com
bbs.redhat.com
bbs.redhat.com
[root@server1 testgit]# git commit -a -m "upadate index.html"
[root@server1 testgit]# git push -u origin master
jenkins主机server2,test项目进行了第12次构建
harbor仓库server3主机里,接收到了第12次的标签号,因为我们设置的标签号是根据构建号来变化的
这里还有一个问题就是,jenkins里的另一个项目在本机部署docker容器,没有执行成功
[root@server2 ~]# curl localhost
www.redhat.com
www.redhat.com
www.redhat.com
因为我们现在标签名是 reg.test.com/library/myweb,不是之前的标签了,所以我们还需要把它里面的Configure里的构建任务改一下
保存再去手动触发项目,然后就可以访问到最新的内容了
[root@server2 ~]# curl localhost
bbs.redhat.com
bbs.redhat.com
bbs.redhat.com
远程镜像构建
目前我最后部署的镜像都是jenkins本机上,如何去让交付的镜像去在其他主机上部署呢
再去使用一台server4主机,作为部署docker的主机,安装docker服务
在jenkins的test项目的配置里我们可以看到Docker Host URL设的是本地的
现在要让Jenkins使用tls方式连接docker构建主机
首先生成key和ca证书
[root@server4 ~]# openssl genrsa -aes256 -out ca-key.pem 4096 #生成key
Enter pass phrase for ca-key.pem: #需要设定一个ca-key
Verifying - Enter pass phrase for ca-key.pem:
生成ca证书
[root@server4 ~]# openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
生成server-key和csr文件
[root@server4 ~]# openssl genrsa -out server-key.pem 4096
[root@server4 ~]# openssl req -subj "/CN=server4" -sha256 -new -key server-key.pem -out server.csr
#这里的server4是这台docker主机的主机名
[root@server4 ~]# ls
ca-key.pem ca.pem server.csr server-key.pem
然后去使用ip地址方式进行tls连接
[root@server4 ~]# echo subjectAltName = DNS:server3,IP:172.25.254.4,IP:127.0.0.1 >> extfile.cnf
[root@server4 ~]# echo extendedKeyUsage = serverAuth >> extfile.cnf
[root@server4 ~]# openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
[root@server4 ~]# ls
ca-key.pem ca.pem ca.srl extfile.cnf server-cert.pem server.csr server-key.pem
我们生成完证书之后就需要给docker去安装证书,否则docker无法自动获取证书
[root@server4 ~]# cp ca.pem server-cert.pem server-key.pem /etc/docker/ #把证书放到指定路径里
[root@server4 ~]# cp /usr/lib/systemd/system/docker.service /etc/systemd/system/docker.service #复制一份docker的启动文件
[root@server4 ~]# vim /etc/systemd/system/docker.service #编辑文件,添加参数,开启tls校验,指定ca和key的位置,开启2376端口监听
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H tcp://0.0.0.0:2376
[root@server4 ~]# systemctl daemon-reload
[root@server4 ~]# systemctl restart docker
[root@server4 ~]# netstat -ntlp | grep 2376
tcp6 0 0 :::2376 :::* LISTEN 13846/dockerd
下来就需要给客户端key和证书
[root@server4 ~]# openssl genrsa -out key.pem 4096
[root@server4 ~]# openssl req -subj '/CN=client' -new -key key.pem -out client.csr
[root@server4 ~]# echo extendedKeyUsage = clientAuth > extfile.cnf
[root@server4 ~]# openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
[root@server4 ~]# ls
ca-key.pem ca.srl client.csr key.pem server.csr
ca.pem cert.pem extfile.cnf server-cert.pem server-key.pem
docker主机上证书建立完了,就需要去jenkins里面添加连接了
把Docker Host改为tcp的方式连接到172.25.254.4:2376端口
Server credentials点击Add添加,里面有三个内容需要复制进去
第一个: Client Key是key.pem里面的内容
第二个:Client Certificate是cert.pem里面的内容
第三个:Server CA Certificate是ca.pem里面的内容
Description描述自己随便写就可以
写完点Add添加,再去选择它就可以了,save保存
因为我们gitlab上传的内容是根据nginx镜像去发布的,server4现在没有任何镜像,所以可以server4里面配置镜像加速器,让它在需要时自行去下载
测试
前提需要给server4主机添加主机解析,并且我们的harbor是https加密的,所以需要给server4里面也创建证书才可以,简单的方法,把server2里的传输给server4里
[root@server3 docker]# scp -r /etc/docker/certs.d/ server4:/etc/docker/
然后开始在gitlab主机去推送内容
[root@server1 testgit]# cat index.html
bbs.test.com
bbs.test.com
bbs.test.com
[root@server1 testgit]# git commit -a -m "update"
[root@server1 testgit]# git push -u origin master
jenkins开始第15次构建 (因为我们做实验时有失败的出现,所以构建号和之前的跨度比较大)
docker主机收到了,标签15 的镜像,自动下载了nginx镜像
[root@server4 ~]# docker images
reg.test.com/library/myweb 15 6eb3c19b186c 8 minutes ago 132MB
reg.test.com/library/myweb latest 6eb3c19b186c 8 minutes ago 132MB
nginx latest 2622e6cca7eb 8 days ago 132MB
harbor里也收到了镜像包
这样的操作就成功了
Jenkins交付任务
ssh 方式交付任务
在jenkins里需要先去安装SSH插件
我们设计,最后交付到server4主机上,让它在server4上运行测试,如果内存多可以再去开启一台虚拟机去进行交付测试
安装完案件再去系统设置里添加ssh连接的主机
Credentials自己去添加一个可以连接server4主机的用户
最后的部署我们是使用jenkins里的docker项目操作的,所以还需要在docker项目里更改设置
删除之前的shell,选择通过ssh连接远端主机执行shell
docker ps -a | grep webserver && docker rm -f webserver
docker rmi myweb
docker run -d --name webserver -p 80:80 myweb
我们还需要给server4配置镜像地址,将官方的地址,改为自己的私有仓库地址,这样镜像拉取就是从harbor里去拉取的
[root@server4 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.test.com"]
}
[root@server4 ~]# systemctl restart docker
现在就可以手动触发了,去访问server4的ip就可以看到内容
也可以去gitlab主机去重新上传,全部自动执行一次
这样我们就完成了自动集成和自动交付