使用Docker实现CI/CD、Docker + Gitlab +Jenkins实现CI/CD
本文详细介绍了如何在Docker容器中使用gitlab以及jenkins实现CI/CD。首先从CI/CD的概念开始介绍,然后详细讲述了gitlab的搭建以及配置,然后讲述了jenkins的搭建配置,最后再使用一个go程序进行了相应的演示。
CI/CD
CI/CD包含这几个含义:
- CI 持续集成(Continuous Integration)
- CD 持续交付(Continuous Delivery)
- CD 持续交付(Continuous Delivery)
整个过程可以简单的如下图所示。当程序发生变更时,开发者只需要推送代码到git仓库,后续编译构建,部署到生产服务器的一系列动作全交给CI/CD这个自动化流程来完成。听起来是不是很爽。
准备
话不多说,如下,我将介绍如何使用Gitlab + jenkins + Docker来实现CI/CD。
我使用了三台服务器:
-
一台是百度云的服务器,下面演示的时候,我会遮蔽其IP地址,用A.A.A.A来表示其IP地址。配置:2h 4g。用来部署gitlab。需要注意的是,在容器中运行gitlab,服务器的运行内存最好是2g以上,官方给的建议也是2g,如果小于2g,整个服务器的内存会被gitlab给占满,连xshell也无法登录连接。
-
一台是阿里云的服务器,下面演示的时候,我会遮蔽其IP地址,用B.B.B.B来表示其IP地址。配置:2h 2g。用来部署jenkins,jenkins不是很占运行内存,2h 2g也足够了。
-
一台是ucloud的服务器,下面演示的时候,我会遮蔽其IP地址,用C.C.C.C来表示其IP地址。配置:2h 2g。用来部署程序。
服务器操作系统全是Centos 8。我使用xshell连接各台服务器。百度云的那台服务器,我使用了其8080端口,阿里云的那台服务器,我使用了8888端口,ucloud那台服务器,我使用了8090端口。因此还要开启对应端口的防火墙,不然无法访问 !!!
如果是首次购买服务器,价格都还挺便宜的,所以每家厂商都买了些。
演示用的程序是一个go程序,相当于是一个http server。当在浏览器端发起 http:\\服务器ip:8090\hello 请求时,浏览器界面会返回一个hello
代码如下:
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "hello\n")
}
func headers(w http.ResponseWriter, req *http.Request) {
for name, headers := range req.Header {
for _, h := range headers {
fmt.Fprintf(w, "%v: %v\n", name, h)
}
}
}
func main() {
http.HandleFunc("/hello", hello)
http.HandleFunc("/headers", headers)
http.ListenAndServe(":8090", nil)
}
整个工程的结构如下:
详细请参见gitee仓库:Gitee代码仓库地址
安装Gitlab并进行相应配置
我在百度云的服务器上运行Gitlab的Docker镜像,百度云服务器公网IP地址用A.A.A.A来表示。
首先是在服务器上安装Docker,至于安装的步骤可以参考我的另一篇文章:初识Docker
1. 下载并运行Gitlab镜像
docker run -d \
--hostname localhost \
-p 8080:80 -p 2222:22 \
--name gitlab \
--restart always \
--volume /tmp/gitlab/config:/etc/gitlab \
--volume /tmp/gitlab/logs:/var/log/gitlab \
--volume /tmp/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:13.3.8-ce.0
2. 登录gitlab
当gitlab镜像成功运行起来以后,可以使用docker ps命令进行查看,确认已经成功运行了就可以开始访问了。
由于我用的是百度云的那台服务器来部署gitlab,所以ip地址也就是我那台百度云服务器的公网ip地址。
第一次登陆,GitLab 会要求我们设置管理员密码,我们输入管理员密码后点击确认即可,之后 GitLab 会自动跳转到登录页面。默认的管理员用户名:admin@example.com
,密码为我们第一次登录时设置的密码。输入用户名和用户密码,点击登录即可登录到系统中
3. 配置SSH
在百度云的那台服务器上执行如下命令生成SSH的公私玥。email@example.com
可以替换为自己的邮箱
ssh-keygen -o -t rsa -b 2048 -C "email@example.com"
执行成功以后,会在当前路径下生成一个 .ssh 文件夹,里面有自己的公私玥。我是以 root 用户登录的服务器,生成的 .ssh 文件夹则会放在 /root/ 这个目录下。
进入 .ssh 这个文件夹,复制 id_rsa.pub 这个文件中的内容,也就是图中的那一大段内容。如果不了解公私玥这个概念,可以去了解一下非对称加密。
在 SSH keys 中粘贴刚才复制的公钥。
为了避免有时候出现使用SSH clone代码时出现没有权限的提示,还需要进行如下配置:
- 步骤1:编辑 /etc/gitlab/gitlab.rb 文件
进入gitlab容器。
[root@baidu-host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4465da3e97e8 gitlab/gitlab-ce:13.3.8-ce.0 "/assets/wrapper" 41 hours ago Up 41 hours (healthy) 443/tcp, 0.0.0.0:2222->22/tcp, 0.0.0.0:8080->80/tcp gitlab
[root@baidu-host ~]# docker exec -it gitlab /bin/bash
root@localhost:/# vim /etc/gitlab/gitlab.rb
在 /etc/gitlab/gitlab.rb 文件中输入如下内容:
A.A.A.A 对应我的百度云服务器的ip地址
gitlab_rails['gitlab_shell_ssh_port'] = 2222
external_url 'http://A.A.A.A'
- 步骤2:编辑*/etc/gitlab/gitlab.rb*文件
root@localhost:/# vim /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
查看配置文件中的host名字是否为在运行docker时配置的主机名,如果不是则进行修改。
修改ssh_port为2222
- 步骤三:在容器内部进行重启
root@localhost:/# cd /bin/
root@localhost:/# gitlab-ctl restart
然后刷新下浏览器就可以了。
4. 创建一个工程
5. 推送代码到gitlab仓库
在百度云的那台服务器上新建了一个文件夹,用来存放代码。编写的代码就放里面。
先clone gitlab这个工程中的代码,然后将我提供的gitee仓库中的代码复制过来放在这个文件夹中,然后pull到gitlab仓库中。
推送成功以后gitlab的仓库中就有了如下内容。
安装Jenkis并进行相应配置
Jenkins我运行在了阿里云的服务器上,其IP地址用B.B.B.B来表示。同样也要在这个服务器上安装Docker。
1. 下载Jenkins镜像并运行
docker run -d --name=jenkins \
-p 8888:8080 \
-u root \
--restart always \ n
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /tmp/jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
2. 访问Jekins
访问的IP地址:http://服务器ip地址:8888/ 我的Jenkins是部署在阿里云服务器上,所以这里填上阿里云服务器的ip地址。
第一次登录时需要需要输入密钥。在运行jenkins镜像时,将 /tmp/jenkins_home 映射到了Jenkins的这个路径 /var/jenkins_home。所以在阿里云的服务器上应该时这样进行访问 :
cat /var/jenkins_home/secrets/initialAdminPassword
然后将该文件中的密码复制到到管理员密码中。
选择安装推荐的插件
等所有组件初始完
创建管理员
在系统管理 -> 插件管理 -> 可选插件处,搜索 GitLab 和 Docker ,分别安装相关插件。
- 安装gitlab相关插件
- 安装docker相关插件
- 安装SSH相关插件
3. 创建Jenkins任务
在新建任务这一栏选择 构建一个自由风格的软件项目
4. 配置工程
配置源码管理
向我下面这样输入以后,一开始可能会有红色的提示。
比如下面这样的红色提示,如图1。当配置好以后,就像图2一样是没有任何错误的提示的。
图1 :
图2
选择添加
然后如下图所示。
配置构建触发器
当我们往gitlab 仓库中推送代码时,Jenkin能自动根据gitlab中代码的版本变化自动重新构建,靠的就是这个构建触发器。
生成token
复制这段token
回到gitlab,在hello工程的设置中选择 Webhooks
在URL这一栏填上Jenkins任务的URL,在配置构建触发器的第一张图片中就有显示。Secret Token填上刚才点击Generate生成的Token。然后点击 Add webhook 保存
配置Shell脚本
在Shell脚本中用来指定我们的应用究竟该怎么构建。
由于需要将构建后生成的镜像推送到镜像仓库,然后用来部署应用的服务器会从该镜像仓库中pull镜像并运行。所以需要先在doccker hub中创建一个仓库,没有Docker hub账号的可以自己先创建一个,然后记住自己的用户名和用户密码,下面需要在shell脚本中写入。
然后在里面输入shell。
shell脚本:
# 需要推送的镜像名称
IMAGE_NAME="zylsimon/devops-demo"
# 获取当前构建的版本号
GIT_VERSION=`git describe --always --tag`
# 生成完整的镜像 URL 变量,用于构建和推送镜像
REPOSITORY=docker.io/${IMAGE_NAME}:${GIT_VERSION}
# 构建Docker镜像
docker build -t $REPOSITORY -f Dockerfile .
# 登录镜像仓库,username 跟 password 为目标镜像仓库的用户名和密码
docker login --username=用户名 --password=用户密码 docker.io
# 推送 Docker 镜像到目标镜像仓库
docker push $REPOSITORY
# 将部署所需要的指令写入当前路径下./shell/release文件中
rm -rf ./shell
mkdir -p ./shell
echo "docker login --username=用户名 --password=用户密码" >> ./shell/release
echo "docker pull $REPOSITORY" >> ./shell/release
echo "docker kill hello" >> ./shell/release
echo "docker rm -f hello" >> ./shell/release
echo "docker run --rm --name=hello -p 8090:8090 -d $REPOSITORY" >> ./shell/release
配置自动部署
当jenkins为我们完成了自动构建,并将构建好的镜像推送到我们的Docker Hub之后,我们还需要它为我们完成自动部署的功能。
当时安装的 Publish Over SSH ,就和我们的自动部署有关。
在jenkins的系统配置中,配置一台服务器,构建好的程序将要部署在这台服务器上。
在Publish over SSH这个模块进行配置,还记得我一开始就交代了吗,我用了三台服务器,一台百度云的服务器用来部署gitlab,一台阿里云的服务器用来部署jenkins,一台ucloud的服务器用来部署应用程序。
配置好以后点击保存。
回到我们hello工程的配置。
选择 Send files or execute commands over SSH
进行如下配置
到此,所有的配置已经结束。
测试
首先,在ucloud服务中运行了一个容器,这个容器是基于上述的go程序构建以后发布到docker hub仓库中的,就当作这个是程序的旧的版本,然后我们需要做出更新,用新版本替换掉这个旧的版本。
然后访问,此时输入的IP地址为ucloud服务器的ip地址,端口号为8090,需要注意首先要开启该端口对应的防火墙,不然无法访问。
我的代码是放在百度云的服务器中的,查看一下此时的版本号,与docker中 zylsimon/devops-demo 镜像的 tag 号保持一致。
编辑main.go,做一点改动,然后重新推送到gitlab代码仓库。
[root@baidu-host hello]# git add . && git commit -m "修改main.go v8" && git push -u origin master
[master 719bbcc] 修改main.go v8
1 file changed, 1 insertion(+), 1 deletion(-)
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 297 bytes | 297.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
To ssh://localhost:2222/root/hello.git
540656b..719bbcc master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
[root@baidu-host hello]#
然后查看jenkins的工程,发现已经开始构建了。
出现蓝色的小球表示构建成功。
在ucloud上查看,发现运行中的容器的已经发生改变了,原来的容器是基于zylsimon/devops-demo:540656b这个镜像的,现在运行的容器是基于 zylsimon/devops-demo:719bbcc 这个镜像的,719bbcc 对应着git托管程序的版本号。
ucloud:
百度云服务器:
再次访问时,发现网页内容已经发生了变化。访问的是ucloud对应的ip地址。
到此,便大功告成了,虽然配置Gitlab,配置jenkins时都还有些复杂,但是当配置好以后,作为一名开发者只需要往git中推送代码,剩下的步骤,包括构建,部署全部交给jenkins来完成,是不是让人感觉一阵清爽,这便是CI/CD的魅力所在。
参考
更多推荐
所有评论(0)