作者 | 高相林(禅鸣)
导读:集群升级是 Kubernetes 集群生命周期中最为重要的一环,也是众多使用者最为谨慎对待的操作之一。为了更好地理解集群升级这件事情的内涵外延,我们首先会对集群升级的必要性和难点进行阐述;随后会对集群升级前必须要做的前置检查进行逐一讲解;接下来会对两种常见的升级方式进行展开介绍;最后对集群升级的三个步骤进行讲解,帮助读者从理论走入实践。
升级的必要性&难点
在 Kubernetes 领域,得益于活跃的开源社区,Kubernetes 的迭代速度较快,目前保持在每个季度发行一个新版本的节奏。新版本的 Kubernetes 有着更为先进的新特性、更加全面的安全加固和漏洞修复。前一段时间社区刚刚完成了 1.19 版本的正式发布。
对于发展如此快速的开源项目,跟上社区的步伐就显得更为重要,而集群升级能力就是帮助我们跟上社区步伐的不二选择。我们可以从以下两个方面对集群升级的必要性进行说明:
讲完了集群升级的必要性,我们来详细看一下集群升级的难点。
目前多数 Kubernetes 使用者对集群升级这件事持有着非常保守的态度,害怕集群在升级的过程中出现不可预期的情况,也有使用者将集群升级称之为“给飞行中的飞机换引擎”。那么,使用者对于升级的保守态度主要来源于什么原因呢?我认为有以下几点:
“千集群千面”的情况的存在,导致了集群升级需要以一套逻辑完成各种不同情况集群的升级工作,这也正是集群升级的困难之处。
升级预检
正如我们前面所说,给正在对外提供服务的 Kubernetes 集群升级,就好比是“给飞行中的飞机换引擎”。因为集群升级面临着众多难点,也使得众多的 Kubernetes 集群维护者对集群升级这件事情比较紧张。
我们可以通过详细的升级预检,来消除集群升级的不确定性。对于上面列举的集群升级的难点,我们也可以分别进行详细的升级预检,对症下药,将难点逐一击破。升级预检主要可以分为三个方面:
说到核心组件健康检查,就不得不剖析一下集群的健康对于集群升级的重要性。一个不健康的集群很可能会在升级中出现各种异常的问题,就算侥幸完成了升级,各种问题也会在后续使用中逐渐凸显出来。
有人会说,我的集群看起来挺健康的,但是升级之后就出现问题了。一般来说,之所以会发生这种情况,是因为在集群在升级之前,这个问题已经存在了,只不过是在经历了集群升级之后才显现出来。
在了解了核心组件健康检查的必要性之后,我们来看一下都需要对那些组件进行检查:
节点作为承载 Kubernetes 的底层元计算资源,不仅运行着 Kubelet、Docker 等重要的系统进程,也充当着集群和底层硬件交互接口的角色。
确保节点的健康性和配置的正确性是确保整个集群健康性重要的一环。下面就对所需的检查项进行讲解。
运行在云上的 Kubernetes 集群依赖着众多云资源,一旦集群所依赖的云资源不健康或者配置错误,就会影响到整个集群的正常运行。我们主要对下列云资源的状态和配置进行预检:
两种常见的升级方式
在软件升级领域,有两种主流的软件升级方式,即原地升级和替换升级。这两种升级方式同样适用于 Kubernetes 集群,它们采用了不同软件升级思路,但也都存在着各自的利弊。下面我们来对这两种集群升级方式进行逐一讲解。
原地升级是一种精细化的、对这个那个集群改动量相对较小的一种升级方式。在升级容器的 worker 节点时,该升级方式会通过在 ECS 上原地替换 Kubernetes 组件的方式(主要为 kubelet 和其相关组件),完成整个集群的升级工作。阿里云容器服务 Kubernetes 为客户提供的集群升级就是基于这种方式的。
以将 Kubernetes 的版本从 1.14 升级到 1.16 为例。首先我们会对 ECS A 上的原本为 1.14 的 Kubelet 及其配置升级为 1.16,在完成节点 ECS A 上的组件升级之后,该节点也就被成功的升级到了 1.16。然后我们再对 ECS B 进行相同的操作,将其升级为 1.16,从而完成整个集群的升级工作。
在这个过程中节点保持运行,ECS 的相关配置也不会被修改。如图所示:
替换升级又称轮转升级,相对于原地升级,替换升级是一种更加粗狂和原子化的升级方式。替换升级会逐个将旧版本的节点从集群中移除,并用新版本全新的节点来替换,从而完成整个 Kubernetes 集群的升级工作。
同样以将 Kubernetes 的版本从 1.14 升级到 1.16 为例。使用替代轮转方式的情况下,我们会将集群中 1.14 版本的节点依次进行排水并从集群中移除,并直接加入 1.16 版本的节点。即将 1.14 节点的 ECS A 从节点剔除,并将 1.16 节点的 ECS C 加入集群,再将 ECS B 从集群中删除,最后将 ECS D 加入到集群中。
这样就完成了所有节点的轮转工作,整个集群就也就升级到 1.16 了。如图所示:
替代升级通过将旧版本的节点替换为新版本的节点从而完成集群升级。这个替换的过程相较于原地升级更为原子化,也不存在那么复杂的中间状态,所以也不需要在升级之前进行太多的前置检查。相对应地,升级过程中可能会出现的各种稀奇古怪的问题也会减少很多。
集群升级三部曲
一个 Kubernetes 集群主要由负责集群管控的 master,执行工作负载的 worker 和众多功能性的系统组件组成。对一个 Kubernetes 集群升级,也就是对集群中的这三个部分进行分别升级。
故集群升级的三部曲为:
下面我们来对集群升级三部曲进行详细的讲解。
master 作为集群的大脑,承担了与使用者交互、任务调度和各种功能性的任务处理。集群 master 的部署方式也比较多样,可以通过 static pod 进行部署,可以通过本地进程进行部署,也可以通过 Kubernetes on Kubernetes 的方式在另一个集群内通过 pod 的方式部署。
总而言之,无论 master 为哪种部署方式,想要升级 master 主要就是对 master 中的三大件进行版本升级,主要包括:
需要注意,为了保证 Kubernetes apiserver 的可用性不中断,master 中的 kube-apiserver 最少需要有两个,这样才可以实现滚动升级,从而保证 apiserver 不会出现 downtime。
在完成 master 的升级工作之后,我们才可以开始对 worker 进行升级。Worker 升级主要是对节点上的 kubelet 及其依赖组件(如 cni 等)进行升级。为了保证集群中 worker 不会同时发生大批量的 kubelet 重启,所以我们需要对 worker 节点进行分批升级。
需要注意,我们必须要先升级 master,再升级 worker。因为高版本的 kubelet 在连接低版本的 master 时,很可能会出现不兼容的情况,从而导致节点 not ready。对于低版本的 kubelet 连接高版本的 apiserver,开源社区保证了 apiserver 对于 kubelet 两个版本的向后兼容性,即 1.14 的 kubelet 可以连接到 1.16 的 apiserver,而不会发生兼容性问题。
为了保证集群中各个组件的兼容性,我们需要在升级集群的同时对集群中的核心系统组件进行同步升级,主要包括:
社区的版本兼容矩阵:https://github.com/coredns/deployment/blob/master/kubernetes/CoreDNS-k8s_version.md
K8S进阶训练营,点击下方图片了解详情