使用docker swarm滚动更新java项目,部署集群,这一切的前提是使用Jenkins+maven进行项目打包,分发等功能
具体可以参考我的另外三篇文章
https://www.cnblogs.com/mumengyun/p/10037246.html
https://www.cnblogs.com/mumengyun/p/10000739.html
https://www.cnblogs.com/mumengyun/p/10143203.html
以下写的就是如何使用docker swarm进行java项目的发布,滚动更新,回滚,镜像管理
大致的流程:
对打包好的jar包制作镜像-->上传到私服-->集群拉取镜像-->根据docker-compose.yaml文件创建swarm集群
Dockerfile文件
FROM x.x.x.x/java:8-jre
MAINTAINER xxx xxxx <xxxx@163.com>
LABEL image_category="fwx"
ADD ./jar/xxx.jar /app/
CMD ["java", "-Xmx1000m", "-jar", "/app/xxx.jar"]
x.x.x.x 这个IP为docker私有仓库的地址
LABEL标签 是为了删除未使用镜像的标签,当然作用不仅仅只这一个,后面的jenkins.sh脚本会使用这个标签
jenkins.sh内容
#!/bin/bash
# set -e
export BUILD_ID=dontkillme
\cp -f $WORKSPACE/target/fbl-findhousewx.jar /data/docker/findhousewx/jar && \
# 容器名称
CONTAINER="findhousewx"
# 服务名称
SERVICE_NAME="findhousewx_fbl-findhousewx-service"
# docker私有仓库的地址
REG_URL="x.x.x.x:8082/"
# 私有仓库账户密码
USER="admin"
PASSWD="fbl*#!"
# 登陆私有仓库
docker login -u $USER -p $PASSWD $REG_URL && \
# 镜像名称(以日期时间为镜像标签,防止重复)
IMAGE=$REG_URL$CONTAINER":"$(date -d "today" +"%Y%m%d_%H%M%S")
# dockerfile目录
cd /data/docker/findhousewx && \
# 创建新镜像
docker build -t $IMAGE . && \
# 上传镜像到私有仓库
docker push $IMAGE && \
echo "上传镜像完成" && \
# 定义删除未使用镜像和容器的函数
deletenotused(){
# 删除未使用的pod
docker container prune -f --filter "label=pod_category=fwx" --filter "until=48h"
# 删除未使用的image(使用标签label来定位改服务的pod,防止删除其他服务的pod)
docker image prune -a -f --filter "label=image_category=fwx" --filter "until=48h"
}
docker service ls | grep -i $CONTAINER
# 如果服务正在运行则滚动更新,如果没有就创建
if [ $? -eq 0 ];then
# 滚动升级
docker service update --image $IMAGE $SERVICE_NAME && \
deletenotused
else
# 删除 docker-compose.jenkins.yml 文件,防止使用相同镜像
rm -rf docker-compose.yml && \
# 复制 docker-compose.src.yml 文件,防止污染原文件
cp docker-compose.src.yml docker-compose.yml && \
# 替换镜像名标志位为最新镜像
sed -i s%IMAGE_LATEST%$IMAGE%g docker-compose.yml && \
# 使用 docker stack 启动服务
docker stack deploy --with-registry-auth -c docker-compose.yml $CONTAINER && \
deletenotused
fi
export BUILD_ID=dontkillme
因为这个脚本实在jenkins中使用的,jenkins在执行完一项任务后,会将启动的进程杀掉,如果不加这个参数,在构建项目后,java -jar会退出-
为什么要将镜像传到私有仓库?
因为swarm集群的其他节点在启动容器时,也需要自己构建的镜像,这个镜像不能仅仅存在在manager节点上,worker上也需要能pull
-
定义删除未使用镜像和容器的函数
函数的作用是删除未使用的镜像和exit状态的容器
docker container prune -f --filter "label=pod_category=fwx" --filter "until=48h"
删除有pod_category标签,且标签值为fwx;并且创建时间超过48小时的容器。 prune参数的作用是删除未运行的conrainer
docker image prune -a -f --filter "label=image_category=fwx" --filter "until=48h"
也是一样 -
docker stack deploy --with-registry-auth -c docker-compose.yml $CONTAINER && \
这里是重点啊!!! 这条命令是在最开始未创建服务的时候执行的,
-c
制定了docker-compose.yaml文件--with-registry-auth
这个是将docker login的登陆状态也传到swarm集群的其他节点。当创建一项服务的时候,各个节点第一步就是从docker私服仓库去拉取需要部署的镜像,但是我们只会在manager节点进行操作,docker login 也只会在manager节点进行登陆,那woker节点不登录肯定不能成功拉取镜像,这个参数就是来解决这个痛点的
docker-compose.src.yaml
version: '3'
services:
fbl-findhousewx-service:
image: IMAGE_LATEST
labels:
pod_category: fwx
ismust: unnecessary
branch: test
hostname: fbl-findhousewx
healthcheck:
test: ["CMD-SHELL", "curl -f http://baidu.com && exit 0 || exit 1"]
interval: 10s
timeout: 3s
retries: 10
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 30s
update_config:
parallelism: 1
delay: 15s
mode: replicated
replicas: 2
labels:
service_category: fwx
environment:
- TZ=Asia/Shanghai
volumes:
- /data/wwwlogs/:/data/wwwlogs/findhousewx
ports:
- 5020:5020
restart: always
networks:
- fbl
networks:
fbl:
driver: overlay
这里说下LABEL:
在Dockerfile文件中的LABEL是images的标签
在docker-compose.yaml文件中services.fbl-findhousewx-service.labels是container的标签
在docker-compose.yaml文件中services.fbl-findhousewx-service.deploy.lebels是service的标签
也就是说镜像,容器,用容器启动的服务都有各自的标签
更多具体的可以学习官网的参考
主要是jenkins.sh这个脚本很重要!