我又想Docker如何不停服更新了
大家可以比较常用k8s
但是我的情况特殊,同时在线的设备数量会超过65535
所以我没有使用k8s,因为服务的负载均衡方式决定了这个数量
我直接是docker部署,然后由NBL直接就到服务程序了。
那怎如何平滑地更新程序呢?
部署架构
我的程序有两种,一种是http服务程序,另外一种是tcp/ip服务程序
Http服务走k8s/k3s部署是可以的,我懒得弄了,就统一用docker-compose来部署了。
结构大概如下:
从上图可以看出,网关进来,然后根据nacos里的配置,去调用各个服务。
nacos里的服务实例是由各服务心跳和nacos的健康检查确保状态的。
思路
在nacos的后台,我们可以看到有服务下线的按钮
点击下线,这样子,这个服务就不会分发流量了。
官方文档:
https://nacos.io/zh-cn/docs/open-api.html
注意版本,是2.x还是1.x的
通过这个接口,可以修改实例下线,还是上线。
如果你是单实例,那么就跑起一个新的实例,一会再关闭旧的实例。
如果你是多实例的,并且能够承载得住的,可以先关闭一个实例的流量,然后停掉服务,升级程序。
脚本
如何通过脚本完成服务实例下线,停止服务呢?
#!/bin/bash
# 过滤出一行内容
grepText=$(docker-compose logs | grep "register finished")
echo $grepText
service_name=$(echo $grepText | cut -d' ' -f15)
echo service_name=$service_name
ip_port=$(echo $grepText | cut -d' ' -f16)
echo "ip_port=$ip_port"
ip=$(echo $ip_port | cut -d':' -f1)
echo "ip="$ip
port=$(echo $ip_port | cut -d':' -f2)
echo "port="$port
name_space='d5204502-4952-41e6-bf07-dcbbf2b6b650'
health=false
url="172.16.193.47:8848/nacos/v1/ns/instance?serviceName=${service_name}&ip=${ip}&port=${port}&namespaceId=${name_space}&enabled=false"
echo $url
curl -X PUT $url
echo ""
下面是我一条一条脚本执行令给大家看,就知道什么意思了。
目的就是拿到当前服务实例的IP,端口,还有服务名
有了这个以后,调用put接口,就可以更新服务的状态了。
通过脚本修改版本号,直接启动,就会去拉取新的镜像更新了,此时停机,不会影响到正在进来的流量,大家可以用jmeter试试保持调用,你会发现基本上没有报错的,可以持续完成调用。当然,也有例外,偶尔有几个是调用失败的,如果并发很高。
docker-compose up -d
DevOps
开发和运维的流程如何呢?
基于上面这个,我会在我的编译脚本里自动生成升级脚本。
升级:编译完以后,上传镜像,推送升级脚本到正式服务器上,编译完,我检查一下,调用一下脚本,就可以完成自动化部署了。
回退:回退的话,由于我正式环境的版本号是有序的,通过脚本,走升级流程即可,只不过是镜像号倒退。也就是回退也是升级,只不过是倒升级。
因为我不是每次都更新所有的程序,所以升级的脚本由编译服务器生成,你编译了什么服务,就生成对应要升级的脚本。