更新集群 - Amazon EKS

更新集群

您可以将现有 Amazon EKS 集群更新为新的 Kubernetes 版本,也可以为集群启用密钥加密

更新 Amazon EKS 集群 Kubernetes 版本

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

重要

我们建议您在更新到新的 Kubernetes 版本之前,请先查看 Amazon EKS Kubernetes 版本 中的信息和本主题中的更新步骤。

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

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

为了升级集群,Amazon EKS 需要您在创建集群时提供的子网中的 2-3 个空闲 IP 地址。如果这些子网没有可用的 IP 地址,则升级可能会失败。此外,如果在集群创建过程中提供的任何子网或安全组已被删除,则集群升级过程可能会失败。

注意

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

更新 Amazon EKS 集群的 Kubernetes 版本的步骤

更新集群的 Kubernetes 版本。

更新集群的 Kubernetes 版本的步骤

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

    • 使用以下命令获取集群控制层面的 Kubernetes 版本。

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

      kubectl get nodes

    集群中的托管节点和 Fargate 节点的 Kubernetes 次要版本必须与控制层面的当前版本相同,然后才能将控制层面更新为新的 Kubernetes 版本。例如,如果您的控制层面运行的是版本 1.20,任意节点运行的是版本 1.19,请在将控制层面的 Kubernetes 版本更新为 1.21 之前,先将节点更新为版本 1.20。我们还建议您,在更新控制层面之前将自我管理节点更新为与控制层面相同的版本。有关更多信息,请参阅 更新托管节点组自行管理节点的更新。要更新 Fargate 节点的版本,请删除节点所表示的 Pod,然后在更新控制层面后重新部署该 Pod。

  2. Amazon EKS 集群上原定设置已启用 Pod 安全策略准入控制器。在升级集群前,请确保在更新之前已实施适当的 Pod 安全策略,以避免出现任何问题。您可以使用以下命令检查默认策略:

    kubectl get psp eks.privileged

    如果您收到以下错误,请参阅原定设置 Pod 安全策略,然后再继续操作。

    Error from server (NotFound): podsecuritypolicies.extensions "eks.privileged" not found
  3. 如果您最初在 Kubernetes 1.17 或更早版本上部署了集群,那么您可能需要从 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 更新您的集群。

    重要
    • 由于 Amazon EKS 运行高度可用的控制层面,您可以一次只更新一个次要版本。请参阅 Kubernetes 版本和版本倾斜支持政策以了解此要求背后的原理。因此,如果您的当前版本为 1.19,并且您想要升级到 1.21,则必须先将集群升级到 1.20,然后再将它从 1.20 升级到 1.21。

    • 在更新之前,确保您的托管节点和 Fargate 节点上的 kubelet 与控制层面的 Kubernetes 版本相同。我们还建议,您的自我管理节点与控制层面的版本相同,尽管它们最多可以比控制层面的当前版本低一个版本。

    • 将集群更新到较新版本可能会覆盖自定义配置。

    eksctl

    此过程需要 eksctl 版本 0.84.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 (Kubernetes 版本),选择您的集群要更新到的版本并选择 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.21>

      输出:

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

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

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

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

      kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.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. 更新 VPC CNI、CoreDNS 和 kube-proxy 附加组件。

在现有集群中启用密钥加密

如果启用密钥加密,将使用您选择的 AWS KMS key 对 Kubernetes 密钥加密。KMS 密钥必须:

  • 对称

  • 能够加密和解密数据

  • 在与集群相同的区域中创建

  • 如果 KMS 密钥是在其他账户中创建的,则用户必须拥有对 KMS 密钥的访问权限。

有关更多信息,请参阅《AWS Key Management Service 开发人员指南》中的允许其他账户中的用户使用 KMS 密钥

警告

密钥加密启用后将无法禁用。此操作不可逆。

eksctl

