(第一版)记录一次Jenkins + Docker实现持续集成、持续部署——门店掌柜项目

第一版已作废,仅参考使用,第二版地址:[(第二版)记录一次Jenkins + Docker + Rancher实现持续集成、持续部署–门店掌柜项目](/2022/08/17/(第二版)记录一次Jenkins + Docker + Rancher实现持续集成、持续部署–门店掌柜项目)

1. Jenkins环境安装

安装部分参考:docker高级之——Docker-Compose、Docker-Swarm、Jakins持续集成、Rancher持续部署

不同之处:

1
2
3
4
5
6
docker run -d --name jenkins \
-p 8888:8080 \
-p 50000:50000 \
--restart=always \
-v jenkins:/var/jenkins_home \
jenkins/jenkins:latest

1.2. Jenkins所需插件

  • Maven Integration: Maven 集成管理插件。
  • Docker plugin: Docker集成插件。
  • GitLab Plugin: GitLab集成插件。
  • Publish Over SSH:远程文件发布与SSH命令执行插件。
  • gitee:用于gitee提交时进行WebHooks触发任务
  • build timeout:用于设置任务超时时间,一般默认装了这个插件

1.3. 常见问题

1.3.1 构建Docker镜像时提示错误:unix://localhost:80: No such file or directory

原因有二:

1、没有给Docker打开远程api访问

2、防火墙没开放该api访问的端口

解决方式:

1、开启Docker的远程api访问

1
2
3
4
5
6
7
# 编辑此文件
vi /lib/systemd/system/docker.service
# 修改此行配置,原来设置删除
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H tcp://0.0.0.0:7654
# 重新加配置文件并重启docker
systemctl daemon-reload
systemctl restart docker

2、防火墙放行2375端口

1
2
firewall-cmd --zone=public --add-port=2375/udp --permanent
firewall-cmd --reload

3、添加Jenkins全局变量

Jenkins > 系统管理 > 系统配置 > 全局属性 > 环境变量

1
2
3
键:DOCKER_HOST
值:tcp://192.168.200.131:2375
ip地址换成Docker所在的服务器地址)

1.3.2 错误提示:http: server gave HTTP response to HTTPS client

因为Docker引擎默认通过 https 协议与 Docker Registry 通信,所以如果搭建的Docker 私有镜像库是 http 协议的话,就会输出上述日志。

解决:

1
2
3
vim /usr/lib/systemd/system/docker.service

# ExecStart 选项,加入 --insecure-registry {docker 私有镜像库 IP} --ipv6=false

2. 防火墙放行端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 以下端口必须是开放的:
# TCP port 2377为集群管理通信
# TCP and UDP port 7946 为节点间通信
# UDP port 4789 为网络间流量

# 需要配置如下端口
firewall-cmd --list-all
firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=7946/tcp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent
firewall-cmd --zone=public --add-port=4789/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --zone=public --add-port=2375/udp --permanent
firewall-cmd --reload

3. 项目配置

3.1 新增需要运行的服务pom文件中的插件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.7</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
<configuration>
<contextDirectory>${project.basedir}</contextDirectory>
<repository>registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper</repository>
<tag>${project.artifactId}</tag>
<goal>push</goal>
<username>阿里云账号</username>
<password>阿里云镜像服务的密码</password>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>

<!--如果使用本地注册中心则直接使用如下配置-->
<!--<configuration>-->
<!-- <contextDirectory>${project.basedir}</contextDirectory>-->
<!-- <repository>registry.liuhaoan.com:5000/shopkeeper/${project.artifactId}</repository>-->
<!-- <buildArgs>-->
<!-- <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>-->
<!-- </buildArgs>-->
<!--</configuration>-->

</configuration>
</plugin>

3.2 新增Dockerfile文件(与pom文件同级)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 设置JAVA版本
FROM java:8
# 拷贝运行JAR包
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
# 设置JVM运行参数, 这里限定下内存大小,减少开销
ENV JAVA_OPTS="\
-server \
-Xms256m \
-Xmx512m \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=512m"
#空参数,方便创建容器时传参
ENV PARAMS=""
# 入口点, 执行JAVA运行命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]

4. 创建父工程任务

Snipaste_2022-08-17_17-23-56

4.1 配置git仓库源码地址

Snipaste_2022-08-17_17-27-32

4.2 设置超时时间

项目构建时间一般挺长,建议多设置一点,这里设置15分钟

Snipaste_2022-08-17_17-59-43

4.3 添加构建步骤

4.3.1 配置Maven打包

1
2
clean install
# 清除,安装

Snipaste_2022-08-17_17-30-29

4.3.2 远程SSH调用管理节点对集群网络进行创建

Snipaste_2022-08-17_17-34-18

Snipaste_2022-08-17_18-03-49

1
2
3
4
5
6
7
8
9
10
11
12
echo "创建集群网络"
shellFile=/tmp/$JOB_NAME-shell.sh
rm -f ${shellFile}
echo '#!/bin/bash' >> ${shellFile}

echo "if [ -z \"\$(docker network ls -f name=shopkeeper -f driver=overlay --format '{{.ID}}')\" ]" >> ${shellFile}
echo then >> ${shellFile}
echo docker network create -d overlay shopkeeper >> ${shellFile}
echo fi >> ${shellFile}

chmod +x ${shellFile}
sh ${shellFile}

5. 创建子工程任务

配置git仓库、设置超时时间等与父工程相同

5.1 添加构建触发器

这里配置成:父工程构建完毕之后子工程自动构建,这样的话只要执行父工程就能完成整个项目的构建

Snipaste_2022-08-17_18-07-19

5.2 添加构建步骤

5.2.1 调用管理节点删除当前工程的集群任务

Snipaste_2022-08-17_18-12-22

