

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 通过网络断开连接实现稳定性的最佳实践
<a name="hybrid-nodes-network-disconnection-best-practices"></a>

## 高度可用的网络
<a name="_highly_available_networking"></a>

避免混合节点和 Kubernetes 控制平面之间网络断开的最佳方法是使用本地环境与 AWS 之间的冗余弹性连接。有关使用这些解决方案构建高可用性混合网络的更多信息，请参阅 [AWS Di [rect Connect Connect 弹性工具包](https://docs.aws.amazon.com/directconnect/latest/UserGuide/resiliency_toolkit.html)和 AWS Site-to-Site VPN 文档](https://docs.aws.amazon.com/vpn/latest/s2svpn/vpn-redundant-connection.html)。

## 高可用性应用程序
<a name="_highly_available_applications"></a>

在设计应用程序时，请考虑您的故障域以及不同类型的中断的影响。Kubernetes 提供了跨节点、区域和区域域部署和维护应用程序副本的内置机制。这些机制的使用取决于您的应用程序架构、环境和可用性要求。例如，无状态应用程序通常可以部署多个副本，并且可以在任意主机和基础架构容量之间移动，并且您可以使用节点选择器和拓扑分布限制在不同的域中运行应用程序的实例。[有关在 Kubernetes 上构建弹性应用程序的应用程序级技术的详细信息，请参阅 EKS 最佳实践指南。](https://aws.github.io/aws-eks-best-practices/reliability/docs/application/)

在确定是否将 Pod 移至其他节点时，Kubernetes 会评估与 Kubernetes 控制平面断开连接的节点的区域信息。如果一个区域中的所有节点都无法访问，Kubernetes 将取消该区域中节点的容器驱逐。作为最佳实践，如果您的部署中有节点在多个数据中心或物理位置运行，请根据每个节点的数据中心或物理位置为其分配一个区域。当您在云中的节点上运行 EKS 时，AWS 会自动应用此区域标签 cloud-controller-manager。但是，混合节点 cloud-controller-manager不使用 a，因此您可以通过 kubelet 配置传递这些信息。下面显示了如何在混合节点的节点配置中配置区域的示例。当您使用混合节点 CLI (`nodeadm`) 将混合节点连接到集群时，配置即被传递。有关`topology.kubernetes.io/zone`标签的更多信息，请参阅 [Kubernetes 文档](https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone)。有关混合节点 CLI 的更多信息，请参阅混合节[点 nodeadm](https://docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-nodeadm.html) 参考。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: my-cluster
    region: my-region
  kubelet:
    flags:
       - --node-labels=topology.kubernetes.io/zone=dc1
  hybrid:
    ...
```

## 网络监测
<a name="_network_monitoring"></a>

如果您使用 AWS Direct Connect 或 AWS Site-to-Site VPN 进行混合连接，则可以利用 CloudWatch 警报、日志和指标来观察混合连接的状态并诊断问题。有关更多信息，请参阅[监控 AWS Direct Connect 资源](https://docs.aws.amazon.com/directconnect/latest/UserGuide/monitoring-overview.html)和[监控 AWS Site-to-Site VPN 连接](https://docs.aws.amazon.com/vpn/latest/s2svpn/monitoring-overview-vpn.html)。

建议为在 EKS 控制平面上 node-lifecycle-controller运行时报告`NodeNotReady`的事件创建警报，这些事件表示混合节点可能出现网络断开的情况。您可以通过以下方式创建此警报：为控制器管理器启用 EKS 控制平面日志记录，然后在 CloudWatch status= “” 中为 “记录节点的状态更改事件消息” 消息创建指标过滤器。NodeNotReady创建指标筛选器后，您可以根据所需的阈值为此过滤器创建警报。有关更多信息，请参阅[ CloudWatch 文档中的日志警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Alarm-On-Logs.html)。

您可以使用 Transit Gateway (TGW) 和虚拟专用网关 (VGW) 的内置指标来观察进出您的 TGW 或 VGW 的网络流量。您可以为这些指标创建警报，以检测网络流量降至正常水平以下的情况，这表明混合节点和 EKS 控制平面之间存在潜在的网络问题。下表描述了 TGW 和 VGW 指标。


| 网关 | 指标 | 说明 | 
| --- | --- | --- | 
|  Transit Gateway  |  BytesIn  |  TGW 从附件（EKS 控制平面到混合节点）接收的字节  | 
|  Transit Gateway  |  BytesOut  |  从 TGW 发送到附件（混合节点到 EKS 控制平面）的字节  | 
|  虚拟专用网关  |  TunnelDataIn  |  从 AWS 端通过 VPN 隧道发送到客户网关（EKS 控制平面到混合节点）的字节  | 
|  虚拟专用网关  |  TunnelDataOut  |  通过 VPN 隧道从客户网关（到 EKS 控制平面的混合节点）在连接的 AWS 端接收的字节  | 

您还可以使用 [CloudWatch Network Monit](https://aws.amazon.com/blogs/networking-and-content-delivery/monitor-hybrid-connectivity-with-amazon-cloudwatch-network-monitor/) or 更深入地了解您的混合连接，从而缩短平均恢复时间，并确定网络问题是源于 AWS 还是您的环境。 CloudWatch Network Monitor 可用于可视化混合网络连接中的数据包丢失和延迟，设置警报和阈值，然后采取措施提高网络性能。有关更多信息，请参阅[使用 Amazon CloudWatch 网络监视器](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/what-is-network-monitor.html)。

EKS 提供了多种用于监控集群和应用程序运行状况的选项。对于集群运行状况，您可以使用 EKS 控制台中的可观察性控制面板来快速检测、故障排除和修复问题。您还可以使用适用于 Prometheus 的亚马逊托管服务、用于开放遥测 (ADOT) 的 AWS Distro 以及集群 CloudWatch 、应用程序和基础设施监控。有关 EKS 可观察性选项的更多信息，请参阅[监控集群性能和查看日志](https://docs.aws.amazon.com/eks/latest/userguide/eks-observe.html)。

## 本地故障排除
<a name="_local_troubleshooting"></a>

要为混合节点和 EKS 控制平面之间的网络断开做好准备，您可以设置辅助监控和日志后端，以便在无法访问区域 AWS 服务时保持应用程序的可观察性。例如，您可以将 AWS Distro 开放遥测版 (ADOT) 收集器配置为向多个后端发送指标和日志。您还可以使用本地工具（例如 `crictl` CLI）与 Pod 和容器进行本地交互，以替代通常查询 Kubernetes API 服务器端点的其他 Kubernetes API 兼容客户端。`kubectl`有关的更多信息`crictl`，请参阅 cri- GitHub t [`crictl`ools 中的文档](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)。下面列出了一些有用的`crictl`命令。

列出主机上运行的 pod：

```
crictl pods
```

列出主机上运行的容器：

```
crictl ps
```

列出主机上运行的映像：

```
crictl images
```

获取主机上运行的容器的日志：

```
crictl logs CONTAINER_NAME
```

获取主机上运行的 Pod 的统计信息：

```
crictl statsp
```

## 应用程序网络流量
<a name="_application_network_traffic"></a>

使用混合节点时，重要的是要考虑和了解应用程序流量的网络流量，以及用于向集群外部公开应用程序的技术。在网络断开连接期间，不同的应用程序负载平衡和入口技术的行为会有所不同。例如，如果您使用 Cilium 的 BGP 控制平面功能进行应用程序负载平衡，则在网络断开连接期间，Pod 和服务的 BGP 会话可能会关闭。之所以发生这种情况，是因为 BGP 扬声器功能与 Cilium 代理集成在一起，而且 Cilium 代理在与 Kubernetes 控制平面断开连接时将持续重启。重启的原因是Cilium的运行状况检查失败，因为它的生命值与对Kubernetes控制平面的访问权限相结合（参见 [CFP: \$131702，C](https://github.com/cilium/cilium/issues/31702) ilium v1.17 中有选择加入的改进）。同样，如果您使用应用程序负载均衡器 (ALB) 或网络负载均衡器 (NLB) 来处理源自 AWS 区域的应用程序流量，则如果您的本地环境与 AWS 区域断开连接，则该流量可能会暂时中断。建议在部署到生产环境之前，验证用于负载平衡和入口的技术在网络断开连接期间是否保持稳定。[aws-samples/ eks-hybrid-examples](https://github.com/aws-samples/eks-hybrid-examples) GitHub 存储库中的示例使用 MetalLB 在 [L2 模式下](https://metallb.universe.tf/concepts/layer2/)进行负载平衡，在混合节点和 EKS 控制平面之间的网络断开连接期间，负载平衡保持稳定。

## 查看对远程 AWS 服务的依赖关系
<a name="_review_dependencies_on_remote_aws_services"></a>

使用混合节点时，请注意您对本地或边缘环境外部的区域 AWS 服务的依赖性。示例包括访问 Amazon S3 或 Amazon RDS 获取应用程序数据、使用适用于 Prometheus 的亚马逊托管服务 CloudWatch 或指标和日志、使用应用程序和网络负载均衡器处理源自区域的流量，以及从 Amazon 弹性容器注册表中提取容器。在您的本地环境与 AWS 之间断开网络连接期间，将无法访问这些服务。如果您的本地环境容易与 AWS 断开网络连接，请检查您对 AWS 服务的使用情况，并确保与这些服务的连接中断不会影响应用程序的静态稳定性。

## 调整 Kubernetes 容器故障转移行为
<a name="_tune_kubernetes_pod_failover_behavior"></a>

对于无法跨主机移植的应用程序，或者没有备用容量进行容器故障转移的资源受限的环境，可以选择在网络断开连接期间调整容器故障转移行为。通常，重要的是要考虑应用程序的资源需求，并有足够的容量让一个或多个应用程序实例在节点出现故障时故障转移到另一台主机。
+  选项 1-使用 DaemonSets：此选项适用于可以而且应该在集群中的所有节点上运行的应用程序。 DaemonSets 会自动配置为容忍无法访问的污点，这会通过网络断开连接使 DaemonSet Pod 与其节点绑定。
+  选项 2-调整无法访问`tolerationSeconds`的污点：您可以调整网络断开连接期间 Pod 与节点绑定的时间。为此，请将应用程序 pod 配置为在您指定的持续时间（在应用程序`NoExecute`规范`tolerationSeconds`中）内容忍无法达到的污点。使用此选项，当网络断开连接时，您的应用程序 Pod 将一直绑定到节点，直到`tolerationSeconds`到期。请仔细考虑这一点，因为增加无法访问`tolerationSeconds`的污点`NoExecute`意味着在无法访问的主机上运行的 Pod 可能需要更长的时间才能移动到其他可访问、运行良好的主机。
+  选项 3：自定义控制器：你可以创建并运行一个自定义控制器（或其他软件），用于监控 Kubernetes 中是否有无法触及的污点。`NoExecute`当检测到这种污点时，自定义控制器可以检查应用程序特定的指标以评估应用程序的运行状况。如果应用程序运行正常，则自定义控制器可以移除无法访问的污点，从而防止在网络断开连接期间将 Pod 从节点中驱逐。

下面显示了如何`tolerationSeconds`为无法到达的污点配置部署的示例。在示例中，设置`tolerationSeconds`为`1800`（30 分钟），这意味着只有在网络断开连接持续时间超过 30 分钟时，在无法访问的节点上运行的 Pod 才会被驱逐出去。

```
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
      tolerations:
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 1800
```