

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 在混合节点上运行本地工作负载
<a name="hybrid-nodes-tutorial"></a>

在启用了混合节点功能的 EKS 集群中，您可以使用与 AWS 云端相同的 Amazon EKS 集群、功能和工具，在自己的基础设施上运行本地和边缘应用程序。

以下章节包含有关使用混合节点的分步指导。

**Topics**
+ [连接混合节点](hybrid-nodes-join.md)
+ [连接使用 Bottlerocket 的混合节点](hybrid-nodes-bottlerocket.md)
+ [升级混合节点](hybrid-nodes-upgrade.md)
+ [修补混合节点](hybrid-nodes-security.md)
+ [删除混合节点](hybrid-nodes-remove.md)

# 连接混合节点
<a name="hybrid-nodes-join"></a>

**注意**  
以下步骤适用于运行除 Bottlerocket 以外的兼容操作系统的混合节点。有关连接运行 Bottlerocket 的混合节点的步骤，请参阅[连接使用 Bottlerocket 的混合节点](hybrid-nodes-bottlerocket.md)。

本主题介绍如何将混合节点连接到 Amazon EKS 集群。混合节点加入集群后，将在 Amazon EKS 控制台和兼容 Kubernetes 的工具（例如 kubectl）中显示并且状态为“未就绪”。完成本页介绍的步骤后，[为混合节点配置 CNI](hybrid-nodes-cni.md) 以确保混合节点可以随时用于运行应用程序。

## 先决条件
<a name="_prerequisites"></a>

在将混合节点连接到 Amazon EKS 集群之前，请确保您已完成先决步骤。
+ 您已建立从本地环境到托管 Amazon EKS 集群的 AWS 区域的连接。请参阅[准备混合节点的联网](hybrid-nodes-networking.md)了解更多信息。
+ 您已在本地主机上安装了适用于混合节点的兼容操作系统。请参阅[为混合节点准备操作系统](hybrid-nodes-os.md)了解更多信息。
+ 您已经创建了混合节点 IAM 角色并设置了本地凭证提供者（AWS Systems Manager 混合激活或 AWS IAM Roles Anywhere）。请参阅[准备用于混合节点的凭证](hybrid-nodes-creds.md)了解更多信息。
+ 您已经创建启用了混合节点的 Amazon EKS 集群。请参阅[创建具有混合节点的 Amazon EKS 集群](hybrid-nodes-cluster-create.md)了解更多信息。
+ 您已为您的混合节点 IAM 角色关联了 Kubernetes 基于角色的访问控制（RBAC）权限。请参阅[准备混合节点的集群访问权限](hybrid-nodes-cluster-prep.md)了解更多信息。

## 第 1 步：在每台本地主机上安装混合节点 CLI (`nodeadm`)
<a name="_step_1_install_the_hybrid_nodes_cli_nodeadm_on_each_on_premises_host"></a>

如果您预构建的操作系统映像已经包含 Amazon EKS 混合节点功能 CLI (`nodeadm`)，则可以跳过此步骤。有关 `nodeadm` 混合节点版本的更多信息，请参阅[混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md)。

