4. Jenkins+Gitlab+Docker联动
Jenkins+Gitlab+Docker联动
Jenkins 流水线 (Pipeline) 是一套插件,它支持实现和集成 continuous delivery pipelines 到Jenkins。
流水线提供了一组可扩展的工具,通过 Pipeline domain-specific language (DSL) syntax. 对从简单到复杂的交付流水线 “作为代码” 进行建模。
对Jenkins 流水线的定义被写在一个文本文件中(成为Jenkinsfile),该文件可以被提交到项目的源代码的控制仓库。这是"流水线即代码"的基础; 将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。 创建 Jenkinsfile
并提交它到源代码控制中提供了一些即时的好处:
- 自动地为所有分支创建流水线构建过程并拉取请求;
- 在流水线上代码复查/迭代 (以及剩余的源代码);
- 对流水线进行审计跟踪;
- 该流水线的真正的源代码, 可以被项目的多个成员查看和编辑。
定义流水线的语法, 无论是在 web UI 还是在 Jenkinsfile 中都是相同的, 通常认为在Jenkinsfile
中定义并检查源代码控制是最佳实践。
下面的流程图是一个 CD 场景的示例,在Jenkins中很容易对该场景进行建模:
一. Pipeline语法
流水线是用户定义的一个CD流水线模型。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段
流水线的语法有两种:
- 声明式
- 脚本化
1.1 声明式流水线基础
在声明式流水线语法中, pipeline 块定义了整个流水线中完成的所有的工作。
- 在任何可用的代理上,执行流水线或它的任何阶段。
- 定义 “Build” 阶段。
- 执行与 “Build” 阶段相关的步骤。
- 定义"Test" 阶段。
- 执行与"Test" 阶段相关的步骤。
- 定义 “Deploy” 阶段。
- 执行与 “Deploy” 阶段相关的步骤。
1.2 脚本化流水线基础
在脚本化流水线语法中, 一个或多个 node 块在整个流水线中执行核心工作。
- 在任何可用的代理上,执行流水线或它的任何阶段。
- 定义 “Build” 阶段。 stage 块在脚本化流水线语法中是可选的。 然而, 在脚本化流水线中实现 stage 块 ,可以清楚的显示Jenkins UI中的每个 stage 的任务子集。
- 执行与 “Build” 阶段相关的步骤。
- 定义 “Test” 阶段。
- 执行与 “Test” 阶段相关的步骤。
- 定义 “Deploy” 阶段。
- 执行与 “Deploy” 阶段相关的步骤。
二. 实验案例
需求:
- Jenkins从gitlab仓库拉取代码及Jenkinsfile文件
- Jenkins通过代码中的Dockerfile构建docker镜像
- Jenkins将构建的docker镜像上传到私有docker仓库
- Jenkins控制部署主机从私有仓库拉取新创建的docker镜像,启动docker容器
实验环境
角色 | 主机地址 | 软件 |
---|---|---|
gitlab | 192.168.154.50:8080 | gitlab 12.8.1 |
jenkins | 192.168.154.60:8080 | jenkins 2.204.3 |
docker registry | 192.168.154.50:5000 | v2 |
deploy host | 192.168.154.50 | docker-ce 19.03.6 |
2.1 基本环境部署
- 关闭主机SElinux
- 配置静态IP
- 安装docker-ce环境
2.2 服务器部署
- 192.168.154.50 上使用docker安装gitlab
[root@git ~]# docker run -d -p 2222:22 -p 8080:80 -p 8443:443 \
> --volume /home/gitlab/config:/etc/gitlab \
> --volume /home/gitlab/logs:/var/log/gitlab \
> --volume /home/gitlab/data:/var/opt/gitlab \
> --restart always \
> --name gitlab \
> gitlab/gitlab-ce
- 192.168.154.50 上部署官方使用仓库registry
[root@git ~]# docker run -d -p 5000:5000 --restart always --privileged \
> -v /opt/registry:/var/lib/registry \
> --name registry-server registry:latest
- 192.168.154.50 上防护墙要放行相应端口
[root@git python-dev]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens32
sources:
services: dhcpv6-client ssh
ports: 8443/tcp 2222/tcp 8080/tcp 5000/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
- 192.168.154.60 上使用docker安装Jenkins
[root@jenkins ~]# docker run -d -u root --restart always \
> -p 8080:8080 -p 50000:50000 \
> -v jenkins-data:/var/jenkins_home \
> -v /var/run/docker.sock:/var/run/docker.sock \
> --privileged \
> --name jenkins-server \
> jenkinsci/blueocean:1.22.0
##防火墙放行端口
[root@jenkins ~]# firewall-cmd --add-port=8080/tcp --permanent
[root@jenkins ~]# firewall-cmd --add-port=50000/tcp --permanent
[root@jenkins ~]# firewall-cmd --reload
success
2.3 实施步骤
2.3.1 gitlab上创建项目
创建项目python-dev,属于development组,并建立develop分支。
开发人员将代码上传到仓库
Pipeline的Jenkinsfile文件内容: 这是关键
[root@git python-dev]# vim Jenkinsfile
node {
stage('Build') {
checkout scm
docker.withRegistry('http://192.168.154.50:5000') {
def customImage = docker.build("liyi888/lamp:latest", "./lamp")
customImage.push()
}
}
stage('depoly') {
sh '''
ssh root@192.168.154.50 'docker stop web | true'
ssh root@192.168.154.50 'docker rm web -f | true'
ssh root@192.168.154.50 'docker rmi 192.168.154.50:5000/liyi888/lamp:latest -f | true'
ssh root@192.168.154.50 'docker pull 192.168.154.50:5000/liyi888/lamp:latest | true'
ssh root@192.168.154.50 'docker run -itd --name web -p 32768:80 192.168.154.50:5000/liyi888/lamp:latest'
'''
}
}
lamp目录中存放Dockerfile文件等
[root@git python-dev]# tree -C lamp/
lamp/
├── CentOS-Base.repo
├── Dockerfile
├── epel.repo
├── index.html
└── run.sh
0 directories, 5 files
Dockerfile文件内容:
FROM centos:7.7.1908
MAINTAINER liyi888
RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
RUN rpm -ivh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm --force
ADD CentOS-Base.repo /etc/yum.repos.d/
ADD epel.repo /etc/yum.repos.d/
RUN yum install -y httpd httpd-devel
RUN yum install -y php70w php70w-mysql php70w-mbstring php70w-mcrypt php70w-gd php70w-imap
RUN yum install -y php70w-ldap php70w-odbc php70w-pear php70w-xml php70w-xmlrpc php70w-pdo
RUN sed -ri 's/#ServerName www.example.com:80/ServerName www.cloud.com/g' /etc/httpd/conf/httpd.conf
ADD index.html /var/www/html/
ADD run.sh /run.sh
RUN chmod 775 /run.sh
EXPOSE 80
CMD ["/run.sh"]
CentOS-Base.repo和epel.repo是两个YUM源文件
[root@git lamp]# cat CentOS-Base.repo
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
[root@git lamp]# cat epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://mirrors.aliyun.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
index.html是默认首页内容
[root@git lamp]# cat index.html
<h1>this is docker test!</h1>
run.sh是镜像默认启动脚本
[root@git lamp]# cat run.sh
#!/bin/sh
/usr/sbin/httpd -D DFOREGROUND
/bin/bash
2.3.2 Jenkins上创建流水线
新建任务–> 选择多分支流水线–>确定
2.3.3 配置python-dev流水线
配置分支源
配置构建配置及触发器
2.3.4 配置SSH 部署主机
首选在jenkins上通过ssh-keygen
命令生成一对秘钥(我这里用的root用户)
然后将公钥通过ssh-copy-id将公钥拷贝到部署主机,务必能免密登录到192.168.154.50。
ssh-copy-id -i ./.ssh/id_rsa.pub root@192.168.154.50
添加全局凭证
添加SSH remote hosts
2.3.5 配置私有仓库客户端
Jenkins主机和部署主机均要配置信任私有仓库
[root@jenkins ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://ariq8b1p.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.154.50:5000"]
}
2.3.6 测试
- 更新仓库代码,比如更新index.html文件的内容;
- Jenkins在轮训间隔到期后,自会自动构建,并按照Jenkinsfile的流水线执行
[root@jenkins ~]# docker exec -it jenkins-server /bin/bash
bash-4.4# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.154.50:5000/liyi888/lamp latest 1c7459020de0 19 minutes ago 670MB
liyi888/lamp latest 1c7459020de0 19 minutes ago 670MB
192.168.154.50:5000/liyi888/lamp <none> 3c7a9de58917 22 minutes ago 670MB
192.168.154.50:5000/liyi888/lamp <none> cc79ccb4392b About an hour ago 670MB
192.168.154.50:5000/liyi888/lamp <none> 3566e3245712 5 hours ago 670MB
nginx latest 6678c7c2e56c 3 days ago 127MB
jenkinsci/blueocean latest cabaf2e16a90 7 days ago 561MB
centos latest 470671670cac 7 weeks ago 237MB
centos 7.7.1908 08d05d1d5859 3 months ago 204MB
python 3.5.1 a00e9008965a 3 years ago 698MB
- 部署主机上已经下载了刚构建的镜像
[root@git ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.154.50:5000/liyi888/lamp latest 1c7459020de0 21 minutes ago 670MB
192.168.154.50:5000/liyi888/lamp 8.0 6cd83ae41c41 8 hours ago 670MB
gitlab/gitlab-ce latest 719e7e45b1e2 12 days ago 1.89GB
192.168.154.50:5000/registry latest 708bc6af7e5e 6 weeks ago 25.8MB
registry latest 708bc6af7e5e 6 weeks ago 25.8MB
centos 7.7.1908 08d05d1d5859 3 months ago 204MB
- 部署主机上也已经启动了容器
[root@git ~]# docker ps
[root@git ~]# docker port web
80/tcp -> 0.0.0.0:32768
- 浏览器访问web容器
2.3.7 配置代码更新自动触发
上面的配置的触发器为间隔轮训,如果不想使用这种方式,就要配置webHOOK。
在gitlab上的仓库上配置即可,格式如下:
http://my-jenkins-host/git/notifyCommit?url=git@gitlab.example.com:group/repository.git&delay=0sec
##my-jenkins-host:Jenkins主机地址及端口
##git@gitlab.example.com:group/repository.git 这个是你Jenkins流水线上的仓库地址
2.3.8 更新代码自会自动触发构建
##进入本地代码仓库
[root@git python-dev]# pwd
/root/administrator-pro/python-dev
[root@git python-dev]# ls
jenkins Jenkinsfile lamp new.py README
[root@git python-dev]# cd lamp/
[root@git lamp]# ls
CentOS-Base.repo Dockerfile epel.repo index.html run.sh
##修改index.html文件内容并提交到gitlab代码仓库
[root@git lamp]# cat index.html
<h1>this is docker test!</h1>
<h1>this is docker test!</h1>
<h1>this is docker test!</h1>
[root@git lamp]# cd ..
[root@git python-dev]# git add .
[root@git python-dev]# git commit -m 'auto push'
[develop 38d9cc0] auto push
1 file changed, 2 insertions(+)
[root@git python-dev]# git push origin develop
Username for 'http://192.168.154.50:8080': root
Password for 'http://root@192.168.154.50:8080':
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 346 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote: http://192.168.154.50:8080/development/python-dev/-/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To http://192.168.154.50:8080/development/python-dev.git
0fe433a..38d9cc0 develop -> develop
[root@git python-dev]#
Jenkins上的流水线python-dev会自动构建。
[[6.Docker基础]] [[1. Git分布式版本控制]] [[3. Jenkins持续集成]]
- 原文作者:老鱼干🦈
- 原文链接://www.tinyfish.top:80/post/%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6%E5%92%8C%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/4.-Jenkins+Gitlab+Docker%E8%81%94%E5%8A%A8/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。