在 Oracle 云上用 Cluster API 升级 K8s 集群

2023-02-24 00:00:00 集群 节点 镜像 升级 机器


本文转自方石剑的博客,原文:https://juejin.cn/post/7130839991999004680,版权归原作者所有。

在这篇文章中,我将介绍Cluster API[1]的一个很棒的功能:对你的 Kubernetes 集群进行滚动升级的能力。Cluster API 让它变得简单,而且可重复。

说实话,我曾经手动升级过一个 Kubernetes 集群,这并不是世界末日,但我是个懒惰的黑客,既然可以自动升级,又有安全的可重复性,为什么还要手动?

什么是群集 API?

如果你不熟悉 Cluster API,它是 Kubernetes 的一个子项目,专注于提供声明式 API 和工具,以简化多个 Kubernetes 集群的配置、升级和操作[2]。作为一个类比,把 Cluster API 看作是你的 Java 接口,它使用 Kubernetes 风格的接口来管理 Kubernetes 集群所需的基础设施。

回到我们的 Java 类比;为了使用上述 Java 接口,你需要在一个类中实现它。Cluster API 使用一个基础设施提供者模型来扩展对多个基础设施提供者的支持。几乎每个基础设施提供商都实现了一个。Oracle 的在这里[3],它可以用来在 Oracle 云中建立集群。关于如何开始使用我们的提供商的简要介绍,请查看 blogs.oracle.com/cloud-infra…[4],或阅读我们的文档,以了解更多关于开始使用的信息[5]。你也应该看看 Cluster API 那本很棒的书。

创建一个新的 Kubernetes 镜像

为了升级我们的工作节点,我们需要使用 Kubernetes Image Builder[6]来构建镜像。按照 "构建镜像[7]" 部分的更详细步骤进行前提条件和其他设置。

然后,我们需要将 kubernetes 信息设置为比我们当前集群版本更新的版本。现在,正在使用的集群是 1.22.9 ,我们想升级到 1.23.6 (当前的发布版本可以在这里找到 kubernetes.io/releases/[8])。我们将编辑 images/capi/packer/config/kubernetes.json ,并改变以下内容。

  "kubernetes_deb_version""1.23.6-00",
  "kubernetes_rpm_version""1.23.6-0",
  "kubernetes_semver""v1.23.6",
  "kubernetes_series""v1.23"

配置更新后,我们将使用 Ubuntu 20.04 build,用 packer 创建新的镜像。

cd <root_of_image_builder_repo>/images/capi
$ PACKER_VAR_FILES=oci.json make build-oci-ubuntu-2004

这将在 OCI 中启动一个实例来构建镜像。一旦完成,你应该得到镜像 OCID 的输出。你也可以通过访问 https://console.us-phoenix-1.oraclecloud.com/compute/images 来检查镜像是否已经建立。你将想保存这个 OCID,因为我们以后会用到它。

使用 Cluster API 升级我的集群

Cluster API 的主要目标[9]之一是

使用声明式 API 来管理符合 Kubernetes 的集群的生命周期(创建、扩展、升级、销毁)。

将升级过程自动化是一个很大的成就[10]。我不希望必须封锁 / 抽干节点来进行滚动更新。这些工具应该为我做到这一点。

我假设你已经有了一个管理和工作负载集群并正在运行。如果没有,请按照入门[11]指南来创建工作负载集群。下面是我如何创建工作负载集群的例子。

$ clusterctl generate cluster oci-cluster-phx --kubernetes-version v1.22.9 \  
--target-namespace default \  
--control-plane-machine-count=3 \  
--from https://github.com/oracle/cluster-api-provider-oci/releases/download/v.3.0/cluster-template.yaml | kubectl apply -f -

现在我们已经有了一个工作负载集群和一个新的镜像,现在是时候升级了。升级过程的步骤如下 :

  1. 升级 控制平面[12]
  2. 升级 工作母机[13]