`nodeadm` 的混合节点版本在 Amazon S3 中托管，由 Amazon CloudFront 分发。要在每台本地主机上安装 `nodeadm`，您可以在本地主机上运行以下命令。

 **x86\$164 主机：**

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/amd64/nodeadm'
```

 **ARM 主机** 

```
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
```

将可执行文件权限添加到每台主机上下载的二进制文件。

```
chmod +x nodeadm
```

## 第 2 步：使用 `nodeadm` 安装混合节点依赖项
<a name="_step_2_install_the_hybrid_nodes_dependencies_with_nodeadm"></a>

如果在预构建的操作系统映像中安装混合节点依赖项，则可以跳过此步骤。`nodeadm install` 命令可用于安装混合节点必需的所有依赖项。混合节点依赖项包括 containerd、kubelet、kubectl 以及 AWS SSM 或 AWS IAM Roles Anywhere 组件。要详细了解 [混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md) 安装的组件和文件位置，请参阅`nodeadm install`。要详细了解必须在本地防火墙中为 `nodeadm install` 进程允许的域，请参阅[准备混合节点的联网](hybrid-nodes-networking.md)。

运行以下命令，从而在本地主机上安装混合节点依赖项。运行以下命令的用户必须具有您主机上的 sudo/root 访问权限。

**重要**  
运行混合节点 CLI (`nodeadm`) 的用户必须具有您主机上的 sudo/root 访问权限。
+ 请 `K8S_VERSION` 替换为 Amazon EKS 集群的 Kubernetes 次要版本，例如 `1.31`。有关支持的 Kubernetes 版本的列表，请参阅 [Amazon EKS 支持的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。
+ 请将 `CREDS_PROVIDER` 替换为您使用的本地凭证提供者。AWS SSM 的有效值为 `ssm`，AWS IAM Roles Anywhere 的有效值为 `iam-ra`。

```
nodeadm install K8S_VERSION --credential-provider CREDS_PROVIDER
```

## 第 3 步：将混合节点连接到集群
<a name="_step_3_connect_hybrid_nodes_to_your_cluster"></a>

在将混合节点连接到集群之前，请确保您的本地防火墙和集群安全组中已经允许在 Amazon EKS 控制面板与混合节点之间进行通信所必需的权限。此步骤中出现的大多数问题都与防火墙配置、安全组配置或混合节点 IAM 角色配置有关。

**重要**  
运行混合节点 CLI (`nodeadm`) 的用户必须具有您主机上的 sudo/root 访问权限。

1. 在每台主机上创建一个包含适用于部署的值的 `nodeConfig.yaml` 文件。有关可用配置设置的完整说明，请参阅[混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md)。如果混合节点 IAM 角色没有执行 `eks:DescribeCluster` 操作的权限，则必须在 `nodeConfig.yaml` 的集群部分中传递 Kubernetes API 端点、集群 CA 捆绑和 Kubernetes 服务 IPv4 CIDR。

   1. 如果您的本地凭证提供者为 AWS SSM 混合激活，请使用以下 `nodeConfig.yaml` 示例。

      1. 将 `CLUSTER_NAME` 替换为您的集群名称。

      1. 请将 AWS 替换为集群所在的 `AWS_REGION` 区域。例如 `us-west-2`。

      1. 请将 `ACTIVATION_CODE` 替换为创建 AWS SSM 混合激活时收到的激活码。请参阅[准备用于混合节点的凭证](hybrid-nodes-creds.md)了解更多信息。

      1. 请将 `ACTIVATION_ID` 替换为创建 AWS SSM 混合激活时收到的激活 ID。您可以通过 AWS Systems Manager 控制台或 AWS CLI `aws ssm describe-activations` 命令查看此信息。

         ```
         apiVersion: node.eks.aws/v1alpha1
         kind: NodeConfig
         spec:
           cluster:
             name: CLUSTER_NAME
             region: AWS_REGION
           hybrid:
             ssm:
               activationCode: ACTIVATION_CODE
               activationId: ACTIVATION_ID
         ```

   1. 如果您的本地凭证提供者为 AWS IAM Roles Anywhere，请使用以下 `nodeConfig.yaml` 示例。

      1. 将 `CLUSTER_NAME` 替换为您的集群名称。

      1. 请将 AWS 替换为集群所在的 `AWS_REGION` 区域。例如 `us-west-2`。

      1. 请将 `NODE_NAME` 替换为节点的名称。如果您为混合节点 IAM 角色配置的信任策略使用 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 资源条件，则节点名称必须与主机上证书的 CN 一致。您使用的 `nodeName` 长度不得超过 64 个字符。

      1. 请将 `TRUST_ANCHOR_ARN` 替换为您在“准备用于混合节点的凭证”步骤中配置的信任锚的 ARN。

      1. 请将 `PROFILE_ARN` 替换为您在“[准备用于混合节点的凭证](hybrid-nodes-creds.md)”步骤中配置的信任锚的 ARN。

      1. 将 `ROLE_ARN` 替换为混合节点 IAM 角色的 ARN。

      1. 请将 `CERTIFICATE_PATH` 替换为磁盘中指向节点证书的路径。如果不指定此参数，则默认值为 `/etc/iam/pki/server.pem`。

      1. 请将 `KEY_PATH` 替换为磁盘中指向证书私有密钥的路径。如果不指定此参数，则默认值为 `/etc/iam/pki/server.key`。

         ```
         apiVersion: node.eks.aws/v1alpha1
         kind: NodeConfig
         spec:
           cluster:
             name: CLUSTER_NAME
             region: AWS_REGION
           hybrid:
             iamRolesAnywhere:
               nodeName: NODE_NAME
               trustAnchorArn: TRUST_ANCHOR_ARN
               profileArn: PROFILE_ARN
               roleArn: ROLE_ARN
               certificatePath: CERTIFICATE_PATH
               privateKeyPath: KEY_PATH
         ```

1. 使用您的 `nodeConfig.yaml` 运行 `nodeadm init` 命令，从而将混合节点连接到 Amazon EKS 集群。

   ```
   nodeadm init -c file://nodeConfig.yaml
   ```

如果上述命令成功完成，则表示混合节点已加入您的 Amazon EKS 集群。您可以在 Amazon EKS 控制台中导航到集群的“计算”选项卡（[确保 IAM 主体具有查看权限](view-kubernetes-resources.md#view-kubernetes-resources-permissions)）或使用 `kubectl get nodes` 来验证此信息。

**重要**  
您的节点将处于 `Not Ready` 状态，此状态符合预期，是因混合节点上缺少正在运行的 CNI 所致。如果节点未加入集群，请参阅[混合节点故障排除](hybrid-nodes-troubleshooting.md)。

## 第 4 步：为混合节点配置 CNI
<a name="_step_4_configure_a_cni_for_hybrid_nodes"></a>

要使混合节点能够随时运行应用程序，请继续完成[为混合节点配置 CNI](hybrid-nodes-cni.md)中的步骤。

# 连接使用 Bottlerocket 的混合节点
<a name="hybrid-nodes-bottlerocket"></a>

本主题介绍如何将运行 Bottlerocket 的混合节点连接到 Amazon EKS 集群。[Bottlerocket](https://aws.amazon.com/bottlerocket/) 是由 AWS 赞助并提供支持的开源 Linux 发行版。Bottlerocket 专为托管容器工作负载而构建。您可以借助 Bottlerocket 实现容器基础设施自动更新，由此提高容器化部署的可用性，降低运营成本。Bottlerocket 仅包含运行容器所需的必备软件，可提高资源利用率、减少安全威胁并降低管理开销。

仅支持将 Bottlerocket 版本 v1.37.0 及更高版本的 VMware 变体与 EKS 混合节点结合使用。Bottlerocket 的 VMware 变体支持 Kubernetes 版本 1.28 及更高版本。这些变体的操作系统映像包括 kubelet、containerd、aws-iam-authenticator 以及适用于 EKS 混合节点功能的其他软件先决条件。您可以使用 Bottlerocket [设置](https://github.com/bottlerocket-os/bottlerocket#settings)文件来配置这些组件，该文件包含用于 Bottlerocket 引导容器和管理容器的 base64 编码用户数据。通过配置这些设置，可让 Bottlerocket 使用您的混合节点凭证提供程序来完成集群对混合节点的身份验证。混合节点加入集群后，将在 Amazon EKS 控制台以及 `kubectl` 等兼容 Kubernetes 的工具中显示并且状态为 `Not Ready`。完成本页介绍的步骤后，[为混合节点配置 CNI](hybrid-nodes-cni.md) 以确保混合节点可以随时用于运行应用程序。

## 先决条件
<a name="_prerequisites"></a>

在将混合节点连接到 Amazon EKS 集群之前，请确保您已完成先决步骤。
+ 您已建立从本地环境到托管 Amazon EKS 集群的 AWS 区域的连接。请参阅[准备混合节点的联网](hybrid-nodes-networking.md)了解更多信息。
+ 您已经创建了混合节点 IAM 角色并设置了本地凭证提供者（AWS Systems Manager 混合激活或 AWS IAM Roles Anywhere）。请参阅[准备用于混合节点的凭证](hybrid-nodes-creds.md)了解更多信息。
+ 您已经创建启用了混合节点的 Amazon EKS 集群。请参阅[创建具有混合节点的 Amazon EKS 集群](hybrid-nodes-cluster-create.md)了解更多信息。
+ 您已为您的混合节点 IAM 角色关联了 Kubernetes 基于角色的访问控制（RBAC）权限。请参阅[准备混合节点的集群访问权限](hybrid-nodes-cluster-prep.md)了解更多信息。

## 第 1 步：创建 Bottlerocket 设置 TOML 文件
<a name="_step_1_create_the_bottlerocket_settings_toml_file"></a>

要为混合节点配置 Bottlerocket，您需要创建一个包含必要配置的 `settings.toml` 文件。TOML 文件的内容因您使用的凭证提供程序（SSM 或 IAM Roles Anywhere）而异。在预置 Bottlerocket 实例时，此文件将作为用户数据传递。

**注意**  
下方提供的 TOML 文件仅包含将 Bottlerocket VMWare 机器初始化为 EKS 集群节点所需的最低配置项。Bottlerocket 提供了丰富的配置项，可满足多种不同的使用案例。因此，若需配置混合节点初始化之外的更多功能，请查阅 [Bottlerocket 文档](https://bottlerocket.dev/en)，获取所使用版本的完整配置项列表（例如，[此处](https://bottlerocket.dev/en/os/1.51.x/api/settings-index)列出了 Bottlerocket 1.51.x 版本的全部可用配置项）。

### SSM
<a name="_ssm"></a>

如果将 AWS Systems Manager 作为凭证提供程序，请创建一个包含以下内容的 `settings.toml` 文件：

```
[settings.kubernetes]
cluster-name = "<cluster-name>"
api-server = "<api-server-endpoint>"
cluster-certificate = "<cluster-certificate-authority>"
hostname-override = "<hostname>"
provider-id = "eks-hybrid:///<region>/<cluster-name>/<hostname>"
authentication-mode = "aws"
cloud-provider = ""
server-tls-bootstrap = true

