

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

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

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

避免混合节点与 Kubernetes 控制平面之间断开网络连接的最佳方法是使用来自本地环境的冗余、弹性连接。有关使用这些解决方案架构高可用混合网络的更多信息，请参阅 [ A [ WS Direct 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/](https://aws.github.io/aws-eks-best-practices/reliability/docs/application/)

在确定是否将 pod 移至其他节点时，Kubernetes 会评估与 Kubernetes 控制平面断开连接的节点的分区信息。如果一个区域中的所有节点都无法访问，Kubernetes 会取消对该区域中节点的 pod 驱逐。最佳做法是，如果您的部署节点运行在多个数据中心或物理位置，请根据其数据中心或物理位置为每个节点分配一个区域。当您使用云中的节点运行 EKS 时，AWS 云控制器管理器会自动应用此区域标签。但是，混合节点不使用云控制器管理器，因此您可以通过 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](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 控制平面上运行的节点生命周期控制器报告`NodeNotReady`的事件创建警报，这表示混合节点可能出现网络中断的情况。您可以通过为控制器管理器启用 EKS 控制平面日志记录，并在中 CloudWatch 为 “记录节点状态更改事件消息” 消息创建指标筛选器（状态为 “NodeNotReady）” 来创建此警报。创建指标筛选器后，您可以根据所需的阈值为该过滤器创建警报。有关更多信息，请参阅 CloudWatch 文档中的日志[警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Alarm-On-Logs.html)。

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


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

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

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

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

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

列出在主机上运行的 pod：

```
crictl pods
```

列出在主机上运行的容器：

```
crictl ps
```

列出在主机上运行的镜像：

```
crictl images
```

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

```
crictl logs CONTAINER_NAME
```

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

```
crictl statsp
```

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

使用混合节点时，重要的是要考虑和了解应用程序流量的网络流以及用于向集群外部公开应用程序的技术。不同的应用程序负载平衡和入口技术在网络断开连接期间的行为会有所不同。例如，如果您使用 Cilium 的 BGP 控制平面功能来平衡应用程序负载，则在网络断开连接期间，您的容器和服务的 BGP 会话可能会关闭。之所以发生这种情况，是因为 BGP 扬声器功能已与 Cilium 代理集成在一起，当与 Kubernetes 控制平面断开连接时，Cilium 代理将持续重启。重启的原因是Cilium的运行状况检查失败，因为它的运行状况与对Kubernetes控制平面的访问权限相结合（参见 [ CFP: \#31702，](https://github.com/cilium/cilium/issues/31702)其中有Cilium v1.17中的选择加入改进）。同样，如果您使用应用程序负载均衡器 (ALB) 或网络负载均衡器 (NLB) 来处理 AWS Region-originated 应用程序流量，则如果您的本地环境断开与 AWS 区域的连接，流量可能会暂时下降。建议在部署到生产环境之前，验证用于负载平衡和入口的技术在网络断开期间是否保持稳定。a [ ws--h samples/eks ybrid-examples ](https://github.com/aws-samples/eks-hybrid-examples) GitHub 存储库中的示例使用 MetalB 在 [ 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 获取指标和日志、使用应用程序和网络负载均衡器获取 Region-originated 流量，以及从亚马逊弹性容器注册表提取容器。在您的本地环境与 AWS 之间断开网络连接期间，将无法访问这些服务。如果您的本地环境容易出现与 AWS 的网络中断的情况，请检查您对 AWS 服务的使用情况，并确保断开与这些服务的连接不会影响应用程序的静态稳定性。

## 调整 Kubernetes 容器组（pod）失效转移行为
<a name="_tune_kubernetes_pod_failover_behavior"></a>

对于无法跨主机移植的应用程序，或者没有备用容量进行 Pod 故障转移的资源受限环境，有一些选项可以在网络断开期间调整 pod 故障转移行为。通常，重要的是要考虑应用程序的资源需求，并有足够的容量让一个或多个应用程序实例在节点出现故障时故障转移到其他主机。
+  选项 1-使用 DaemonSets：此选项适用于可以而且应该在群集中的所有节点上运行的应用程序。 DaemonSets 会自动配置为容忍无法访问的污点，这会使 DaemonSet Pod 通过断开网络连接保持与其节点的绑定。
+  选项 2-调整无法访问`tolerationSeconds`的污点：你可以调整网络中断期间 pod 与节点保持绑定的时间。为此，将应用程序 pod 配置为在您指定的持续时间`tolerationSeconds`内（在应用程序`NoExecute`规范中）容忍无法触及的污点。使用此选项，当网络中断时，您的应用程序 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
```