在我们开始之前,让我们继续检查我们正在运行的工作负载集群的版本。为了访问我们的工作负载集群,我们需要从我们的管理集群导出 Kubernetes 配置

$ clusterctl get kubeconfig oci-cluster-phx -n default > oci-cluster-phx.kubeconfig

一旦我们有了 kubeconfig 文件,我们就可以检查我们工作负载集群的版本了。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig version

Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.4", GitCommit:"e6c093d87ea4cbb530a7b2ae91e54c0842d8308a", GitTreeState:"clean", BuildDate:"2022-02-16T12:38:05Z", GoVersion:"go1.17.7", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.9", GitCommit:"6df4433e288edc9c40c2e344eb336f63fad45cd2", GitTreeState:"clean", BuildDate:"2022-04-13T19:52:02Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}

注意服务器版本是 v1.22.9 。让我们来改变它。

升级控制平面

首先,让我们为控制平面制作一个机器模板的副本。

$ kubectl get ocimachinetemplate oci-cluster-phx-control-plane -o yaml > control-plane-machine-template.yaml

我们需要修改以下内容 :

  • spec.template.spec.imageId - 使用之前创建的自定义镜像 OCID
  • metadata.name - 用一个新的名字。例如。oci-cluster-phx-control-plane-v1-23-6

一旦字段被修改,我们就可以把它们应用到集群上。注意,这只会创建新的机器模板。下一步将触发实际的更新。

$ kubectl apply -f control-plane-machine-template.yaml

ocimachinetemplate.infrastructure.cluster.x-k8s.io/oci-cluster-phx-control-plane configured

我们现在要告诉 KubeadmControlPlane 资源关于新的机器模板并升级版本号。

把这个补丁文件保存为 kubeadm-control-plan-update.yaml

spec:
  machineTemplate:
    infrastructureRef:
      name: oci-cluster-phx-control-plane-v1-23-6
  version: v1.23.6

然后应用该补丁 :

$ kubectl patch --type=merge KubeadmControlPlane oci-cluster-phx-control-plane --patch-file kubeadm-control-plan-update.yaml

这将触发控制平面的滚动更新。

我们可以通过以下方式观察集群的进展 clusterctl

$ clusterctl describe cluster oci-cluster-phx                                                                                                                   
NAME                                                                READY  SEVERITY  REASON                   SINCE  MESSAGE
Cluster/oci-cluster-phx                                             False  Warning   RollingUpdateInProgress  98s    Rolling 3 replicas with outdated spec (1 replicas up to date)
├─ClusterInfrastructure - OCICluster/oci-cluster-phx                True                                      4h50m
├─ControlPlane - KubeadmControlPlane/oci-cluster-phx-control-plane  False  Warning   RollingUpdateInProgress  98s    Rolling 3 replicas with outdated spec (1 replicas up to date)
│ └─4 Machines...                                                   True                                      9m17s  See oci-cluster-phx-control-plane-ptg4m, oci-cluster-phx-control-plane-sg67j, ...
└─Workers
  └─MachineDeployment/oci-cluster-phx-md-0                          True                                      10m
    └─3 Machines...                                                 True                                      4h44m  See oci-cluster-phx-md-0-8667c8d69-47nh9, oci-cluster-phx-md-0-8667c8d69-5r4zc, ...

我们也可以看到随着新实例的创建,滚动更新开始发生。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig get nodes -A

NAME                                  STATUS     ROLES                  AGE     VERSION
oci-cluster-phx-control-plane-464zs   Ready      control-plane,master   4h40m   v1.22.5
oci-cluster-phx-control-plane-7vdxp   NotReady   control-plane,master   27s     v1.23.6
oci-cluster-phx-control-plane-dhxml   Ready      control-plane,master   4h48m   v1.22.5
oci-cluster-phx-control-plane-dmk8j   Ready      control-plane,master   4h44m   v1.22.5
oci-cluster-phx-md--cnrbf            Ready      <none>                 4h44m   v1.22.5
oci-cluster-phx-md--hc6fj            Ready      <none>                 4h45m   v1.22.5
oci-cluster-phx-md--nc2g9            Ready      <none>                 4h44m   v1.22.5