Snipaste_2022-08-17_18-12-49

1
2
3
4
5
6
7
8
9
10
11
12
echo "删除集群服务"
shellFile=/tmp/$JOB_NAME-shell.sh
rm -f ${shellFile}
echo '#!/bin/bash' >> ${shellFile}

echo "if [ -n \"\$(docker service ls -f name=$JOB_NAME --format '{{.ID}}')\" ]" >> ${shellFile}
echo then >> ${shellFile}
echo docker service rm \$\(docker service ls -f name=$JOB_NAME --format '{{.ID}}' \) >> ${shellFile}
echo fi >> ${shellFile}

chmod +x ${shellFile}
sh ${shellFile}

5.2.2 删除Jenkins所在服务器Docker中当前要生成同名的镜像

Snipaste_2022-08-19_21-57-35

Snipaste_2022-08-19_21-58-11

1
2
3
4
5
6
7
8
9
10
11
12
echo "删除Jenkins所在服务器Docker中当前要生成同名的镜像"
shellFile=/tmp/$JOB_NAME-shell.sh
rm -f ${shellFile}
echo '#!/bin/bash' >> ${shellFile}

echo "if [ -n \"\$(docker images -a -f reference=registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME --format '{{.ID}}')\" ] ">> ${shellFile}
echo then >> ${shellFile}
echo docker rmi -f \$\(docker images -a -f reference=registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME --format '{{.ID}}'\) >> ${shellFile}
echo fi >> ${shellFile}

chmod +x ${shellFile}
sh ${shellFile}

5.2.3 配置Maven打包

Snipaste_2022-08-17_18-09-28

1
clean install  dockerfile:build -f shopkeeper-gateway/gateway-uniapp/pom.xml dockerfile:push

5.2.4 当前服务的所有节点从阿里云拉取最新镜像

示例:当前只部署一个阿里云的节点

Snipaste_2022-08-17_18-15-46

Snipaste_2022-08-17_18-17-57

1
2
3
4
5
6
7
8
9
10
11
12
13
14
echo "拉取最新镜像"
shellFile=/tmp/$JOB_NAME-shell.sh
rm -f ${shellFile}
echo '#!/bin/bash' >> ${shellFile}

echo "if [ -n \"\$(docker images -a -f reference=registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME --format '{{.ID}}')\" ] ">> ${shellFile}
echo then >> ${shellFile}
echo docker rmi -f \$\(docker images -a -f reference=registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME --format '{{.ID}}'\) >> ${shellFile}
echo fi >> ${shellFile}

echo docker login --username=阿里云账号 registry.cn-shenzhen.aliyuncs.com --password=阿里云镜像服务密码 >> ${shellFile}
echo docker pull registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME >> ${shellFile}
chmod +x ${shellFile}
sh ${shellFile}

5.2.5 调用管理节点进行服务部署

Snipaste_2022-08-17_18-18-44

Snipaste_2022-08-17_18-19-32

1
2
3
4
5
6
7
8
9
echo "服务部署"
shellFile=/tmp/$JOB_NAME-shell.sh
rm -f ${shellFile}
echo '#!/bin/bash' >> ${shellFile}

echo docker service create --replicas 1 -p 8018:8018 --constraint \"node.hostname == aly\" --network shopkeeper -e PARAMS=\"--spring.profiles.active=test\" --name $JOB_NAME registry.cn-shenzhen.aliyuncs.com/liuhaoan/shopkeeper:$JOB_NAME >> ${shellFile}

chmod +x ${shellFile}
sh ${shellFile}

6. 配置gitee提交后自动触发任务构建

这里只需要触发父工程就行了,父工程构建完会自动触发子工程的构建

6.1 配置Gitee插件

Jenkins系统 > 系统管理 > 系统配置 > Gitee配置

Snipaste_2022-08-17_18-24-18

链接名称:随意

Gitee域名:https://gitee.com

证书令牌:Gitee > 设置 > 私人令牌 > 添加即可

6.2 配置父工程任务的WebHooks触发

Snipaste_2022-08-17_18-26-56

Snipaste_2022-08-17_18-28-28

配置号了之后去Gitee配置WebHooks触发

触发链接为上图框起来的:

1
http://192.168.200.131:8888/gitee-project/shopkeeper

密码则是自己生成的

6.3 配置内网穿透

注意:如果Jenkins所在服务器是内网ip才需要配置,外网ip服务器跳过此步骤

6.3.1 下载frp内网穿透工具:

frp_0.39.1_linux_amd64_131.zip

6.3.2 修改start_frp.sh与start_frp_service.sh

Snipaste_2022-08-17_18-35-01

框起来部分修改为工具所在目录

6.3.3 修改frps.ini

Snipaste_2022-08-17_18-41-29

服务端token随便改,但是下面的客户端配置要和服务端配置的一致

6.3.4 修改frpc.ini

Snipaste_2022-08-17_18-38-38

6.3.5 配置服务端

把整个工具上传至有外网ip的服务器中,修改start_frp_service.sh权限并执行就行

注意事项:防火墙必须开放相应端口,这里是7000端口

1
2
firewall-cmd --zone=public --add-port=7000/udp --permanent
firewall-cmd --reload

为了方便可以添加至开机启动,客户端同理

1
2
3
4
vim /etc/rc.d/rc.local

# 最后面添加启动文件全路径即可
/root/frp_0.39.1_linux_amd64/start_frp_service.sh

6.3.6 配置客户端

把整个工具上传至有内网的服务器中,修改start_frp.sh权限并执行就行

6.4 配置Gitee提交代码后的自动WebHooks触发

Gitee > 项目仓库 > 管理 > WebHooks > 添加

Snipaste_2022-08-17_18-51-31

注意:需要把地址改为外网IP地址