[settings.network]
hostname = "<hostname>"

[settings.aws]
region = "<region>"

[settings.kubernetes.credential-providers.ecr-credential-provider]
enabled = true
cache-duration = "12h"
image-patterns = [
    "*.dkr.ecr.*.amazonaws.com",
    "*.dkr.ecr.*.amazonaws.com.rproxy.govskope.us.cn",
    "*.dkr.ecr.*.amazonaws.eu",
    "*.dkr.ecr-fips.*.amazonaws.com",
    "*.dkr.ecr-fips.*.amazonaws.eu",
    "public.ecr.aws"
]

[settings.kubernetes.node-labels]
"eks.amazonaws.com/compute-type" = "hybrid"
"eks.amazonaws.com/hybrid-credential-provider" = "ssm"

[settings.host-containers.admin]
enabled = true
user-data = "<base64-encoded-admin-container-userdata>"

[settings.bootstrap-containers.eks-hybrid-setup]
mode = "always"
user-data = "<base64-encoded-bootstrap-container-userdata>"

[settings.host-containers.control]
enabled = true
```

将占位符替换为以下值：
+  `<cluster-name>`：Amazon EKS 集群的名称。
+  `<api-server-endpoint>`：集群的 API 服务器端点。
+  `<cluster-certificate-authority>`：集群的 base64 编码 CA 捆绑包。
+  `<region>`：托管集群的 AWS 区域，例如“us-east-1”。
+  `<hostname>`：Bottlerocket 实例的主机名，这也将被配置为节点名称。这可以是您选择的任何唯一值，但必须符合 [Kubernetes 对象命名惯例](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)。此外，使用的主机名称长度不能超过 64 个字符。注意：使用 SSM 提供程序时，在将实例注册到 SSM 后，该主机名和节点名称将替换为托管实例 ID（例如，`mi-*` ID）。
+  `<base64-encoded-admin-container-userdata>`：Bottlerocket 管理容器配置的 base64 编码内容。启用管理容器后，您将能够通过 SSH 连接到 Bottlerocket 实例，以便进行系统探索和调试。虽然这不是必需设置，但为了便于故障排除，我们建议将其启用。有关使用管理容器进行身份验证的更多信息，请参阅 [Bottlerocket 管理容器文档](https://github.com/bottlerocket-os/bottlerocket-admin-container#authenticating-with-the-admin-container)。例如，管理容器接受 JSON 格式的 SSH 用户和密钥输入。

```
{
  "user": "<ssh-user>",
  "ssh": {
    "authorized-keys": [
      "<ssh-authorized-key>"
    ]
  }
}
```
+  `<base64-encoded-bootstrap-container-userdata>`：Bottlerocket 引导容器配置的 base64 编码内容。有关其配置的更多信息，请参阅 [Bottlerocket 引导容器文档](https://github.com/bottlerocket-os/bottlerocket-bootstrap-container)。引导容器负责将实例注册为 AWS SSM 托管式实例，并将其作为 Kubernetes 节点加入 Amazon EKS 集群。传递到引导容器的用户数据采用命令调用的形式，这会将您之前创建的 SSM 混合激活码和 ID 作为输入接受：

```
eks-hybrid-ssm-setup --activation-id=<activation-id> --activation-code=<activation-code> --region=<region>
```

### IAM Roles Anywhere
<a name="_iam_roles_anywhere"></a>

如果将 AWS IAM Roles Anywhere 作为凭证提供程序，请创建一个包含以下内容的 `settings.toml` 文件：

```
[settings.kubernetes]
cluster-name = "<cluster-name>"
api-server = "<api-server-endpoint>"
cluster-certificate = "<cluster-certificate-authority>"
hostname-override = "<hostname>"
provider-id = "eks-hybrid:///<region>/<cluster-name>/<hostname>"
authentication-mode = "aws"
cloud-provider = ""
server-tls-bootstrap = true

