众所周知,为优化安全性和性能,最好让应用时刻保持最新状态。Kubernetes 和 Docker 可以简化上述更新操作,因为您可以用更新构建一个新容器,部署操作相对而言更加轻松。

与应用类似,Kubernetes 不断获取新功能和安全更新,因此,底层节点和 Kubernetes 基础架构也需要保持最新状态。

在本集的 “Kubernetes 最佳实践” 中,我们来看看 Google Kubernetes Engine 如何使升级 Kubernetes 集群变得轻松!

集群的两个部分

在升级集群时,两个部分都需要更新:主节点和工作节点。必须先更新主节点,然后才能更新工作节点。下面我们来看看如何使用 Kubernetes Engine 升级这两种节点。

零宕机升级主节点

Kubernetes Engine 会在发布单点版本时自动升级主节点,但通常不会自动升级到新版本(例如,1.7 到 1.8)。当您准备好升级到新版本时,只需点击 Kubernetes Engine 控制台中的升级主节点按钮即可。

但是,您可能会发现对话框中提示以下信息:

“Changing the master version can result in several minutes of control plane downtime.During that period you will be unable to edit this cluster.”

在主节点停机进行升级期间,部署和服务等继续照常工作。但是,任何需要 Kubernetes API 的程序都会停止工作。这意味着 kubectl 将停止工作,使用 Kubernetes API 获取集群信息的应用也将停止工作,并且在升级集群期间基本上不能对集群进行任何更改。

那么,如何在不引起停机的情况下更新主节点呢?

Kubernetes Engine 区域性集群的高度可用主节点

标准的 “分区性” Kubernetes Engine 集群只有一个主节点来支持集群,但您可以创建 “区域性” 集群,提供多分区、高度可用的主节点。

创建集群时,务必选择 “区域性” 选项:

就这么简单。Kubernetes Engine 自动在三个分区内创建工作节点和主节点,主节点使用已进行负载平衡的 IP 地址,因此,升级期间 Kubernetes API 将继续工作。

零宕机升级工作节点

升级工作节点时,可采用几种不同的策略。下面将重点介绍其中两个:

1、滚动更新

2、使用工作节点池迁移

滚动更新

更新 Kubernetes 工作节点的最简单方法是使用滚动更新。这是 Kubernetes Engine 用于更新工作节点的默认升级机制。

滚动更新的工作方式如下。逐个排空并封锁工作节点,确保该工作节点上未运行任何 pod。然后删除工作节点,并使用更新的 Kubernetes 版本创建新工作节点。一旦该工作节点启动并运行,下一个工作节点就会更新。此过程将一直进行,直到所有工作节点更新完毕。

可通过在工作节点池上启用自动工作节点升级,将此过程完全交由 Kubernetes Engine 管理。

如果不选择此选项,Kubernetes Engine 信息中心会在有可用升级时提醒您:

只需点击链接,按照提示执行滚动更新。

警告:确保您的 pod 由 ReplicaSet、Deployment、StatefulSet 或类似程序管理。不会重新安排独立 pod!

在 Kubernetes Engine 上执行滚动更新很简单,但也有一些缺点。

其中一个缺点是就集群容量而言少了一个工作节点。您可以扩展工作节点池来增加额外容量,然后在升级完成后缩减容量,这样便可轻松解决这一问题。

滚动更新的完全自动化特性使其易于操作,但您对过程的控制也相对减少。一旦出现问题,回滚到旧版本也需要时间,因为您必须先停止滚动更新,然后撤消。

使用工作节点池迁移

不像滚动更新那样升级 “活动” 工作节点池,您可以创建一个新工作节点池,等待所有工作节点运行,然后一次迁移一个工作节点上的负载。

假设我们的 Kubernetes 集群现在有三个虚拟机。您可以通过以下命令显示工作节点:

kubectl get nodes

NAME                                        STATUS  AGE

gke-cluster-1-default-pool-7d6b79ce-0s6z    Ready   3h

gke-cluster-1-default-pool-7d6b79ce-9kkm    Ready   3h

gke-cluster-1-default-pool-7d6b79ce-j6ch    Ready   3h

创建新工作节点池

要创建名为 “pool-two” 的新工作节点池,请运行以下命令:

gcloud container node-pools create pool-two

注:务必自定义此命令,以确保新工作节点池与旧池相同。如果需要,还可以使用 GUI 创建新的工作节点池。

现在,如果您检查工作节点,您将注意到还有三个具有新池名称的工作节点:

$ kubectl get nodes

NAME                                        STATUS  AGE

gke-cluster-1-pool-two-9ca78aa9–5gmk        Ready   1m

gke-cluster-1-pool-two-9ca78aa9–5w6w        Ready   1m

gke-cluster-1-pool-two-9ca78aa9-v88c        Ready   1m

gke-cluster-1-default-pool-7d6b79ce-0s6z    Ready   3h

gke-cluster-1-default-pool-7d6b79ce-9kkm    Ready   3h

gke-cluster-1-default-pool-7d6b79ce-j6ch    Ready   3h

不过,pod 仍位于旧工作节点上!我们把它们转移过来。

排空旧池

现在,我们需要将工作转移到新的工作节点池。让我们以滚动的方式一次移动一个工作节点。

首先,封锁每个旧工作节点。这样可避免将新 pod 安排给旧工作节点。

kubectl cordon在封锁所有旧工作节点后,只能在新工作节点上安排 pod。这意味着您可以开始从旧工作节点中移除 pod,Kubernetes 会自动在新工作节点上安排这些 pod。

警告:确保您的 pod 由 ReplicaSet、Deployment、StatefulSet 或类似程序管理。不会重新安排独立 pod!

运行以下命令来排空每个工作节点。这将删除该工作节点上的所有 pod。

kubectl drain--force

排空工作节点后,确保新的 pod 已启动并运行,然后再继续下一个工作节点。

如果您在迁移过程中有任何问题,可打开旧池,然后封锁并排空新池。Pod 将被重新安排回旧池。

删除旧池

在所有 pod 重新安排妥当后,需要删除旧池。

将 “default-pool” 替换为要删除的池。

gcloud container node-pools delete default-pool

至此,您已成功更新所有工作节点!

结论

通过使用 Kubernetes Engine,您只需点击几下,即可使 Kubernetes 集群保持最新状态。

如果您未使用类似 Kubernetes 这样的托管服务,也可以对您的集群使用滚动更新或工作节点池方法来升级工作节点。不同的是,您需要手动将新工作节点添加到集群中,并自己执行主节点升级,这可能会比较麻烦。

强烈建议您使用 Kubernetes Engine 区域性集群进行高可用主节点和自动工作节点升级,以获得轻松的升级体验。如果您需要对工作节点更新进行额外控制,可使用工作节点池方法,这种方法既可以提供所需的控制,同时还能利用 Kubernetes Engine 具有的托管 Kubernetes 平台的优势。

至此,Kubernetes 最佳实践系列正式结束。如果您对未来我要讨论的其他话题有什么想法,可通过 Twitter 与我联系。如果您要参加今年 7 月的 Google Cloud Next ‘18,我们可以见面交流一下。

声明:本文来自谷歌开发者,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。