CI-CD 解决的是代码从生产到线上的一个距离的问题,有效的管控中间的流程。也是开发和运维之间的问题。
我们在开启一台server2主机作为jenkins服务器.
它需要jdk的支持:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/
在这里下载
[root@server2 ~]# rpm -ivh jdk-8u171-linux-x64.rpm
[root@server2 ~]# rpm -ivh jenkins-2.237-1.1.noarch.rpm
# 它在下载的时候会自动的从外网下载软件包。
[root@server2 ~]# systemctl start jenkins
[root@server2 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3019/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3140/master
tcp6 0 0 :::8080 :::* LISTEN 3315/java
tcp6 0 0 :::22 :::* LISTEN 3019/sshd
tcp6 0 0 ::1:25 :::* LISTEN 3140/master
# 启动服务会打开8080端口
访问:
它需要admin用户的一个密码,在/var/lib/jenkins/secrets/initialAdminPassword
[root@server2 ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
e5687fa1f9544d13a1e61de6e0ea2518
它接下来会去安装一些插件,我们更改它的插件源,让他更快一些:
[root@server2 ~]# cat /var/lib/jenkins/hudson.model.UpdateCenter.xml
default
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
# 换成清华大学下载站的会快很多
[root@server2 updates]# cd /var/lib/jenkins/
[root@server2 jenkins]# ls
updates # 这时就会生成一个更新目录,里面
[root@server2 jenkins]# ls
config.xml jenkins.telemetry.Correlator.xml nodes secrets
hudson.model.UpdateCenter.xml jobs plugins updates
identity.key.enc logs secret.key userContent
jenkins.install.UpgradeWizard.state nodeMonitors.xml secret.key.not-so-secret users
[root@server2 jenkins]# cd updates/ && ls
default.json hudson.tasks.Maven.MavenInstaller
# default.json 这个文件记录了插件的下载路径,我们还要去这里面更改
[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 updates]# systemctl restart jenkins.service
安装推荐的插件。
推荐安装了这些,我们还可以手动往里面添加。
它让我们创建管理员,我们直接使用右下角的admin就可以
就可以了。
点击右上角用户,点击设置,更改密码。
我们可以去插件管理那里下载locale 和Localization: Chinese (Simplified) 这两个插件来支持中文。
我们现在新建一个任务:
企业中大多用的都是流水线风格的.
首先在源码管理这里我们添加上gitlab的ssh链接地址,由于需要认证,所以我们将server1上的私钥复制下来粘上去,因为我们在gitlab上传的是公钥,需要私钥与其对应:
这时还无法链接仓库,是因为我们的server2主机上的jenkins要通过git命令去链接gitlab仓库,所以我们需要在server2上也安装git。
[root@server2 jenkins]# yum install -y git
这时就没有报错了。
然后我们使用轮询的方式构建触发器。
构建一条shell命令测试一下。
一分钟后,
任务执行了。
在控制台中可以看见用git命令将gitlab仓库克隆到了 /var/lib/jinkens/workspace/ 下,并执行了ls -l 命令。 /var/lib/jinkens/workspace/ 是jenkins的工作目录。
[root@server2 workspace]# cd /var/lib/jenkins/workspace/demo
[root@server2 demo]# ls
index.html README.md
在server2上安装docker。
docker-ce-19.03.8-3.el7.x86_64
docker-ce-cli-19.03.8-3.el7.x86_64
[root@server2 ~]# systemctl start docker.service
[root@server2 ~]# docker info
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled # 这两个模块是关闭的
[root@server2 ~]# sysctl -a | grep bridge-nf-call
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
我们去打开:
[root@server2 ~]# vim /etc/sysctl.d/bridge.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@server2 ~]# sysctl --system # 使其生效
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@server2 ~]# docker pull nginx # 拉取一个镜像
[root@server2 ~]# docker run -d --name web nginx
821e91cf33ac9e6704858597378d53f782e02a923d4e852a2af1a99bf5b6145e
[root@server2 ~]# curl 172.17.0.2
Welcome to nginx! # 可以运行
这样我们就可以让jinkens去自动构建镜像了。
git --> dockerfile --> gitlab --> jenkins --> plugins --> images build --> harbor
具体的流程如上,开发人员通过 git 将 dockerfile 上传到 gitlab 仓库,然后jenkins 从 gitlab 抓取,通过docker的功能插件来完成docker镜像的构建,然后还可以把镜像推送到 docker 的 harbor 仓库中。整个过程没有人工的干预。
root@server1 demo]# vim Dockerfie
FROM nginx
COPY index.html /usr/share/nginx/html
# 将当前目录下的index.html 放到容器的发布目录中
[root@server1 demo]# cat index.html
www.caoaoyuan.org
[root@server1 demo]# git add dockerfie
[root@server1 demo]# git commit -m "add Dockerfile"
[root@server1 demo]# git push -u origin master # 推送到gitlab
jenkins 已经自动构建了,构建号是2,这是单调递增的。
[root@server2 demo]# ls
Dockerfie index.html README.md #有了
此时新容器还没有进行构建,因为我们还没有安装插件:
安装这个插件,它下面可以看到它会根据dockerfile构建镜像,并推送到docker仓库中去。
然后我们在demo在这个项目的配置中就有了这个参数:
docker的构建和发布,这是我们就需要一个仓库了,我们先搭建一个:
[root@server2 demo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 2622e6cca7eb 5 days ago 132MB
registry 2 708bc6af7e5e 4 months ago 25.8MB
[root@server2 demo]# docker run -d --name registry -p 5000:5000 registry:2
3bf873cb1234a494a213d1f451464fe9180c581057798fdf4a02a38b95c2bbbd
doc[root@server2 demo]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bf873cb1234 registry:2 "/entrypoint.sh /etc…" 3 seconds ago Up 1 second 0.0.0.0:5000->5000/tcp registry # 已经在运行了
#我们获取一个测试镜像。
[root@server2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 2622e6cca7eb 5 days ago 132MB
registry 2 708bc6af7e5e 4 months ago 25.8MB
ikubernetes/myapp v1 d4a5e0eaa84f 2 years ago 15.5MB
ikubernetes/myapp v2 54202d3f0f35 2 years ago 15.5MB
[root@server2 ~]# docker tag ikubernetes/myapp:v1 localhost:5000/myapp:v1
[root@server2 ~]# docker push localhost:5000/myapp
[root@server2 ~]# curl localhost:5000/v2/_catalog
{"repositories":["myapp"]} # 传上去了,仓库可用
接着去配置:
标签名为构建号,就是 #1 #2.docker主机是套接字文件,仓库地址是,本地的5000端口。关掉强行拉取,因为我们本地已经有nginx的缓存了。点开跳过推送,分开进行。
修改docker.sock权限,不然jenkins无法直接执行docker命令:
root@server2 run]# chmod 777 /etc/run/docker.sock
[root@server2 demo]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost:5000/myweb 4 8579df46fc59 About a minute ago 132MB
localhost:5000/myweb 5 8579df46fc59 About a minute ago 132MB
localhost:5000/myweb latest 8579df46fc59 About a minute ago 132MB
nginx latest 2622e6cca7eb 5 days ago 132MB
registry 2 708bc6af7e5e 4 months ago 25.8MB
ikubernetes/myapp v1 d4a5e0eaa84f 2 years ago 15.5MB
localhost:5000/myapp v1 d4a5e0eaa84f 2 years ago 15.5MB
ikubernetes/myapp v2 54202d3f0f35 2 years ago 15.5MB
4 和5 都是我刚才触发的,直接就构建好了,现在我们关闭刚才打开的skip Push,让它上传到仓库中去。
[root@server1 demo]# vim index.html
www.caoaoyuan.org
www.hhhhhhh.org # 我们把这个文件改成这样子
www.hhhhhhh.org
[root@server1 demo]# git add index.html
[root@server1 demo]# git commit index.html -m "update index"
[root@server1 demo]# git push -u origin master # 传到gitlab
[root@server2 demo]# curl localhost:5000/v2/_catalog
{"repositories":["myapp","myweb"]}
# 并且自动的上传到了仓库中
我们测试构建的这个镜像有没有问题:
现在server2上给jenkins 加上sudo 权力下放.
[root@server2 demo]# visudo
jenkins ALL=(ALL) NOPASSWD: ALL
然后再web界面新建一个项目。
选择demo项目构建以后再触发。
让他运行我们刚才构建的容器,不加TAG的话始终使用最新的。
手动触发一次。
[root@server2 demo]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aae25a3115aa localhost:5000/myweb "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp webserver
3bf873cb1234 registry:2 "/entrypoint.sh /etc…" About an hour ago Up About an hour 0.0.0.0:5000->5000/tcp registry
[root@server2 demo]# docker inspect webserve
"IPAddress": "172.17.0.3",
[root@server2 demo]# curl 172.17.0.3
www.caoaoyuan.org
www.hhhhhhh.org
www.hhhhhhh.org # 是我们改过的内容。
但是下次运行的话就不行了,因为webserver这个容器名只能有一个,我们更改一下
每次运行前进行判断,有就删除。
在手动触发一次。
可以看出先删除了以前的容器,再重新运行了。
我们在最后做一次自动触发:再server1上进行更改
[root@server1 demo]# vim index.html
[root@server1 demo]# cat index.html
www.caoaoyuan.ooooo
www.hhhhhhh.ooooo # 改动文件内容
www.hhhhhhh.ooooo
[root@server1 demo]# git commit -a -m "update index v2"
[master 3540479] update index v2
1 file changed, 3 insertions(+), 3 deletions(-)
[root@server1 demo]# git push -u origin master #推送
gitlab就直接更新了。
jenkins也自动进行了构建。
[root@server2 demo]# curl localhost
www.caoaoyuan.ooooo
www.hhhhhhh.ooooo
www.hhhhhhh.ooooo
server2上就可以直接访问到了。
我们只改变了代码,然后接下来的代码的提交,镜像的构建和交付就完全自动化了。这就是持续集成与持续交付。