在终止一个控制平面实例之前,它将按照预期进行封锁和排水。

oci-cluster-phx-control-plane-dmk8j   NotReady,SchedulingDisabled   control-plane,master   4h52m   v1.22.5

这个过程应该需要 15 分钟左右。一旦所有的控制平面节点都升级了,你应该使用 kubectl version ,看到新的版本。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.4", GitCommit:"e6c093d87ea4cbb530a7b2ae91e54c0842d8308a", GitTreeState:"clean", BuildDate:"2022-02-16T12:38:05Z", GoVersion:"go1.17.7", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.6", GitCommit:"ad3338546da947756e8a88aa6822e9c11e7eac22", GitTreeState:"clean", BuildDate:"2022-04-14T08:43:11Z", GoVersion:"go1.17.9", Compiler:"gc", Platform:"linux/amd64"}

升级工作节点

在升级了控制平面节点之后,我们现在可以升级工作节点了cluster-api.sigs.k8s.io/tasks/updat…[14]

首先,我们需要做的是复制工作节点的机器模板。

$ kubectl get ocimachinetemplate oci-cluster-phx-md-0 -o yaml > worker-machine-template.yaml

你将需要修改以下内容

  • spec.template.spec.imageId - 使用之前创建的自定义图像 OCID
  • metadata.name - 用一个新的名字。例如。oci-cluster-phx-md-0-v1-23-6

一旦字段被修改,我们需要将它们应用于集群。和以前一样,这只是创建新的机器模板。下一步将开始实际的更新。

$ kubectl apply -f worker-machine-template.yaml

ocimachinetemplate.infrastructure.cluster.x-k8s.io/oci-cluster-phx-md-0-v1-23-6 created

我们现在要用我们刚刚创建的新资源来修改工人节点的 MachineDeployment

将此补丁文件保存为 worker-machine-deployment-update.yaml

spec:
  template:
    spec:
      infrastructureRef:
        name: oci-cluster-phx-md--v1-23-6
      version: v1.23.6

然后应用该补丁,这将触发机器部署的滚动更新。

$ kubectl patch --type=merge MachineDeployment oci-cluster-phx-md- --patch-file worker-machine-deployment-update.yaml

同样,我们可以通过 clusterctl 命令观察集群的进展。但与控制平面不同,机器部署处理更新工人机器。clusterctl describe cluster ,只显示机器部署正在更新。如果你想观察滚动更新的发生和新实例的创建,你可以做以下事情。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig get nodes -A

...

oci-cluster-phx-md--z59t8                   Ready,SchedulingDisabled   <none>                 55m    v1.22.5

oci-cluster-phx-md--z59t8                   NotReady,SchedulingDisabled   <none>                 56m     v1.22.5

如果你在工作母机上有 pod,你会看到它们被迁移到新机器上。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig get pods

NAME                          READY   STATUS       AGE     NODE
echoserver-55587b4c46-2q5hz   1/1     Terminating  89m    oci-cluster-phx-md-0-z59t8
echoserver-55587b4c46-4x72p   1/1     Running      5m24s  oci-cluster-phx-md-0-v1-23-6-bqs8l
echoserver-55587b4c46-tmj4b   1/1     Running      29s    oci-cluster-phx-md-0-v1-23-6-btjzs
echoserver-55587b4c46-vz7gm   1/1     Running      89m    oci-cluster-phx-md-0-z79bd

大约 10 或 15 分钟后,在我们的例子中,工人机应该被更新。很明显,你的节点越多,这个滚动更新就越长。你可以检查所有节点的版本来确认。

$ kubectl --kubeconfig=oci-cluster-phx.kubeconfig get nodes -A

