

 **帮助改进此页面** 

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

# 为混合节点配置 Webhook
<a name="hybrid-nodes-webhooks"></a>

本页详细介绍了使用混合节点运行 Webhook 的注意事项。在 Kubernetes 应用程序和开源项目（例如 AWS 负载均衡器控制器和 CloudWatch 可观测性代理）中，Webhook 用于执行运行时更改和验证功能。

 **可路由的容器组网络** 

如果您能够在本地网络上路由本地容器组 CIDR，则可以在混合节点上运行 Webhook。您可以通过多种方法来使本地容器组 CIDR 可在本地网络上路由，包括边界网关协议（BGP）、静态路由或其他自定义路由解决方案。我们推荐使用 BGP 解决方案，因为与需要自定义或手动路由配置的备选解决方案相比，此方案具有更好的可扩展性并且更易于管理。AWS 支持使用 Cilium 和 Calico 的 BGP 功能来公开容器组 CIDR，有关更多信息，请参阅[为混合节点配置 CNI](hybrid-nodes-cni.md)和[可路由的远程容器组（pod）CIDR](hybrid-nodes-concepts-kubernetes.md#hybrid-nodes-concepts-k8s-pod-cidrs)。

 **不可路由的容器组网络** 

如果*无法*在本地网络上路由本地容器组 CIDR，但又需要运行 Webhook，我们建议您在与混合节点位于同一 EKS 集群中的云节点上运行所有 Webhook。

## 混合模式集群的注意事项
<a name="hybrid-nodes-considerations-mixed-mode"></a>

 *混合模式集群*是指为既有混合节点又有在 AWS 云端运行的节点的 EKS 集群。运行混合模式集群时应注意以下建议：
+ 在 AWS 云端节点上运行 VPC CNI，在混合节点上运行 Cilium 或 Calico。在 AWS 云端节点上运行时，AWS 不支持 Cilium 和 Calico。
+ 配置要在 AWS 云端节点上运行的 Webhook。请参阅[为附加组件配置 Webhook](#hybrid-nodes-webhooks-add-ons)，了解如何为 AWS 和社区附加组件配置 webhook。
+ 如果应用程序要求在 AWS Cloud 节点上运行的容器组直接与在混合节点上运行的容器组通信（“东西向通信”），并且您在 AWS Cloud 节点上使用 VPC CNI，在混合节点上使用 Cilium 或 Calico，则必须使本地容器组 CIDR 可在本地网络上路由。
+ 在 AWS Cloud 中的节点上运行至少一个 CoreDNS 副本，在混合节点上运行至少一个 CoreDNS 副本。
+ 配置服务流量分布，使服务流量保持在其源区域的本地。有关服务流量分布的更多信息，请参阅[配置服务流量分布](#hybrid-nodes-mixed-service-traffic-distribution)。
+ 如果使用 AWS 应用程序负载均衡器（ALB）或网络负载均衡器（NLB）来处理在混合节点上运行的工作负载流量，则用于 ALB 或 NLB 的 IP 目标必须可以从 AWS 路由。
+ Metrics Server 附加组件需要能够从 EKS 控制面板连接到 Metrics Server 容器组 IP 地址。如果在混合节点上运行 Metrics Server 附加组件，则本地容器组 CIDR 必须可在本地网络上路由。
+ 要使用 Amazon Managed Service for Prometheus（AMP）托管式收集器来收集混合节点的指标，本地容器组 CIDR 必须可在本地网络上路由。您也可以将 AMP 托管式收集器用于 EKS 控制面板指标和在 AWS Cloud 中运行的资源，以及使用 AWS Distro for OpenTelemetry（ADOT）附加组件来收集混合节点的指标。

## 配置混合模式集群
<a name="hybrid-nodes-mixed-mode"></a>

要查看集群上运行的更改和验证 Webhook，可以通过集群的 EKS 控制台的**资源**面板查看**扩展**资源类型，也可以使用以下命令。EKS 还会在集群可观测性控制面板中报告 Webhook 指标，有关更多信息，请参阅[使用可观测性仪表板监控您的集群](observability-dashboard.md)。

```
kubectl get mutatingwebhookconfigurations
```

```
kubectl get validatingwebhookconfigurations
```

### 配置服务流量分布
<a name="hybrid-nodes-mixed-service-traffic-distribution"></a>

运行混合模式集群时，我们建议您使用[https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)将服务流量保持在其源区域的本地。推荐解决方案是服务流量分配功能（在 Kubernetes 1.31 及更高版本的 EKS 中提供此功能），而不建议使用[拓扑感知路由](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)功能，因为前者的可预测性更好。使用服务流量分配功能时，分区中运行正常的端点将会接收指向该分区的所有流量。使用拓扑感知路由功能时，每项服务必须满足该分区中的多个条件才能应用自定义路由，否则会将流量平均路由到所有端点。

如果将 Cilium 作为 CNI，则必须在运行该 CNI 时将 `enable-service-topology` 设置为 `true`，才能启用服务流量分配功能。您可以使用 Helm 安装标志 `--set loadBalancer.serviceTopology=true` 传递此配置，也可以使用 Cilium CLI 命令 `cilium config set enable-service-topology true` 更新现有安装。更新现有安装的配置后，必须重新启动在每个节点上运行的 Cilium 代理。

以下部分显示如何为 CoreDNS 服务配置服务流量分布的示例，我们建议您为集群中的所有服务启用相同的配置，以避免意外的跨环境流量。

### 配置 CoreDNS 副本
<a name="hybrid-nodes-mixed-coredns"></a>

如果运行混合模式集群，既有混合节点，也有位于 AWS 云端的节点，则建议混合节点上至少有一个 CoreDNS 副本，在 AWS 云端的节点上也至少有一个 CoreDNS 副本。为防止混合模式集群设置中的延迟和网络问题，可以使用[服务流量分配](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)功能，将 CoreDNS 服务配置为首选距离最近的 CoreDNS 副本。

 推荐解决方案是*服务流量分配*功能（在 Kubernetes 1.31 及更高版本的 EKS 中提供此功能），而不建议使用[拓扑感知路由](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)功能，因为前者的可预测性更好。使用服务流量分配功能时，分区中运行正常的端点将会接收指向该分区的所有流量。而使用拓扑感知路由功能时，每项服务必须满足该分区中的多个条件才能应用自定义路由，否则会将流量平均路由到所有端点。以下是配置服务流量分配功能的步骤。

如果将 Cilium 作为 CNI，则必须在运行该 CNI 时将 `enable-service-topology` 设置为 `true`，才能启用服务流量分配功能。您可以使用 Helm 安装标志 `--set loadBalancer.serviceTopology=true` 传递此配置，也可以使用 Cilium CLI 命令 `cilium config set enable-service-topology true` 更新现有安装。更新现有安装的配置后，必须重新启动在每个节点上运行的 Cilium 代理。

1. 为每个混合节点添加一个拓扑分区标签，例如 `topology.kubernetes.io/zone: onprem`。您也可以通过在 `nodeadm` 配置中指定标签，从而在 `nodeadm init` 阶段设置该标签，具体请参阅[自定义 kubelet 的节点配置（可选）](hybrid-nodes-nodeadm.md#hybrid-nodes-nodeadm-kubelet)。请注意，在 AWS 云端运行的节点会自动应用一个拓扑分区标签，与节点的可用区（AZ）相对应。

   ```
   kubectl label node hybrid-node-name topology.kubernetes.io/zone=zone
   ```

1. 使用拓扑分区键将 `podAntiAffinity` 添加到 CoreDNS 部署。您也可以在安装过程中使用 EKS 附加组件配置 CoreDNS 部署。

   ```
   kubectl edit deployment coredns -n kube-system
   ```

   ```
   spec:
     template:
       spec:
         affinity:
          ...
           podAntiAffinity:
             preferredDuringSchedulingIgnoredDuringExecution:
             - podAffinityTerm:
                 labelSelector:
                   matchExpressions:
                   - key: k8s-app
                     operator: In
                     values:
                     - kube-dns
                 topologyKey: kubernetes.io/hostname
               weight: 100
             - podAffinityTerm:
                 labelSelector:
                   matchExpressions:
                   - key: k8s-app
                     operator: In
                     values:
                     - kube-dns
                 topologyKey: topology.kubernetes.io/zone
               weight: 50
         ...
   ```

1. 将设置 `trafficDistribution: PreferClose` 添加到 `kube-dns` 服务配置以启用服务流量分布。

   ```
   kubectl patch svc kube-dns -n kube-system --type=merge -p '{
     "spec": {
       "trafficDistribution": "PreferClose"
     }
   }'
   ```

1. 您可以通过查看 `kube-dns` 服务的端点切片来确认已启用服务流量功能。端点切片必须显示拓扑分区标签为 `hints`，从而确认服务流量分配功能已启用。如果没有看到每个端点地址为 `hints`，则说明服务流量分配功能尚未启用。

   ```
   kubectl get endpointslice -A | grep "kube-dns"
   ```

   ```
   kubectl get endpointslice [.replaceable]`kube-dns-<id>`  -n kube-system -o yaml
   ```

   ```
   addressType: IPv4
   apiVersion: discovery.k8s.io/v1
   endpoints:
   - addresses:
     - <your-hybrid-node-pod-ip>
     hints:
       forZones:
       - name: onprem
     nodeName: <your-hybrid-node-name>
     zone: onprem
   - addresses:
     - <your-cloud-node-pod-ip>
     hints:
       forZones:
       - name: us-west-2a
     nodeName: <your-cloud-node-name>
     zone: us-west-2a
   ```

### 为附加组件配置 Webhook
<a name="hybrid-nodes-webhooks-add-ons"></a>

以下附加组件使用 Webhook，并支持将 Webhook 用于混合节点。
+  AWS Load Balancer Controller
+ CloudWatch 可观测性代理
+  AWS Distro for OpenTelemetry (ADOT)
+  `cert-manager` 

请参阅以下章节，了解如何配置这些附加组件使用的 Webhook，使其在 AWS 云端的节点上运行。

#### AWS Load Balancer Controller
<a name="hybrid-nodes-mixed-lbc"></a>

要在混合模式集群设置中使用 AWS 负载均衡器控制器，您必须在 AWS 云端的节点上运行控制器。为此，请将以下内容添加到 Helm 值配置中，或者使用 EKS 附加组件配置来指定值。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
```

#### CloudWatch 可观测性代理
<a name="hybrid-nodes-mixed-cwagent"></a>

CloudWatch 可观测性代理附加组件有一个使用 Webhook 的 Kubernetes 操作符。要在混合模式集群设置下在 AWS 云端节点上运行此操作符，请编辑 CloudWatch 可观测性代理操作符配置。无法在安装过程中使用 Helm 和 EKS 附加组件配置操作符亲和性（请参阅 [containers-roadmap 问题 \$12431](https://github.com/aws/containers-roadmap/issues/2431)）。

```
kubectl edit -n amazon-cloudwatch deployment amazon-cloudwatch-observability-controller-manager
```

```
spec:
  ...
  template:
    ...
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: eks.amazonaws.com/compute-type
                operator: NotIn
                values:
                - hybrid
```

#### AWS Distro for OpenTelemetry (ADOT)
<a name="hybrid-nodes-mixed-adot"></a>

AWS Distro for OpenTelemetry（ADOT）附加组件有一个使用 Webhook 的 Kubernetes 操作符。要在混合模式集群设置中的 AWS 云端节点上运行此操作符，请将以下内容添加到 Helm 值配置中，或者使用 EKS 附加组件配置来指定值。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
```

如果容器组 CIDR 无法在本地网络上路由，则 ADOT 收集器必须在混合节点上运行，以便可以从混合节点以及在其上运行的工作负载中抓取指标。为此，请编辑自定义资源定义（CRD）。

```
kubectl -n opentelemetry-operator-system edit opentelemetrycollectors.opentelemetry.io adot-col-prom-metrics
```

```
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: In
            values:
            - hybrid
```

您可以通过在 ADOT 收集器 CRD 配置中将以下 `relabel_configs` 添加到每个 `scrape_configs` 中，从而将 ADOT 收集器配置为仅从混合节点以及在混合节点上运行的资源中抓取指标。

```
relabel_configs:
  - action: keep
    regex: hybrid
    source_labels:
    - __meta_kubernetes_node_label_eks_amazonaws_com_compute_type
```

ADOT 附加组件的一个先决条件是为 ADOT 操作符使用的 TLS 证书安装 `cert-manager`。`cert-manager` 也会运行 Webhook，并且您可以使用以下 Helm 值配置将其配置为在 AWS 云端的节点上运行。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
webhook:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
cainjector:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
startupapicheck:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
```

#### `cert-manager`
<a name="hybrid-nodes-mixed-cert-manager"></a>

`cert-manager` 附加组件会运行 Webhook，并且您可以使用以下 Helm 值配置将其配置为在 AWS 云端的节点上运行。

```
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: eks.amazonaws.com/compute-type
          operator: NotIn
          values:
          - hybrid
webhook:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
cainjector:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
startupapicheck:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/compute-type
            operator: NotIn
            values:
            - hybrid
```