

 **帮助改进此页面** 

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

# 在使用 EC2 实例存储配置的 AWS Outposts 上准备 Amazon EKS 本地集群以在网络连接断开期间使用
<a name="eks-outposts-instance-store-network-disconnects"></a>

如果连接本地网络和 AWS 云的 AWS Outposts 服务链路断开，您可以继续在 Outpost 上使用 Amazon EKS 本地集群。本主题介绍如何准备本地集群以应对网络连接断开以及相关注意事项。
+ 本地集群可在临时、计划外网络断开连接期间实现稳定性和持续操作。AWSOutposts 仍是一个完全连接的产品，充当您的数据中心内 AWS 云的扩展。当 Outpost 与 AWS 云之间的网络连接断开时，我们建议您尝试恢复连接。如需查看相关说明，请参阅《AWS Outposts 用户指南》中的 [AWS Outposts rack network troubleshooting checklist](https://docs.aws.amazon.com/outposts/latest/userguide/network-troubleshoot.html)**。
+ Outpost 将发出一个 `ConnectedStatus` 指标，您可用于监控 Outpost 的连接状态。有关更多信息，请参阅 *AWS Outposts 用户指南*中的 [Outposts 指标](https://docs.aws.amazon.com/outposts/latest/userguide/outposts-cloudwatch-metrics.html#outposts-metrics)。

## 网络连接断开期间的身份验证
<a name="eks-outposts-instance-store-network-disconnects-authentication"></a>

本地集群支持多种身份验证机制。在网络连接断开期间具体可用的机制因情况而异：


| 身份验证机制 | 在连接断开期间是否可用？ | 
| --- | --- | 
|  AWSIAM（访问条目、`aws-auth` ConfigMap） | 否。IAM 需要连接到 AWS 区域。 | 
| OIDC（客户提供的提供者） | 取决于提供者的位置。如果可以从 Outpost 本地网络访问 OIDC 提供者，则该身份验证机制将继续有效。 | 
| X.509 客户端证书 | 可以。证书由 Kubernetes API 服务器在本地验证。 | 
| 服务账户的 IAM 角色（IRSA） | 否。请参阅[断开连接期间的 IRSA 和容器组身份](#eks-outposts-instance-store-network-disconnects-irsa)。 | 
| EKS 容器组身份 | 否。请参阅[断开连接期间的 IRSA 和容器组身份](#eks-outposts-instance-store-network-disconnects-irsa)。 | 

### X.509 客户端证书
<a name="eks-outposts-instance-store-network-disconnects-x509"></a>

要在网络连接断开期间保持 `kubectl` 访问，请在断开连接之前创建客户端 X.509 证书。

要创建管理员证书，请执行以下操作：

1. 生成私有密钥和证书签名请求（CSR）：

   ```
   openssl req -new -newkey rsa:4096 -nodes \
       -keyout admin.key -out admin.csr -subj "/CN=admin"
   ```

1. 创建并批准 Kubernetes `CertificateSigningRequest` 资源：

   ```
   cat admin.csr | base64 | tr -d '\n' > admin.csr.b64
   ```

   ```
   apiVersion: certificates.k8s.io/v1
   kind: CertificateSigningRequest
   metadata:
     name: admin-csr
   spec:
     request: <base64-encoded-csr>
     signerName: kubernetes.io/kube-apiserver-client
     usages:
       - client auth
   ```

   ```
   kubectl apply -f admin-csr.yaml
   kubectl certificate approve admin-csr
   ```

1. 检索签名后的证书：

   ```
   kubectl get csr admin-csr -o jsonpath='{.status.certificate}' | base64 --decode > admin.crt
   ```

1.  创建`ClusterRoleBinding` 以授予管理员访问权限：

   ```
   kubectl create clusterrolebinding admin --clusterrole=cluster-admin \
       --user=admin --group=system:masters
   ```

1. 生成一个使用该证书的 `kubeconfig`：

   ```
   kubectl config --kubeconfig admin.kubeconfig set-cluster my-cluster \
       --certificate-authority=ca.crt --server $APISERVER_ENDPOINT --embed-certs
   kubectl config --kubeconfig admin.kubeconfig set-credentials admin \
       --client-certificate=admin.crt --client-key=admin.key --embed-certs
   kubectl config --kubeconfig admin.kubeconfig set-context admin@my-cluster \
       --cluster my-cluster --user admin
   kubectl config --kubeconfig admin.kubeconfig use-context admin@my-cluster
   ```

### 连接断开期间的集群端点 DNS 解析
<a name="eks-outposts-instance-store-network-disconnects-cluster-dns"></a>

本地集群的 Kubernetes API 服务器端点在 Amazon Route 53 中托管，并且会解析为 Amazon EKS 在您的子网中创建的跨账户弹性网络接口（ENI）的私有 IP 地址。这些 ENI 具有静态私有 IP 地址，在集群正常运行期间不会更改。

在网络连接断开期间，Outpost 无法连接到 Route 53，因此除非您已事先准备好本地解析路径，否则集群端点主机名无法解析。需要连接到 API 服务器的客户端有三类：
+  在运行 `kubectl` 的**集群管理员**。
+  发送节点心跳并提取规范的的 **Worker 节点** (`kubelet`)。
+  每个节点上的 **`kube-proxy`**，用于设置集群集服务 IP。

#### 选项 1：本地 DNS 解决方案（推荐）
<a name="_option_1_local_dns_solution_recommended"></a>

 AWS 建议部署本地 DNS 解决方案，用来缓存集群端点记录并在 Outpost 断开连接时为这些记录提供服务。您可以在本地环境中运行自己的 DNS 服务器来缓存集群端点记录。

如果使用本地 DNS 解决方案，我们建议您的 `kubeconfig` 和 Worker 节点 AMI 均指向集群端点主机名（而不是 ENI IP 地址），以确保解析结果与本地 DNS 解决方案保持一致。

#### 选项 2：静态 IP 访问
<a name="_option_2_static_ip_based_access"></a>

如果不希望运行本地 DNS 解决方案，可以使用静态 IP 访问。
+  **管理员：**将您的 `kubeconfig` 配置为直接指向跨账户 ENI 私有 IP 地址。通过在您的 AWS 账户中搜索具有描述 `Amazon EKS {{cluster-name}} ` 的网络接口来查找 ENI。正常运行时，每个 ENI 的 IP 地址在集群的生命周期会保持稳定。
+  **Worker 节点（Amazon EKS 优化版 AMI）：**从 Amazon EKS 优化版 AMI 启动 Worker 节点时，引导脚本会将集群端点添加到 `/etc/hosts` ENI IP 地址。无需额外配置。
+  **Worker 节点（自定义 AMI）：**将集群端点主机名和 ENI IP 地址添加到自定义引导中的 `/etc/hosts`。否则，`kubelet` 和 `kube-proxy` 将无法在连接断开期间连接到 API 服务器。

**重要**  
如果跨账户 ENI 被删除或其 IP 地址更改（例如，当您将其删除或以某种导致 Amazon EKS 需要重新连接的方式修改时），则必须手动更新每个节点和每个使用静态 IP 访问的管理员。使用本地 DNS 解决方案时，无需手动干预。

### 断开连接期间的容器组 DNS 解析
<a name="eks-outposts-instance-store-network-disconnects-pod-dns"></a>

为防止在连接断开期间操作时发生 DNS 故障，请将 Worker 节点启动模板配置为覆盖 `kubelet’s `resolvConf` 设置。在您的用户数据中创建一个仅包含 `nameserver 10.0.0.2`（不包含 VPC 搜索域）的自定义 `resolv.conf` 文件（例如 `/etc/kubernetes/resolv.conf`），然后在您的 `NodeConfig` 中设置 `spec.kubelet.config.resolvConf: /etc/kubernetes/resolv.conf`。这会将 ` {{region-code}}.compute.internal` 搜索域从容器组 DNS 配置中移除，从而防止在断开连接时将查询转发到无法访问的 VPC DNS 解析器。

以下示例显示了 Worker 节点用户数据：

```
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"

--BOUNDARY
Content-Type: text/x-shellscript; charset="us-ascii"

#!/bin/bash
mkdir -p /etc/kubernetes
echo "nameserver [.replaceable]``10.0.0.2``" > /etc/kubernetes/resolv.conf

--BOUNDARY
Content-Type: application/node.eks.aws

---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: my-cluster
    ...
  kubelet:
    config:
      resolvConf: /etc/kubernetes/resolv.conf

--BOUNDARY--
```

### 断开连接期间的 IRSA 和容器组身份
<a name="eks-outposts-instance-store-network-disconnects-irsa"></a>

**重要**  
IRSA 和 EKS 容器组身份依赖在 AWS 区域中运行的 AWS STS。在网络连接断开期间，使用 IRSA 或容器组身份的工作负载无法获得新的凭证。现有凭证会在一段时间后到期。

对于在网络连接断开期间必须保持可用的工作负载，我们不建议使用基于区域的 AWS 服务的功能或操作依赖项。

## 连接断开期间的 `etcd` 行为
<a name="eks-outposts-instance-store-network-disconnects-etcd"></a>

在网络连接断开期间，无法备份 `etcd` 快照。如果在网络连接断开期间有多个 `etcd` 实例不可用，则 `etcd` 会失去法定数量，并且 Kubernetes API 操作在您的 Outpost 重新连接并且 `etcd` 重新达到法定数量之前不可用。已经在运行的工作负载将继续运行。

## 网络连接断开期间的控制面板日志记录
<a name="eks-outposts-instance-store-network-disconnects-cp-logs"></a>

在网络连接断开期间，Amazon EKS 控制面板日志将在控制面板实例上本地缓存。恢复连接后，这些日志会发送到父级 AWS 区域中的 Amazon CloudWatch Logs。无需在控制面板上安装或维护任何日志记录代理。

## 本地可观测性
<a name="eks-outposts-instance-store-network-disconnects-local-observability"></a>

在网络连接断开期间，您可以使用 [Prometheus](https://prometheus.io/)、[Grafana](https://grafana.com/) 或其他第三方解决方案来抓取 Kubernetes API 服务器指标端点，从而在本地监控集群。

## 本地映像存储库
<a name="eks-outposts-instance-store-network-disconnects-image-repo"></a>

要使用额外的副本扩展部署或从断开连接期间的容器组故障中恢复，您必须拥有本地容器映像存储库（例如 Docker 注册表），否则必须在断开连接之前将映像缓存到该节点上。Amazon ECR 在网络连接断开期间不可用。

## 调整 Kubernetes 容器组（pod）失效转移行为
<a name="eks-outposts-instance-store-network-disconnects-pod-failover"></a>

在网络连接断开期间，Kubernetes 控制面板无法与 AWS 区域通信。如果无法连接到节点，Kubernetes 的默认行为是在超时期满后驱逐容器组。您可以使用容器组规范上的容忍度和 `tolerationSeconds` 来微调此行为，以控制在分区期间重新调度容器组的速度。有关详细的指导和示例，请参阅 https://docs.aws.amazon.com/eks/latest/best-practices/hybrid-nodes-network-disconnection-best-practices.html\#*tune\_kubernetes\_pod\_failover\_behavior[调整 Kubernetes 容器组（pod）失效转移行为]（位于《Amazon EKS 最佳实践指南》中）*。

## 模拟网络连接断开
<a name="eks-outposts-instance-store-network-disconnects-simulate"></a>

在将本地集群投入生产之前，应首先模拟断开连接，以确保在网络连接断开期间能够访问集群。

1. 在将您的 Outpost 连接到 AWS 区域的联网设备上应用防火墙规则。这将断开 Outpost 的服务链接。

1. 使用您创建的 X.509 证书测试与本地集群之间的连接：

   ```
   kubectl --kubeconfig admin.kubeconfig get nodes
   ```

**注意**  
如果您的 Outpost 上已有投入生产中的服务，请不要模拟断开连接。断开连接会影响在 Outpost 上运行的所有服务链路。