docker-compose+nginx实现服务不中断更新
思路是写一个脚本,docker-compose scale扩容,然后重写nginx配置文件,刷新负载均衡
nginx重写的配置文件,文件名service,里面只有upstream,例如:
upstream e-chatbot-server-dev {
server 0.0.0.0:8080;
server 0.0.0.0:8081;
}
脚本使用方法:
./rollupdate.sh --service=test-server --port=8080
需要注意的是docker-compose.yaml的服务test-server端口范围要比实例数多一个,yaml示例如下:
version: '3'
services:
test-server:
image: test-server:1.0
restart: always
networks:
- dev
ports:
- "8080-8082:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
cpus: 2
memory: 1g
replicas: 2
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
networks:
dev:
external: true
driver: bridge
rollupdate.sh脚本如下:
service=
port=
# 循环处理所有命令行参数
for arg in "$@"
do
case $arg in
--service=*) # 如果参数以--service=开头
service="${arg#*=}" # 截取等号后的部分作为服务名称
;;
--port=*) # 如果参数以--port=开头
port="${arg#*=}" # 截取等号后的部分作为端口号
;;
*) # 如果参数不是以--service=或--port=开头,则跳过
;;
esac
done
if [ -z "$service" ]; then
echo "--service=?"
fi
if [ -z "$port" ]; then
echo "--port=?"
fi
if [ -z "$service" ] || [ -z "$port" ]; then
exit 1
fi
old_names=$(docker-compose ps $service --format "{{.Names}}")
if [ -z "$old_names" ]; then
docker-compose up -d $service
exit $?
fi
echo -e "服务$service,老的实例:\n $old_names"
docker-compose port $service $port > /etc/null
if [ "$?" != "0" ]; then
exit 1
fi
replicas=$(docker-compose config $service --format="json" | jq ".services.\"$service\".deploy.replicas // 1")
if [ -z "$replicas" ]; then
echo "未获取到副本数量"
exit 1
fi
echo "old replicas: $replicas"
let replicas=replicas+1
echo "update replicas: $replicas"
for container_name in $old_names; do
# 在这里可以添加其他针对每个容器名称的操作
echo "服务:$service设置副本为$replicas,正在添加一个副本"
docker-compose scale "$service=$replicas"
if [ "$?" != "0" ]; then
exit
fi
echo -n "等待新增副本就绪..."
for i in {1..100}; do
#服务需要监控检查
start_count=$(docker-compose ps $service | grep "health: starting" | wc -l)
if [ $start_count -eq 0 ]; then
break
fi
echo -n "."
sleep 5
done
echo ""
if [ $start_count -gt 0 ]; then
echo "超过最大等待时间"
exit 1
fi
new_names=$(docker-compose ps $service --format "{{.Names}}")
nx_conf="upstream $service {\n"
for new_name in $new_names; do
if [ "$new_name" != "$container_name" ]; then
hport=$(docker port $new_name $port | head -n 1)
nx_conf+=" server $hport;\n"
fi
done
nx_conf+="}"
echo "从nginx负载均衡移除实例$container_name"
echo -e $nx_conf > /etc/nginx/conf.d/$service.conf
nginx -s reload
echo "docker stop $container_name"
docker stop $container_name && docker rm $container_name
done

浙公网安备 33010602011771号