更新 Amazon EKS 集群 Kubernetes 版本 - Amazon EKS

更新 Amazon EKS 集群 Kubernetes 版本

当 Amazon EKS 中有新的 Kubernetes 版本可用时,您可以将 Amazon EKS 集群更新到最新版本。

重要

我们建议您在更新到新的 Kubernetes 版本之前,先查看 Amazon EKS Kubernetes 版本 中的信息,同时查看此主题中的更新步骤。如果您要更新到版本 1.22,您必须对集群进行 Kubernetes 版本 1.22 的先决条件 中列出的更改,然后再更新它。

新的 Kubernetes 版本有时会引入重大更改。因此,我们建议您先针对新的 Kubernetes 版本测试您应用程序的行为,然后再更新生产集群。您可以通过构建持续集成工作流来测试应用程序行为,然后再移至新的 Kubernetes 版本来执行此操作。

更新过程包含 Amazon EKS 随 Kubernetes 的更新版本推出新的 API 服务器节点,以取代现有此类节点。Amazon EKS 对这些新节点上的网络流量执行标准基础设施和就绪运行状况检查,以确认它们是否按预期工作。如果任意一项检查失败,Amazon EKS 都将恢复基础设施部署,且您的集群仍为先前的 Kubernetes 版本。正在运行的应用程序不会受影响,并且您的集群绝不会处于不确定性或不可恢复的状态。Amazon EKS 会定期备份所有托管的集群,并且具有在必要时恢复集群的机制。我们会不断评估和改进我们的 Kubernetes 基础设施管理流程。

为了升级集群,Amazon EKS 需要您在创建集群时指定的子网中的最多 5 个空闲 IP 地址。Amazon EKS 在您指定的任何子网中创建新的集群弹性网络接口(网络接口)。网络接口可能在不同于现有网络接口所在的子网中创建,因此请确保您的安全组规则允许您对创建集群时指定的任何子网进行所需的集群通信。如果您在创建集群时指定的任何子网不存在,没有足够的可用 IP 地址,或者没有允许必要的集群通信的安全组规则,则更新可能会失败。

注意

尽管 Amazon EKS 运行高度可用的控制层面,但您可能在更新期间遇到次要服务中断。例如,假设您在终止 API 服务器并使用运行新版 Kubernetes 的新 API 服务器替换此服务器时,尝试连接到此服务器。您可能会遇到 API 调用错误或连接问题。如果出现这种情况,请重试您的 API 操作直至成功。

更新 Amazon EKS 集群的 Kubernetes 版本

