本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。

自动升级

概述

您可以使用Rancher的Upgrade Controller管理K3s集群的升级。这是一种Kubernetes原生的集群升级方法。它利用一个https://github.com/rancher/system-upgrade-controller/blob/master/doc/plan.md#planspec[Plan]自定义资源来声明性地描述要升级的节点及其版本。

该计划定义了升级策略和要求。它还通过https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/[标签选择器]定义了哪些节点应该被升级。请参见下方适合升级K3s集群的默认计划。有关更高级的计划配置选项,请参见上面链接的计划文档。

Upgrade Controller通过监控计划并选择节点来调度升级,在这些节点上运行升级https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/[作业]。当作业成功完成后,控制器将相应地标记运行该作业的节点。

如果K3s集群由Rancher管理,您应该使用Rancher UI来管理升级。

  • 如果K3s集群已导入(注册)到Rancher,Rancher默认管理Upgrade Controller的部署和计划。除非您已在Rancher中禁用版本管理,否则请勿按照此页面上的步骤操作。 有关更多信息,请参见https://rancher.github.io/product-docs-playbook/rancher-manager/latest/en/cluster-deployment/register-existing-clusters.html#_configuring_version_management_for_suse_rancher_prime_rke2_and_suse_rancher_prime_k3s_clusters[为RKE2和K3s集群配置版本管理]。

  • 如果K3s集群由Rancher提供,Rancher使用系统代理来管理版本升级。请勿按照此页面上的步骤操作。

  • 如果K3s集群*不*由Rancher管理,您可以按照以下步骤操作。

使用Upgrade Controller

要自动化升级,您必须执行以下操作:

  1. 将Upgrade Controller安装到您的集群中

  2. 创建描述要升级的节点组及其方式的计划。

有关Upgrade Controller的设计和架构或其与 K3s 集成的更多详细信息,请参见以下 Git 仓库:

在尝试升级到新版本的 K3s 时,https://kubernetes.io/docs/setup/release/version-skew-policy/[Kubernetes 版本偏差策略]适用。确保您的计划在升级时不会跳过中间的小版本。系统升级控制器本身不会保护不支持的 Kubernetes 版本更改。

安装

Upgrade Controller清单安装了自定义资源定义、部署、服务帐户、集群角色绑定和配置映射。要安装这些组件,请运行以下命令:

kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/crd.yaml -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/system-upgrade-controller.yaml

可以通过前面提到的配置映射来配置和自定义Upgrade Controller,但必须删除控制器 Pod 才能应用更改。

配置

服务器节点应始终在代理节点之前升级。因此,建议您创建至少两个计划:一个用于升级服务器(控制平面)节点,另一个用于升级代理节点。您可以根据需要创建其他计划,以控制升级在节点之间的推出。在创建计划后,控制器会获取它们并开始升级您的集群。

以下两个示例计划通过针对稳定的发布通道,持续保持您的集群升级到当前稳定版本:

# Server plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: server-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/control-plane
      operator: In
      values:
      - "true"
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  channel: https://update.k3s.io/v1-release/channels/stable
---
# Agent plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: agent-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/control-plane
      operator: DoesNotExist
  prepare:
    args:
    - prepare
    - server-plan
    image: rancher/k3s-upgrade
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  channel: https://update.k3s.io/v1-release/channels/stable

关于这些计划,有几个重要事项需要指出:

  1. 计划必须在控制器部署的同一名称空间中创建。

  2. concurrency 字段指示可以同时升级多少个节点。

  3. 服务器计划通过指定选择具有 node-role.kubernetes.io/control-plane 标签的节点的标签选择器来针对服务器节点。代理计划通过指定选择没有该标签的节点的标签选择器来针对代理节点。

  4. 代理计划中的 prepare 步骤使该计划的升级作业在执行之前等待服务器计划完成。此逻辑内置于用于准备步骤的映像中,并不是Upgrade Controller本身的一部分。

  5. 两个计划的 channel 字段都设置为稳定版本通道的 URL。这使得控制器监控该 URL,并在其解析为新版本时升级集群。这与发布通道配合良好。因此,您可以使用以下通道配置您的计划,以确保您的集群始终自动升级到最新的 K3s 稳定版本。或者,您可以省略 channel 字段,并将 version 字段设置为 K3s 的特定版本:

    apiVersion: upgrade.cattle.io/v1
    kind: Plan
    # ...
    spec:
      # ...
      version: v1.33.4+k3s1

