升级之前review集群状态,确保所有组件正常工作,review重要业务的实例数,避免副本数为1,并且适当设置PDB; 需要检查是否有单个node带有特殊的label,可能有pod依赖于该label,如果该node异常导致pod也会发生故障(这个坑真的有人踩过:参见:ingress-cordoned)。
升级过程中发现的“坑” (已填)上面的实践3中就是笔者测试的时候发现的一个坑: 目前升级会导致部分controller(daemonset)重建容器,升级之后因为pod spec发生变化,部分controller会创建新的controllerrevision ,升级更新所有其控制的容器。如果先升级master/controller-manager,因为此时kubelet还未升级,版本较低,会出现不兼容的字段,严重情况下kubelet会reject掉该pod,导致最终该node上此daemonset container退出并无法重启。如果daemonset 设置为滚动升级,并且maxUnavailable设置为1的话,可以避免一定损失,最多只允许同时挂掉一个daemonset container。参见kubernetes/kubernetes: Issue #78633。所以最佳实践还是升级之前停掉Controller-manager,集群实际完毕之后最后升级controller-manager。设置所有controller的升级策略为滚动升级并设置最大不可用实例数。对于上述Issue官方在新版本中已经进行修复并backport到旧版本中。
对于一些刚从alpha转到beta的特性,beta版本是默认开启的版本,对于这些特性一定要非常小心,可能仍然会存在一些bug,建议还是手动关闭,对于一些可用性要求较高的集群建议只使用GA的feature。这次踩的一个坑就是node lease特性,该特性在1.14中刚好是Beta版本默认开启,这是一个非常有用的feature,对于大规模集群可以有效降低apiserver,etcd的负载,但是kubelet中node lease的默认renew周期是hardcode的10s中且不可调整,也就是说此时node与master心跳的频率只能是10s,此时指定--node-status-update-frequencyflag没有任何作用,如果controller-manager中配置的--node-monitor-grace-period刚好是10s,这时候node会不断地在ready和non-ready直接摇摆,参见kubernetes/kubernetes issue#80172,该issue已经被笔者给修复掉了 :)。
写在后面kubernetes还是在高速的迭代过程中,升级过程中出现不兼容是在所难免的, 唯有搞懂内部的实现机制才能保障集群的长治久安。发现问题也需要我们有能力去解决并且反馈到社区中,取之于社区,理应回报于社区。
referenceKubernetes Release Versioning