可以通过下列两种方式启用加密:

  • 使用单个命令将加密添加到您的集群。

    要自动重新加密密码,请执行以下操作:

    eksctl utils enable-secrets-encryption / --cluster <my-cluster> / --key-arn arn:aws:kms:<Region-code>:<account>:key/<key>

    要选择退出自动重新加密密钥,请执行以下操作:

    eksctl utils enable-secrets-encryption --cluster <my-cluster> / --key-arn arn:aws:kms:<Region-code>:<account>:key/<key> / --encrypt-existing-secrets=false
  • 使用 .yaml 文件向集群添加加密。

    # cluster.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: <my-cluster> region: <Region-code> secretsEncryption: keyARN: arn:aws:kms:<Region-code>:<account>:key/<key>

    要自动重新加密密码,请执行以下操作:

    eksctl utils enable-secrets-encryption -f kms-cluster.yaml

    要选择退出自动重新加密密钥,请执行以下操作:

    eksctl utils enable-secrets-encryption -f kms-cluster.yaml --encrypt-existing-secrets=false
AWS Management Console
  1. 访问 https://console.aws.amazon.com/eks/home#/clusters 打开 Amazon EKS 控制台。

  2. 选择要向其添加 KMS 加密的集群。

  3. 选择 Configuration 选项卡。

  4. 向下滚动到 Secrets encryption(密钥加密)部分,然后选择 Enable(启用)按钮。

  5. 从下拉列表中选择一个密钥,然后选择 Enable(启用)按钮。如果未列出任何密钥,则必须先创建一个密钥。有关更多信息,请参阅创建密钥

  6. 选择 Confirm(确认)按钮以使用选定的密钥。

AWS CLI
  1. 使用以下 AWS CLI 命令将密钥加密配置与您的集群相关联。将 <example-values>(包括 <>)替换为您自己的值。

    aws eks associate-encryption-config \ --cluster-name <my-cluster> \ --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:<Region-code>:<account>:key/<key>"}}]'

    输出

    {   "update": {     "id": "<3141b835-8103-423a-8e68-12c2521ffa4d>",     "status": "InProgress",     "type": "AssociateEncryptionConfig",     "params": [       {         "type": "EncryptionConfig",         "value": "[{\"resources\":[\"secrets\"],\"provider\":{\"keyArn\":\"arn:aws:kms:<Region-code>:<account>:key/<key>\"}}]"       }     ],     "createdAt": <1613754188.734>,     "errors": []   } }
  2. 您可以使用以下命令监控加密更新的状态。使用上面步骤的输出中返回的 cluster nameupdate ID。当状态显示为 Successful 时,您的更新将完成。

    aws eks describe-update \ --region <Region-code> \ --name <my-cluster> \ --update-id <3141b835-8103-423a-8e68-12c2521ffa4d>

    输出

    {   "update": {     "id": "<3141b835-8103-423a-8e68-12c2521ffa4d>",     "status": "Successful",     "type": "AssociateEncryptionConfig",     "params": [       {         "type": "EncryptionConfig",         "value": "[{\"resources\":[\"secrets\"],\"provider\":{\"keyArn\":\"arn:aws:kms:<region-code>:<account>:key/<key>\"}}]"       }     ],     "createdAt": <1613754188.734>,     "errors": []   } }
  3. 要验证集群已启用加密,请运行 describe-cluster 命令。响应将包含 EncryptionConfig

    aws eks describe-cluster --region <Region-code> --name <my-cluster>

在集群上启用加密后,您需要使用新密钥加密所有现有密钥:

注意

如果您使用的是 eksctl,则除非选择退出自动重新加密密码,否则无需运行以下命令。

kubectl get secrets --all-namespaces -o json | kubectl annotate --overwrite -f - kms-encryption-timestamp="<time value>"
警告

如果您为现有集群启用密钥加密,并且您使用的密钥已被删除,那么将无法恢复集群。删除 KMS 密钥会将集群永久性置于降级状态。有关更多信息,请参阅删除 AWS KMS 密钥.。

注意

预设情况下,create-key 命令会创建一个具有密钥策略的对称密钥,该密钥策略向账户的根管理员授予对 AWS KMS 操作和资源的访问权限。如果要缩小权限的范围,请确保允许对将调用 create-cluster API 的委托人的策略执行 kms:DescribeKeykms:CreateGrant 操作。

Amazon EKS 不支持策略条件 kms:GrantIsForAWSResource。如果此操作位于 KMS 密钥策略语句中,则将无法创建集群。