一旦控制器检测到计划的目标版本已被解析,无论是通过版本字段还是通过轮询通道服务器,升级便会开始。修改计划会导致控制器重新评估该计划,并确定是否需要另一次升级。如果已配置通道,URL 也会定期轮询以检查新版本。

您可以通过 kubectl 查看计划和作业来监控升级的进度:

kubectl -n system-upgrade get plans -o wide
kubectl -n system-upgrade get jobs

调度升级

通过在计划规范中设置 window 字段,可以限制计划在特定时间窗口内进行。时间窗口字段与 kured 调度选项 兼容,并采用相同的格式。例如:

apiVersion: upgrade.cattle.io/v1
kind: Plan
# ...
spec:
  # ...
  window:
    days:
      - monday
      - tuesday
      - wednesday
      - thursday
      - friday
    startTime: 19:00
    endTime: 21:00
    timeZone: UTC

用于执行计划升级的作业不会在时间窗口外创建。在作业创建后,计划可能会在窗口关闭后继续运行。

防止降级

版本门控

从 2023-07 版本开始 (v1.27.4+k3s1, v1.26.7+k3s1, v1.25.12+k3s1, v1.24.16+k3s1)

Kubernetes 不支持控制平面组件的降级。升级计划使用的 k3s-upgrade 映像将拒绝降级 K3s,从而使计划失败。在其计划中配置了 cordon: true 的节点在故障后将保持被隔离状态。

这是一个示例集群,显示了失败的升级 Pod 和被隔离的节点:

$ kubectl get pods -n system-upgrade
NAME                                                              READY   STATUS    RESTARTS   AGE
apply-k3s-server-on-ip-172-31-0-16-with-7af95590a5af8e8c3-2cdc6   0/1     Error     0          9m25s
apply-k3s-server-on-ip-172-31-10-23-with-7af95590a5af8e8c-9xvwg   0/1     Error     0          14m
apply-k3s-server-on-ip-172-31-13-213-with-7af95590a5af8e8-8j72v   0/1     Error     0          18m
system-upgrade-controller-7c4b84d5d9-kkzr6                        1/1     Running   0          20m
$ kubectl get nodes
NAME               STATUS                     ROLES                       AGE   VERSION
ip-172-31-0-16     Ready,SchedulingDisabled   control-plane,etcd,master   19h   v1.27.4+k3s1
ip-172-31-10-23    Ready,SchedulingDisabled   control-plane,etcd,master   19h   v1.27.4+k3s1
ip-172-31-13-213   Ready,SchedulingDisabled   control-plane,etcd,master   19h   v1.27.4+k3s1
ip-172-31-2-13     Ready                      <none>                      19h   v1.27.4+k3s1

您可以通过以下任一方法将被隔离的节点恢复服务:

  • 将您的计划中的版本或通道更改为目标版本,该版本与当前在集群上运行的版本相同或更新,以便计划成功。

  • 删除计划并手动解除节点的隔离。 使用 kubectl get plan -n system-upgrade 查找计划名称,然后使用 kubectl delete plan -n system-upgrade PLAN_NAME 删除它。一旦计划被删除,使用 kubectl uncordon NODE_NAME 解除每个节点的隔离。

安全性

启动的升级作业必须具有高度权限,以便对底层节点进行更改。默认情况下,它配置如下:

  • 主机 IPCNETPID 名称空间

  • CAP_SYS_BOOT 功能

  • 主机 root 挂载在 /host,具有读写权限