[settings.network]
hostname = "<hostname>"

[settings.aws]
region = "<region>"
config = "<base64-encoded-aws-config-file>"

[settings.kubernetes.credential-providers.ecr-credential-provider]
enabled = true
cache-duration = "12h"
image-patterns = [
    "*.dkr.ecr.*.amazonaws.com",
    "*.dkr.ecr.*.amazonaws.com.rproxy.govskope.us.cn",
    "*.dkr.ecr.*.amazonaws.eu",
    "*.dkr.ecr-fips.*.amazonaws.com",
    "*.dkr.ecr-fips.*.amazonaws.eu",
    "public.ecr.aws"
]

[settings.kubernetes.node-labels]
"eks.amazonaws.com/compute-type" = "hybrid"
"eks.amazonaws.com/hybrid-credential-provider" = "iam-ra"

[settings.host-containers.admin]
enabled = true
user-data = "<base64-encoded-admin-container-userdata>"

[settings.bootstrap-containers.eks-hybrid-setup]
mode = "always"
user-data = "<base64-encoded-bootstrap-container-userdata>"
```

将占位符替换为以下值：
+  `<cluster-name>`：Amazon EKS 集群的名称。
+  `<api-server-endpoint>`：集群的 API 服务器端点。
+  `<cluster-certificate-authority>`：集群的 base64 编码 CA 捆绑包。
+  `<region>`：托管集群的 AWS 区域，例如“us-east-1”
+  `<hostname>`：Bottlerocket 实例的主机名，这也将被配置为节点名称。这可以是您选择的任何唯一值，但必须符合 [Kubernetes 对象命名惯例](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names)。此外，使用的主机名称长度不能超过 64 个字符。注意：使用 IAM-RA 提供程序时，如果您为混合节点 IAM 角色配置的信任策略使用 `"sts:RoleSessionName": "${aws:PrincipalTag/x509Subject/CN}"` 资源条件，则节点名称必须与主机上证书的 CN 一致。
+  `<base64-encoded-aws-config-file>`：AWS 配置文件的 Base64 编码内容。该文件的内容应会如下所示：

```
[default]
credential_process = aws_signing_helper credential-process --certificate /root/.aws/node.crt --private-key /root/.aws/node.key --profile-arn <profile-arn> --role-arn <role-arn> --trust-anchor-arn <trust-anchor-arn> --role-session-name <role-session-name>
```
+  `<base64-encoded-admin-container-userdata>`：Bottlerocket 管理容器配置的 base64 编码内容。启用管理容器后，您将能够通过 SSH 连接到 Bottlerocket 实例，以便进行系统探索和调试。虽然这不是必需设置，但为了便于故障排除，我们建议将其启用。有关使用管理容器进行身份验证的更多信息，请参阅 [Bottlerocket 管理容器文档](https://github.com/bottlerocket-os/bottlerocket-admin-container#authenticating-with-the-admin-container)。例如，管理容器接受 JSON 格式的 SSH 用户和密钥输入。

```
{
  "user": "<ssh-user>",
  "ssh": {
    "authorized-keys": [
      "<ssh-authorized-key>"
    ]
  }
}
```
+  `<base64-encoded-bootstrap-container-userdata>`：Bottlerocket 引导容器配置的 base64 编码内容。有关其配置的更多信息，请参阅 [Bottlerocket 引导容器文档](https://github.com/bottlerocket-os/bottlerocket-bootstrap-container)。引导容器负责在实例上创建 IAM Roles Anywhere 主机证书和证书私有密钥文件。然后，`aws_signing_helper` 将会使用这些证书和文件来获取临时证书，以用于 Amazon EKS 集群身份验证。传递到引导容器的用户数据采用命令调用的形式，这会将您之前创建的证书和私有密钥内容作为输入接受：

```
eks-hybrid-iam-ra-setup --certificate=<certificate> --key=<private-key>
```

## 第 2 步：预置 Bottlerocket vSphere 虚拟机及用户数据
<a name="_step_2_provision_the_bottlerocket_vsphere_vm_with_user_data"></a>

构造 TOML 文件后，在创建 vSphere 虚拟机期间将其传递为用户数据。请注意，在虚拟机首次开机之前，必须配置用户数据。因此，您需要在创建实例时提供用户数据；如果您希望先行创建虚拟机，则在您为其配置用户数据前，虚拟机必须处于关机状态。例如，假设使用 `govc` CLI：

### 首次创建虚拟机
<a name="_creating_vm_for_the_first_time"></a>

```
govc vm.create \
  -on=true \
  -c=2 \
  -m=4096 \
  -net.adapter=<network-adapter> \
  -net=<network-name> \
  -e guestinfo.userdata.encoding="base64" \
  -e guestinfo.userdata="$(base64 -w0 settings.toml)" \
  -template=<template-name> \
  <vm-name>