NAME                                          STATUS                     ROLES                  AGE     VERSION
oci-cluster-phx-control-plane-v1-23-6-926gx   Ready                      control-plane,master   18m     v1.23.6
oci-cluster-phx-control-plane-v1-23-6-vfp5g   Ready                      control-plane,master   24m     v1.23.6
oci-cluster-phx-control-plane-v1-23-6-vprqc   Ready                      control-plane,master   30m     v1.23.6
oci-cluster-phx-md--v1-23-6-bqs8l            Ready                      <none>                 9m58s   v1.23.6
oci-cluster-phx-md--v1-23-6-btjzs            Ready                      <none>                 5m37s   v1.23.6
oci-cluster-phx-md--v1-23-6-z79bd            Ready                      <none>                 71s     v1.23.6

机器部署的策略

Cluster API 提供了两种 MachineDeployment 策略 RollingUpdateOnDelete

我们遵循的例子使用 RollingUpdate 。通过这个策略,你可以修改 maxSurgemaxUnavailable

maxSurgemaxUnavailable 的值都可以是一个数字(例如,5)或所需机器的百分比(例如,10%)。

另一个策略选项是 OnDelete 。这需要用户完全删除一台旧机器来驱动更新。当机器被完全删除后,新的机器就会出现。

结论

我们创建了一个新的镜像,并向集群的控制平面和工作节点推送了一个滚动升级,所有这些都是通过对我们的配置进行一些修改。无论集群是小是大,升级过程都是一样的。如果这还不是集群 API 的一个卖点,我不知道什么才是。

Cluster API 项目正在迅速发展,许多新功能即将推出。OCI Cluster[15] API 供应商团队正在努力工作,为 Cluster API 提供所有新的伟大功能,如 ClusterClass[16], MachinePools[17]ManagedClusters[18]

引用链接

[1]

Cluster API: https://cluster-api.sigs.k8s.io/

[2]

如果你不熟悉 Cluster API,它是 Kubernetes 的一个子项目,专注于提供声明式 API 和工具,以简化多个 Kubernetes 集群的配置、升级和操作: https://dzone.com/articles/introducing-the-kubernetes-cluster-api-project-2

[3]

这里: https://github.com/oracle/cluster-api-provider-oci

[4]

blogs.oracle.com/cloud-infra…: https://blogs.oracle.com/cloud-infrastructure/post/create-and-manage-kubernetes-clusters-on-oracle-cloud-infrastructure-with-cluster-api

[5]

我们的文档,以了解更多关于开始使用的信息: https://oracle.github.io/cluster-api-provider-oci/gs/overview.html

[6]

Kubernetes Image Builder: https://image-builder.sigs.k8s.io/capi/providers/oci.html

[7]

构建镜像: https://image-builder.sigs.k8s.io/capi/providers/oci.html%23building-images

[8]

kubernetes.io/releases/: https://kubernetes.io/releases/

[9]

主要目标: https://cluster-api.sigs.k8s.io/%23goals

[10]

将升级过程自动化是一个很大的成就: https://dzone.com/articles/kubernetes-upgrade-the-definitive-guide-to-do-it-yourself

[11]

入门: https://oracle.github.io/cluster-api-provider-oci/gs/gs.html

[12]

控制平面: https://dzone.com/refcardz/advanced-kubernetes

[13]

工作母机: https://dzone.com/refcardz/getting-started-kubernetes

[14]

cluster-api.sigs.k8s.io/tasks/updat…: https://cluster-api.sigs.k8s.io/tasks/updating-machine-templates.html

[15]

OCI Cluster: https://dzone.com/articles/5-best-security-practices-for-kubernetes-and-oracle-kubernetes-engine

[16]

ClusterClass: https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/index.html

[17]

MachinePools: https://cluster-api.sigs.k8s.io/tasks/experimental-features/machine-pools.html

[18]

ManagedClusters: https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster.html





相关文章