更新集群的 Kubernetes 版本的步骤

  1. 比较集群控制面板的 Kubernetes 版本与节点的 Kubernetes 版本。

    • 使用 kubectl version --short 命令获取集群控制面板的 Kubernetes 版本。

      kubectl version --short
    • 使用 kubectl get nodes 命令获取节点的 Kubernetes 版本。此命令会返回所有自我管理和托管的 Amazon EC2 和 Fargate 节点。每个 Fargate pod 都作为其自身的节点列出。

      kubectl get nodes

    将控制面板升级到新的 Kubernetes 版本之前,确保集群中的托管节点和 Fargate 节点的 Kubernetes 次要版本与控制面板的版本相同。例如,如果您的控制面板正在运行版本 1.22 且您的其中一个节点正在运行版本 1.21,则您必须将节点更新为版本 1.22。我们还建议您,在更新控制层面之前将自我管理节点更新为与控制层面相同的版本。有关更多信息,请参阅 更新托管节点组自行管理节点的更新。要更新 Fargate 节点的版本,请先删除节点所表示的 pod。然后更新您的控制面板。任何剩余的 pods 都将在重新部署之后更新到新版本。

  2. 默认情况下,Amazon EKS 集群上会启用 pod 安全策略准入控制器。在升级集群前,请确保已实施适当的 pod 安全策略。这是为了避免潜在的安全问题。您可以使用 kubectl get psp eks.privileged 命令检查默认策略。

    kubectl get psp eks.privileged

    如果您收到以下错误,请参阅默认 pod 安全策略,然后再继续操作。

    Error from server (NotFound): podsecuritypolicies.extensions "eks.privileged" not found
  3. 如果您最初部署集群所用的 Kubernetes 版本是 Kubernetes 1.18 或更高版本,请跳过此步骤。

    您可能需要从您的 CoreDNS 清单中删除已停用的术语。

    1. 检查您的 CoreDNS 清单是否有一行仅包含词语 upstream

      kubectl get configmap coredns -n kube-system -o jsonpath='{$.data.Corefile}' | grep upstream

      如果未返回任何输出,则说明您的清单没有此类行。如果是这样,请跳至下一步。如果返回了词语 upstream,则删除该行。

    2. 删除文件顶部附近在 configmap 文件中仅包含词语 upstream 的行。不要更改文件中的任何其他内容。删除该行后,保存更改。

      kubectl edit configmap coredns -n kube-system -o yaml
  4. 使用 eksctl、AWS Management Console 或 AWS CLI 更新您的集群。

    重要
    • 如果您要更新到版本 1.22,您必须对集群进行 Kubernetes 版本 1.22 的先决条件 中列出的更改,然后再更新它。

    • 如果您要在集群中更新到版本 1.23 并使用 Amazon EBS 卷,请在将集群更新为版本 1.23 之前,在集群中安装 Amazon EBS CSI 驱动程序,避免中断工作负载。有关更多信息,请参阅 Kubernetes 1.23Amazon EBS CSI 驱动程序

    • 由于 Amazon EKS 运行高度可用的控制层面,您可以一次只更新一个次要版本。有关此要求的更多信息,请参阅 Kubernetes 版本和版本偏差支持策略。假设集群的当前版本为 1.21,而且您想更新到 1.23,则必须先将集群更新为 1.22,再将集群从 1.22 更新到 1.23

    • 在更新之前,请确保您的托管节点和 Fargate 节点上的 kubelet 与控制面板的 Kubernetes 版本相同。我们建议您将自行管理节点保持在与控制面板相同的版本。它们最多只能比控制面板的当前版本落后一个版本。

    • 如果您的集群配置了早于 1.8.0 的 Amazon VPC CNI 插件版本,那么我们建议您将插件更新为版本 1.11.3,然后再将集群更新为版本 1.21 或更高版本。有关更多信息,请参阅 更新 Amazon VPC CNI plugin for Kubernetes 附加组件更新 Amazon VPC CNI plugin for Kubernetes 自行管理的附加组件

    eksctl

    此过程需要 eksctl 版本 0.110.0 或更高版本。可以使用以下命令来查看您的版本:

    eksctl version

    有关如何安装或更新 eksctl 的说明,请参阅 安装或更新 eksctl

    使用以下命令将 Amazon EKS 控制面板的 Kubernetes 版本更新到比当前版本高的一个次要版本。将 my-cluster 替换为您的集群名称。

    eksctl upgrade cluster --name my-cluster --approve

    更新过程可能需要几分钟才能完成。

    AWS Management Console
    1. 访问 https://console.aws.amazon.com/eks/home#/clusters 打开 Amazon EKS 控制台。

    2. 选择要更新的 Amazon EKS 集群的名称,然后选择 Update cluster version (更新集群版本)

    3. 对于 Kubernetes version(版本),选择集群要更新到的版本,然后选择 Update(更新)。

    4. 对于 Cluster name(集群名称),输入您的集群的名称并选择 Confirm(确认)。

      更新过程可能需要几分钟才能完成。

    AWS CLI
    1. 使用以下 AWS CLI 命令更新 Amazon EKS 集群。将 example values 替换为您自己的值。

      aws eks update-cluster-version \ --region region-code \ --name my-cluster \ --kubernetes-version 1.23

      输出示例如下。

      { "update": { "id": "b5f0ba18-9a87-4450-b5a0-825e6e84496f", "status": "InProgress", "type": "VersionUpdate", "params": [ { "type": "Version", "value": "1.23" }, { "type": "PlatformVersion", "value": "eks.1" } ], ... "errors": [] } }
    2. 使用以下命令监控集群更新的状态。使用上一命令返回的集群名称和更新 ID。当 Successful 状态显示时,更新完成。更新过程可能需要几分钟才能完成。

      aws eks describe-update \ --region region-code \ --name my-cluster \ --update-id b5f0ba18-9a87-4450-b5a0-825e6e84496f

      输出示例如下。

      { "update": { "id": "b5f0ba18-9a87-4450-b5a0-825e6e84496f", "status": "Successful", "type": "VersionUpdate", "params": [ { "type": "Version", "value": "1.23" }, { "type": "PlatformVersion", "value": "eks.1" } ], ... "errors": [] } }
  5. 集群更新完成后,将节点更新为与已更新的集群相同的 Kubernetes 次要版本。有关更多信息,请参阅 自行管理节点的更新更新托管节点组。在 Fargate 上启动的任何新 pods 都具有与您的集群版本匹配的 kubelet 版本。不会更改现有 Fargate pods。

  6. (可选)如果您在更新集群之前将 Kubernetes Cluster Autoscaler 部署到了集群,请将 Cluster Autoscaler 更新为与您升级后的 Kubernetes 主版本和次要版本匹配的最新版本。

    1. 在 Web 浏览器中打开 Cluster Autoscaler 版本页面,找到与您集群的 Kubernetes 主版本和次要版本相匹配的 Cluster Autoscaler 最新版本。例如,如果您集群的 Kubernetes 版本是 1.23,则查找以 1.23 开头的 Cluster Autoscaler 最新版本。记录该版本的语义版本号 (<1.23.n>) 以在下一步中使用。

    2. 使用以下命令,将 Cluster Autoscaler 映像标签设置为您在上一步中记录的版本。如有必要,将 1.23.n 替换为您自己的值。

      kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.23.n
  7. (仅限于具有 GPU 节点的集群)如果您的集群具有带 GPU 支持的节点组(例如,p3.2xlarge),则您必须使用以下命令在您的集群上更新适用于 Kubernetes 的 NVIDIA 设备插件 DaemonSet。

    kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml
  8. 更新 Amazon VPC CNI plugin for Kubernetes、CoreDNS 和 kube-proxy 附加组件。如果您将集群更新为版本 1.21 或更新版本,我们建议将附加组件更新为服务账户令牌中列出的最低版本。

    • 如果您将集群更新为版本 1.18,则可以添加 Amazon EKS 附加组件。有关说明,请参阅 添加 Amazon VPC CNI Amazon EKS 附加组件添加 CoreDNS Amazon EKS 附加组件添加 kube-proxy Amazon EKS 附加组件。要了解有关 Amazon EKS 附加组件的详情,请参阅 Amazon EKS 附加组件

    • 如果您已更新到 1.19 或更高版本,并且正在使用 Amazon EKS 附加组件,请在 Amazon EKS 控制台中选择 Clusters(集群),然后在左侧导航窗格中选择更新的集群的名称。控制台中显示通知。这些通知将告知您有一个新版本可用于每个具有可用更新的附加组件。要更新附加组件,请选择 Add-ons(附加组件)选项卡。在具有可用更新的附加组件的其中一个框中,选择 Update now(立即更新),选择一个可用版本,然后选择 Update(更新)

    • 此外,您也可以使用 AWS CLI 或 eksctl 更新 Amazon VPC CNI plugin for KubernetesCoreDNSkube-proxy Amazon EKS 附加组件。

