美文网首页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