

 **帮助改进此页面** 

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

# 连接使用 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.ca.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.ca.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)中的步骤。