Kubernetes 版本 1.22 的先决条件

许多已弃用的测试版 API(v1beta1)已在版本 1.22 中删除,以支持这些相同 API 的 GA(v1)版本。正如 Kubernetes 版本 1.22 API 和功能删除博客以及已弃用的 API 迁移指南中所提到的,在将集群更新为版本 1.22 之前,需要对以下部署的资源进行 API 更改。

在将集群更新为 Kubernetes 版本 1.22 之前,请确保执行以下操作:

  • 更改您的 YAML 清单文件和客户端以引用新 API。

  • 更新自定义集成和控制器以调用新的 API。

  • 确保使用任何第三方工具的更新版本。这些工具包括入口控制器、服务网格控制器、持续交付系统以及调用新 API 的其他工具。要检查集群中已停用的 API 使用情况,启用审计控制面板日志记录并将 v1beta 指定为事件筛选条件。Kubernetes 中提供了多个版本的替换 API。

  • 如果您目前有部署到集群的 AWS 负载均衡器控制器,您必须将其更新为版本 2.4.1,然后再将您的集群更新到 Kubernetes 版本 1.22

重要

当您将集群更新为版本 1.22 时,可以使用新 API 访问现有的持久化对象。但是,您必须迁移清单并更新客户端才能使用这些新 API。更新集群可防止潜在的工作负载故障。

Kubernetes 版本 1.22 从以下测试版 API 中删除了支持。根据以下信息迁移清单和 API 客户端:

资源 测试版本 目标版本 注意
ValidatingWebhookConfiguration MutatingWebhookConfiguration admissionregistration.k8s.io/v1beta1 admissionregistration.k8s.io/v1
  • v1webhooks[*].failurePolicy 默认设置已从 Ignore 更改为 Fail

  • v1webhooks[*].matchPolicy 默认设置已从 Exact 更改为 Equivalent

  • v1webhooks[*].timeoutSeconds 默认设置已从 30s 更改为 10s

  • webhooks[*].sideEffects 默认值被删除,字段变为必填字段,且仅 v1 只允许 NoneNoneOnDryRun

  • webhooks[*].admissionReviewVersions 默认值被删除,而且字段对于 v1 为必填字段(AdmissionReview 的支持的版本为 v1v1beta1)。

  • 对于通过 admissionregistration.k8s.io/v1 创建的对象,webhooks[*].name 在列表中必须是唯一的。

CustomResourceDefinition apiextensions.k8s.io/v1beta1 apiextensions.k8s.io/v1
  • spec.scope 不再默认设置为 Namespaced 并且必须明确指定。

  • spec.version 已在 v1 中删除,改用 spec.versions

  • spec.validation 已在 v1 中删除,改用 spec.versions[*].schema

  • spec.subresources 已在 v1 中删除,改用 spec.versions[*].subresources

  • spec.additionalPrinterColumns已在 v1 中删除;改用 spec.versions[*].additionalPrinterColumns

  • spec.conversion.webhookClientConfig 已在 v1 中迁移至 spec.conversion.webhook.clientConfig

  • spec.conversion.conversionReviewVersions 已在 v1 中迁移至 spec.conversion.webhook.conversionReviewVersions

  • spec.versions[*].schema.openAPIV3Schema 现在在创建 v1 CustomResourceDefinition 对象时是必填项,并且必须是结构化模式

  • 创建 v1 CustomResourceDefinition 时不允许 spec.preserveUnknownFields: true;必须在模式定义中将其指定为 x-kubernetes-preserve-unknown-fields: true

  • additionalPrinterColumns 项目中,JSONPath 字段在 v1 中被重命名为 jsonPath(修复 #66531)。

APIService apiregistration.k8s.io/v1beta1 apiregistration.k8s.io/v1 None(无)
TokenReview authentication.k8s.io/v1beta1 authentication.k8s.io/v1 None(无)
SubjectAccessReview LocalSubjectAccessReview SelfSubjectAccessReview authorization.k8s.io/v1beta1 authorization.k8s.io/v1 spec.group 已重命名为 spec.groups
CertificateSigningRequest certificates.k8s.io/v1beta1 certificates.k8s.io/v1
  • 对于请求证书的 API 客户端:

    • spec.signerName 现在是必需的(请参阅已知的 Kubernetes 签名者),且不允许通过 certificates.k8s.io/v1 API 创建 kubernetes.io/legacy-unknown 的请求

    • spec.usages 现在是必需的,可能不包含重复值,并且必须只包含已知的用法

  • 对于批准或签名证书的 API 客户端:

    • status.conditions 可能不包含重复的类型

    • 现在需要使用 status.conditions[*].status

    • status.certificate 必须是 PEM 编码的,并且只包含 CERTIFICATE

Lease

coordination.k8s.io/v1beta1 coordination.k8s.io/v1 None(无)

Ingress

  • extensions/v1beta1

  • networking.k8s.io/v1beta1

networking.k8s.io/v1
  • spec.backend 已重命名为 spec.defaultBackend

  • serviceName 字段被重命名为 service.name

  • 数字后端 servicePort 字段被重命名为 service.port.number

  • 字符串后端 servicePort 字段被重命名为 service.port.name

  • pathType 现在是每个指定路径的必填项。可选值有 PrefixExactImplementationSpecific。要匹配未定义的 v1beta1 行为,请使用 ImplementationSpecific

IngressClass

networking.k8s.io/v1beta1 networking.k8s.io/v1 None(无)

RBAC

rbac.authorization.k8s.io/v1beta1 rbac.authorization.k8s.io/v1
PriorityClass scheduling.k8s.io/v1beta1 scheduling.k8s.io/v1
CSIDriver CSINode StorageClass VolumeAttachment storage.k8s.io/v1beta1 storage.k8s.io/v1 None(无)

要了解有关 API 移除的更多信息,请参阅已弃用的 API 迁移指南