```

### 更新现有虚拟机的用户数据
<a name="_updating_user_data_for_an_existing_vm"></a>

```
govc vm.create \
    -on=false \
    -c=2 \
    -m=4096 \
    -net.adapter=<network-adapter> \
    -net=<network-name> \
    -template=<template-name> \
    <vm-name>

govc vm.change
    -vm <vm-name> \
    -e guestinfo.userdata="$(base64 -w0 settings.toml)" \
    -e guestinfo.userdata.encoding="base64"

govc vm.power -on <vm-name>
```

在以上章节中，`-e guestinfo.userdata.encoding="base64"` 选项用于指定用户数据采用 base64 编码。`-e guestinfo.userdata` 选项将 `settings.toml` 文件的 base64 编码内容作为用户数据传递给 Bottlerocket 实例。将占位符替换为您的具体值，例如 Bottlerocket OVA 模板和联网详细信息。

## 第 3 步：验证混合节点连接
<a name="_step_3_verify_the_hybrid_node_connection"></a>

Bottlerocket 实例启动后，将会尝试加入您的 Amazon EKS 集群。您可以在 Amazon EKS 控制台中导航到集群的“计算”选项卡或运行以下命令，从而验证连接：

```
kubectl get nodes
```

**重要**  
您的节点将处于 `Not Ready` 状态，此状态符合预期，是因混合节点上缺少正在运行的 CNI 所致。如果节点未加入集群，请参阅[混合节点故障排除](hybrid-nodes-troubleshooting.md)。

## 第 4 步：为混合节点配置 CNI
<a name="_step_4_configure_a_cni_for_hybrid_nodes"></a>

要使混合节点能够随时运行应用程序，请继续完成[为混合节点配置 CNI](hybrid-nodes-cni.md)中的步骤。

# 升级集群的混合节点
<a name="hybrid-nodes-upgrade"></a>

升级混合节点的指南与在 Amazon EC2 中运行的自主管理型 Amazon EKS 节点类似。我们建议您在目标 Kubernetes 版本上创建新的混合节点，从容地将现有应用程序迁移到新 Kubernetes 版本上的混合节点，然后再从集群中移除旧 Kubernetes 版本上的混合节点。在开始升级之前，请务必检查 [Amazon EKS 升级最佳实践](https://docs.aws.amazon.com/eks/latest/best-practices/cluster-upgrades.html)。Amazon EKS 混合节点功能[支持的 Kubernetes 版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)与具有云节点的 Amazon EKS 集群相同，包括标准和扩展支持。

Amazon EKS 混合节点功能使用的节点[版本偏斜策略](https://kubernetes.io/releases/version-skew-policy/#supported-version-skew)与上游 Kubernetes 相同。Amazon EKS 混合节点功能不能使用比 Amazon EKS 控制面板更高的版本，混合节点的 Kubernetes 次要版本最多可比 Amazon EKS 控制面板早三个次要版本。

如果您没有剩余容量可用来创建具有目标 Kubernetes 版本的新混合节点，以满足割接迁移升级策略的需要，则可以使用 Amazon EKS 混合节点 CLI (`nodeadm`) 就地升级混合节点的 Kubernetes 版本。

**重要**  
如果您使用 `nodeadm` 就地升级混合节点，则在关闭旧版本的 Kubernetes 组件以及安装和启动新的 Kubernetes 版本组件的过程中，节点会有停机时间。

## 先决条件
<a name="_prerequisites"></a>

在升级之前，请确保您已满足以下先决条件。
+ 升级混合节点的目标 Kubernetes 版本必须等于或早于 Amazon EKS 控制面板的版本。
+ 如果您遵循割接迁移升级策略，则在目标 Kubernetes 版本上安装的新混合节点必须满足[混合节点的先决条件设置](hybrid-nodes-prereqs.md)要求。这包括拥有在创建 Amazon EKS 集群期间传递的远程节点网络 CIDR 中的 IP 地址。
+ 无论是割接迁移升级还是就地升级，混合节点必须有权访问[所需的域](hybrid-nodes-networking.md#hybrid-nodes-networking-on-prem)才能拉取混合节点依赖项的新版本。
+ 您必须已在本地计算机或用于与 Amazon EKS Kubernetes API 端点进行交互的实例上安装 kubectl。
+ 您的 CNI 版本必须支持要升级到的 Kubernetes 版本。如果不支持，请在升级混合节点之前先升级 CNI 版本。请参阅[为混合节点配置 CNI](hybrid-nodes-cni.md)了解更多信息。

## 割接迁移（蓝绿迁移）升级
<a name="hybrid-nodes-upgrade-cutover"></a>

 *割接迁移升级*是指首先在新主机上创建具有目标 Kubernetes 版本的新混合节点，从容地将现有应用程序迁移到目标 Kubernetes 版本的新混合节点，然后再从集群中移除旧 Kubernetes 版本的混合节点的过程。这种策略也称为蓝绿迁移。

1. 按照 [连接混合节点](hybrid-nodes-join.md) 步骤将新主机作为混合节点连接。运行 `nodeadm install` 命令时，请使用目标 Kubernetes 版本。

1. 启用目标 Kubernetes 版本的新混合节点与旧 Kubernetes 版本的混合节点之间的通信。此配置让容器组可在将工作负载迁移到目标 Kubernetes 版本的混合节点后进行相互通信。

1. 确认目标 Kubernetes 版本的混合节点已成功加入集群并处于“就绪”状态。

1. 使用以下命令，将要移除的每个节点标记为不可调度。这样可确保新容器组不会在要替换的节点上调度或重新调度。有关更多信息，请参阅 Kubernetes 文档中的 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)。请将 `NODE_NAME` 替换为旧 Kubernetes 版本混合节点的名称。

   ```
   kubectl cordon NODE_NAME
   ```

   您可以使用以下代码段标识并封锁使用特定 Kubernetes 版本（此示例中为版本 `1.28`）的所有节点。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Cordoning $node"
       kubectl cordon $node
   done
   ```

