美文网首页K8s
In Place upgrade

In Place upgrade

作者: 程序员札记 | 来源:发表于2022-10-13 09:15 被阅读0次

在k8s 的应用中, 通常的deployment 都是rolling update, 也就是说,去掉一个老的pod ,对等产生一个新的pod。 新的pod 的ip是变化的。 在企业安全环境中,通常所有的防火墙,无论是硬件防火墙或者软件防火墙,都是基于ip的。如果ip 经常变化,意味着ip不在是一个静态资源,而是一个动态资源。 这个变化显然对于ip based 的防火墙和验证机制是个巨大的冲击。 意味着每次deploy,都对ip 的防火墙等数据配置进行更新,这就对系统的性能有了巨大的要求。

  • 这个速度如果不能及时满足,就会产生控制面能通,但是实际数据连不通的情况。一个cluster 的pod 数量巨大, 对contorller 的处理能力和速度有极高的要求。在这个应用场景, 可能ip 不停的变化不是一个很好的稳定的方案。
  • 再次 rolling update 对于系统的capacity 就需要有很多冗余,从而某种程度造成浪费
  • 再三由于部署的app 数量是变化的,由于surge number 的存在,很难估计到底一个精确的容量。 、
  • 重新新create pod ,部署的速度和稳定性都会受到影响。
  • 同样ip 也是资源,动态ip导致ip 的资源容易被耗尽, 从infrastructue 的角度来看, 动态ip 应该非必要,不执行。

基于上面的问题,能不能在deploy 的时候,如果是image 的变化,只是update image,而不用重新deploy. 从而尽量减少新的pod 生成, 从而是ip 能够被复用。

在k8s集群中已经支持这样的要升级镜像的需求,但是挂载的数据并不发生变化。同时又不想停止线上服务。

替换镜像操作:

升级镜像

kubectl set image deployment/deploy-name containerName=newIMG:version

# kubectl set image controllerType/controllerInstanceName underInstanceContainerName=image:version
需要注意的是,如果镜像版本没有发生变化,更新可能不生效。

在docker中可以通过停止容器(pause)来达到不删除容器,又不提供服务的功能。


image.png

需要恢复的时候,执行一下docker resume即可。

在k8s集群中也有类似的操作,就是rollout操作(k8s1.15版本之后)。

image.png image.png

在想重启pod,又不想再创建一次的情况下可以考虑使用。这里的restart和在不删除pod(kubectl delete -f xxx.yaml)的情况下再次执行创建(create 或 apply)的效果类似,都可以达到滚动升级的效果,不过前提是副本数要大于1。

例子

删掉旧pod,并重新创建

产品部署完成上线之后,经常遇到需要升级服务的要求(只考虑更新镜像),以往操作流程大致如下:

  • 方式一:找到 master具体调度到的所有目标node,删除其对应的镜像文件
  • 方式二:修改 file.yaml中镜像拉取策略为Always

kubectl delete -f /path/file.yaml
kubectl create -f /path/file.yaml
但是这样有一个比较棘手的问题,就是如果升级失败的回滚策略。

流程

因此我们利用kubernetes自身的滚动升级的工具,部署及升级流程如下:

  1. 在初次创建的时候,尽量加入参数 --record,这样k8s会记录下本次启动的脚本 。
# --record
kubectl create -f /path/file.yaml --record
2.执行查看发布的历史记录,会显示现在已经记录的脚本及其序号。

# 查看历史记录
kubectl rollout history deployment deploy-apigw
3.升级命令执行后会输出:xxx   image updated

# 升级镜像
kubectl set image deployment/deploy-name containerName=newIMG:version
 
# kubectl set image controllerType/controllerInstanceName underInstanceContainerName=image:version
4.查看pod状态,如果失败需要回滚操作

# 回滚到上一个操作版本
kubectl rollout undo deployment/deploy-name
# 回滚到指定版本,版本号由第二步查看获得
kubectl rollout undo deployment/deploy-name --to-revision=3
Notice:

k8s 1.15版本,目前支持 pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs)
执行rollout undo操作之后,版本号会移动,需要确认版本号无误再undo

结论

基于这样的方案,我们可以去customize deploy controller 在deploy的时候根据spec 的变化来决定是否是重新create pod 还是update image, 这样对企业的资源,效率,稳定性都有巨大的帮助。

相关文章

网友评论

    本文标题:In Place upgrade

    本文链接:https://www.haomeiwen.com/subject/cexfzrtx.html