1. 如果混合节点上当前部署运行的 CoreDNS 副本少于 2 个，请将部署横向扩展到至少 2 个副本。我们建议您在混合节点上运行至少两个 CoreDNS 副本，以确保正常运行期间的恢复能力。

   ```
   kubectl scale deployments/coredns --replicas=2 -n kube-system
   ```

1. 使用以下命令清空要从集群中删除的每个使用旧版本 Kubernetes 的混合节点。有关清空节点的更多信息，请参阅 Kubernetes 文档中的[安全地清空一个节点](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。请将 `NODE_NAME` 替换为旧 Kubernetes 版本混合节点的名称。

   ```
   kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
   ```

   您可以使用以下代码段标识并清空特定 Kubernetes 版本（此示例中为版本 `1.28`）的所有节点。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Draining $node"
       kubectl drain $node --ignore-daemonsets --delete-emptydir-data
   done
   ```

1. 您可以使用 `nodeadm` 停止混合节点构件并将其从主机中移除。您必须使用具有 root/sudo 权限的用户运行 `nodeadm`。默认情况下，如果节点上还有容器组，则 `nodeadm uninstall` 不会执行。有关更多信息，请参阅 [混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md)。

   ```
   nodeadm uninstall
   ```

1. 停止并卸载混合节点构件后，从集群中移除节点资源。

   ```
   kubectl delete node node-name
   ```

   您可以使用以下代码段标识并删除特定 Kubernetes 版本（此示例中为版本 `1.28`）的所有节点。

   ```
   K8S_VERSION=1.28
   for node in $(kubectl get nodes -o json | jq --arg K8S_VERSION "$K8S_VERSION" -r '.items[] | select(.status.nodeInfo.kubeletVersion | match("\($K8S_VERSION)")).metadata.name')
   do
       echo "Deleting $node"
       kubectl delete node $node
   done
   ```

1. 运行上述步骤后，您的混合节点上可能会剩下一些构件，具体取决于您选择的 CNI。请参阅[为混合节点配置 CNI](hybrid-nodes-cni.md)了解更多信息。

## 就地升级
<a name="hybrid-nodes-upgrade-inplace"></a>

就地升级过程是指使用 `nodeadm upgrade` 升级混合节点的 Kubernetes 版本，而不使用新的物理或虚拟主机和割接迁移策略。`nodeadm upgrade` 进程会关闭在混合节点上运行的现有较早版本的 Kubernetes 组件，卸载现有较早版本的 Kubernetes 组件，安装新的目标 Kubernetes 组件，然后启动新的目标 Kubernetes 组件。强烈建议一次升级一个节点，以尽可能减少对混合节点上运行的应用程序的影响。此过程的持续时间取决于网络带宽和延迟。

1. 使用以下命令将要升级的节点标记为不可调度。这样可确保新容器组不会在要升级的节点上调度或重新调度。有关更多信息，请参阅 Kubernetes 文档中的 [kubectl cordon](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_cordon/)。请将 `NODE_NAME` 替换为要升级的混合节点的名称

   ```
   kubectl cordon NODE_NAME
   ```

1. 使用以下命令清空您要升级的节点。有关清空节点的更多信息，请参阅 Kubernetes 文档中的[安全地清空一个节点](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。请将 `NODE_NAME` 替换为要升级的混合节点的名称。

   ```
   kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
   ```

1. 在要升级的混合节点上运行 `nodeadm upgrade`。您必须使用具有 root/sudo 权限的用户运行 `nodeadm`。无论是使用 AWS SSM 还是 AWS IAM Roles Anywhere 凭证提供者，节点名称都会通过升级保留。在升级过程中，您无法更改凭证提供者。有关 `nodeConfig.yaml` 的配置值，请参阅 [混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md)。请将 `K8S_VERSION` 替换为要升级到的目标 Kubernetes 版本。

   ```
   nodeadm upgrade K8S_VERSION -c file://nodeConfig.yaml
   ```

1. 要允许在升级后在节点上调度容器组（pod），请键入以下内容。请将 `NODE_NAME` 替换为节点的名称。

   ```
   kubectl uncordon NODE_NAME
   ```

1. 观察混合节点的状态，等待节点关闭并在新的 Kubernetes 版本上重新启动并进入“就绪”状态。

   ```
   kubectl get nodes -o wide -w
   ```

# 混合节点的安全更新修补
<a name="hybrid-nodes-security"></a>

本主题介绍为在混合节点上运行的特定程序包和依赖项执行就地安全更新修补的过程。作为一项最佳实践，我们建议您定期更新混合节点以获取 CVE 和安全补丁。

有关升级 Kubernetes 版本的步骤，请参阅[升级集群的混合节点](hybrid-nodes-upgrade.md)。

可能需要安装安全补丁的软件的一个例子是 `containerd`。

## `Containerd`
<a name="_containerd"></a>

 `containerd` 是适用于 EKS 混合节点功能的标准 Kubernetes 容器运行时和核心依赖项，用于管理容器生命周期，包括提取映像和管理容器执行等。在混合节点上，您可以通过 [nodeadm CLI](https://docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-nodeadm.html) 来安装 `containerd`，也可以手动安装。`nodeadm` 将从操作系统分发的程序包或 Docker 程序包安装 `containerd`，具体取决于节点使用的操作系统。

`containerd` 中的 CVE 发布后，您可以使用以下方案，在混合节点上升级到 `containerd` 的修补版本。

## 第 1 步：检查补丁是否已发布
<a name="_step_1_check_if_the_patch_published_to_package_managers"></a>

您可以参考相应的安全公告，检查 `containerd` CVE 补丁是否已发布到相应的各个操作系统程序包管理器：
+  [Amazon Linux 2023](https://alas.aws.amazon.com/alas2023.html) 
+  [RHEL](https://access.redhat.com/security/security-updates/security-advisories) 
+  [Ubuntu 20.04](https://ubuntu.com/security/notices?order=newest&release=focal) 
+  [Ubuntu 22.04](https://ubuntu.com/security/notices?order=newest&release=jammy) 
+  [Ubuntu 24.04](https://ubuntu.com/security/notices?order=newest&release=noble) 

如果将该 Docker 存储库作为 `containerd` 的来源，您可以检查 [Docker 安全公告](https://docs.docker.com/security/security-announcements/)，来确定已修补版本是否在 Docker 存储库中可用。

## 第 2 步：选择安装补丁的方法
<a name="_step_2_choose_the_method_to_install_the_patch"></a>

在节点上就地修补和安装安全升级的方法有三种。具体可以使用的方法，取决于程序包管理器中的操作系统是否提供补丁：

1. 使用 `nodeadm upgrade` 发布到程序包管理器的安装补丁，详情请参阅[第 2 a 步](#hybrid-nodes-security-nodeadm)。

1. 直接使用程序包管理器安装补丁，详情请参见[第 2 b 步](#hybrid-nodes-security-package)。

1. 安装未在程序包管理器中发布的自定义补丁。对于[第 2 c 步](#hybrid-nodes-security-manual) 中 `containerd` 的自定义补丁，有一些特殊注意事项需要注意。

## 第 2 a 步：使用 `nodeadm upgrade` 修补
<a name="hybrid-nodes-security-nodeadm"></a>

确认 `containerd` CVE 补丁已发布到操作系统或 Docker 存储库（Apt 或 RPM）后，您可以使用 `nodeadm upgrade` 命令升级到最新版本的 `containerd`。由于这不属于 Kubernetes 版本升级，因此您必须将当前的 Kubernetes 版本传递给 `nodeadm` 升级命令。

```
nodeadm upgrade K8S_VERSION --config-source file:///root/nodeConfig.yaml
```

## 第 2 b 步：使用操作系统程序包管理器修补
<a name="hybrid-nodes-security-package"></a>

您也可以通过相应的程序包管理器来获取更新，并使用该更新来升级 `containerd` 程序包，如下所示。

 **Amazon Linux 2023** 

```
sudo yum update -y
sudo yum install -y containerd
```

 **RHEL** 

```
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo yum update -y
sudo yum install -y containerd
```

 **Ubuntu** 

```
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update -y
sudo apt install -y --only-upgrade containerd.io
```

## 第 2 c 步：`Containerd` CVE 补丁未在程序包管理器中发布
<a name="hybrid-nodes-security-manual"></a>

如果修补后的 `containerd` 版本只能通过其他方式获取，而未在程序包管理器中提供，例如对于 GitHub 发行版，可以从 GitHub 官方网站安装 `containerd`。

1. 如果计算机已作为混合节点加入集群，则需要运行 `nodeadm uninstall` 命令。

1. 安装官方 `containerd` 二进制文件。您可以使用 GitHub 上的[官方安装步骤](https://github.com/containerd/containerd/blob/main/docs/getting-started.md#option-1-from-the-official-binaries)。

1. 运行 `nodeadm install` 命令并将 `--containerd-source` 参数设置为 `none`，这将跳过通过 `nodeadm` 安装 `containerd` 的过程。对于节点运行的任何操作系统，您可以在 `containerd` 来源中使用 `none` 的值。

   ```
   nodeadm install K8S_VERSION --credential-provider CREDS_PROVIDER --containerd-source none
   ```

# 移除混合节点
<a name="hybrid-nodes-remove"></a>

本主题介绍如何删除 Amazon EKS 集群中的混合节点。必须使用您选择的兼容 Kubernetes 的工具（例如 [kubectl](https://kubernetes.io/docs/reference/kubectl/)）来删除混合节点。从 Amazon EKS 集群中移除节点对象后，将停止收取混合节点的费用。有关混合节点定价的更多信息，请参阅 [Amazon EKS 定价](https://aws.amazon.com/eks/pricing/)。

**重要**  
移除节点对于在节点上运行的工作负载而言是破坏性的。在删除混合节点之前，我们建议您首先清空节点以将容器组转移到其他活动节点。有关清空节点的更多信息，请参阅 Kubernetes 文档中的[安全地清空一个节点](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)。

在用于与 Amazon EKS 集群的 Kubernetes API 端点进行交互的本地计算机或实例上运行以下 kubectl 步骤。如果您使用特定的 `kubeconfig` 文件，请使用 `--kubeconfig` 标志。

## 第 1 步：列出节点
<a name="_step_1_list_your_nodes"></a>

```
kubectl get nodes
```

## 第 2 步：清空节点
<a name="_step_2_drain_your_node"></a>

有关 `kubectl drain` 命令的更多信息，请参阅 Kubernetes 文档中的 [kubectl drain](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_drain/)。

```
kubectl drain --ignore-daemonsets <node-name>
```

## 第 3 步：停止并卸载混合节点构件
<a name="_step_3_stop_and_uninstall_hybrid_nodes_artifacts"></a>

您可以使用 Amazon EKS 混合节点功能 CLI (`nodeadm`) 来停止混合节点构件并将其从主机中移除。您必须使用具有 root/sudo 权限的用户运行 `nodeadm`。默认情况下，如果节点上还有容器组，则 `nodeadm uninstall` 不会执行。如果您将 AWS Systems Manager（SSM）作为凭证提供者，则 `nodeadm uninstall` 命令会将主机从 AWS SSM 托管式实例中注销。有关更多信息，请参阅 [混合节点 `nodeadm` 参考](hybrid-nodes-nodeadm.md)。

```
nodeadm uninstall
```

## 第 4 步：删除集群中的节点
<a name="_step_4_delete_your_node_from_the_cluster"></a>

停止并卸载混合节点构件后，从集群中移除节点资源。

```
kubectl delete node <node-name>
```

## 第 5 步：检查剩余的构件
<a name="_step_5_check_for_remaining_artifacts"></a>

运行上述步骤后，您的混合节点上可能会剩下一些构件，具体取决于您选择的 CNI。参阅 [为混合节点配置 CNI](hybrid-nodes-cni.md) 了解更多信息。