

 **帮助改进此页面** 

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

# 排查 Amazon EKS 的 Kubernetes 网络策略问题
<a name="network-policies-troubleshooting"></a>

这是 Amazon VPC CNI 网络策略功能的故障排除指南。

本指南涵盖以下内容：
+ 安装信息、CRD 和 RBAC 权限（[新的 `policyendpoints` CRD 和权限](#network-policies-troubleshooting-permissions)） 
+ 诊断网络策略问题时要检查的日志（[网络策略日志](#network-policies-troubleshooting-flowlogs)） 
+ 运行 eBPF SDK 工具集进行故障排除
+ 已知问题和解决方案 [已知问题和解决方案](#network-policies-troubleshooting-known-issues) 

**注意**  
请注意，网络策略仅适用于通过 Kubernetes *部署*创建的容器组。有关 VPC CNI 中网络策略的更多限制，请参阅[注意事项](cni-network-policy.md#cni-network-policy-considerations)。

您可以通过查看[网络策略日志](#network-policies-troubleshooting-flowlogs)和运行 [eBPF SDK](#network-policies-ebpf-sdk) 中的工具，对使用网络策略的网络连接进行问题排查和调查。

## 新的 `policyendpoints` CRD 和权限
<a name="network-policies-troubleshooting-permissions"></a>
+ CRD：`policyendpoints.networking.k8s.aws`
+ Kubernetes API：名为 `v1.networking.k8s.io` 的 `apiservice` 
+ Kubernetes 资源：`Kind: NetworkPolicy`
+ RBAC：名为 `aws-node` 的 `ClusterRole`（VPC CNI），名为 `eks:network-policy-controller` 的 `ClusterRole`（EKS 集群控制面板中的网络策略控制器）

对于网络策略，VPC CNI 会创建一个名为 `policyendpoints.networking.k8s.aws` 的新 `CustomResourceDefinition`（CRD）。VPC CNI 必须有相关权限，以创建 CRD 以及创建由 VPC CNI（`eniconfigs.crd.k8s.amazonaws.com`）安装的此 CRD 和另一个 CRD 的 CustomResources（CR）。这两个 CRD 都在 GitHub 上的 [`crds.yaml` 文件](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/charts/aws-vpc-cni/crds/customresourcedefinition.yaml)中提供。具体而言，VPC CNI 必须具有对 `policyendpoints` 执行“获取”、“列出”和“监控”操作的权限。

Kubernetes *网络策略*是名为 `v1.networking.k8s.io` 的 `apiservice` 的一部分，这是您的策略 YAML 文件中的 `apiversion: networking.k8s.io/v1`。VPC CNI `DaemonSet` 必须有使用 Kubernetes API 这一部分的权限。

VPC CNI 权限位于名为 `aws-node` 的 `ClusterRole` 中。请注意，`ClusterRole` 对象未按命名空间分组。以下显示了集群的 `aws-node`：

```
kubectl get clusterrole aws-node -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/instance: aws-vpc-cni
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: aws-node
    app.kubernetes.io/version: v1.19.4
    helm.sh/chart: aws-vpc-cni-1.19.4
    k8s-app: aws-node
  name: aws-node
rules:
- apiGroups:
  - crd.k8s.amazonaws.com
  resources:
  - eniconfigs
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
  - list
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
- apiGroups:
  - vpcresources.k8s.aws
  resources:
  - cninodes
  verbs:
  - get
  - list
  - watch
  - patch
```

此外，每个 EKS 集群的控制面板中都会运行一个新的控制器。控制器使用名为 `eks:network-policy-controller` 的 `ClusterRole` 的权限。以下显示了集群的 `eks:network-policy-controller`：

```
kubectl get clusterrole eks:network-policy-controller -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: amazon-network-policy-controller-k8s
  name: eks:network-policy-controller
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/finalizers
  verbs:
  - update
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - networkpolicies
  verbs:
  - get
  - list
  - patch
  - update
  - watch
```

## 网络策略日志
<a name="network-policies-troubleshooting-flowlogs"></a>

VPC CNI 根据网络策略允许还是拒绝连接的每个决定都将记录在*流日志*中。每个节点上的网络策略日志包括每个具有网络策略的容器组（pod）流日志。网络策略日志存储在 `/var/log/aws-routed-eni/network-policy-agent.log`。以下示例来自 `network-policy-agent.log` 文件：

```
{"level":"info","timestamp":"2023-05-30T16:05:32.573Z","logger":"ebpf-client","msg":"Flow Info: ","Src
IP":"192.168.87.155","Src Port":38971,"Dest IP":"64.6.160","Dest
Port":53,"Proto":"UDP","Verdict":"ACCEPT"}
```

默认情况下，网络策略日志被禁用。要启用网络策略日志，请按照下列步骤操作：

**注意**  
网络策略日志需要为 VPC CNI `aws-node` `DaemonSet` 清单中的 `aws-network-policy-agent` 容器额外提供 1 个 vCPU。

### Amazon EKS 附加组件
<a name="cni-network-policy-flowlogs-addon"></a>

 ** AWS 管理控制台 **   

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 在左侧导航窗格中，选择**集群**，然后选择要为其配置 Amazon VPC CNI 附加组件的集群名称。

1. 选择**附加组件**选项卡。

1. 选择附加组件框右上角的框，然后选择 **Edit**（编辑）。

1. 在**配置 *Amazon VPC CNI*** 页面上：

   1. 在**版本**下拉列表中选择 `v1.14.0-eksbuild.3` 或更高版本。

   1. 展开**可选配置设置**。

   1. 输入顶级 JSON 键 `"nodeAgent":`，值是一个在**配置值**中键为 `"enablePolicyEventLogs":` 且值为 `"true"` 的对象。生成的文本必须是有效的 JSON 对象。以下示例显示网络策略和网络策略日志已启用，并将网络策略日志发送到 CloudWatch Logs：

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true"
          }
      }
      ```

下面的屏幕截图为此场景的一个示例。

![\[<shared id="consolelong"/>在可选配置中显示带有网络策略和 CloudWatch Logs 的 VPC CNI 附加组件。\]](http://docs.aws.amazon.com/zh_cn/eks/latest/userguide/images/console-cni-config-network-policy-logs.png)


 AWS CLI  

1. 运行以下 AWS CLI 命令。将 `my-cluster` 替换为集群的名称，并将 IAM 角色 ARN 替换为您正在使用的角色。

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true"}}'
   ```

### 自主管理的附加组件
<a name="cni-network-policy-flowlogs-selfmanaged"></a>

Helm  
如果已通过 `helm` 安装适用于 Kubernetes 的 Amazon VPC CNI 插件，则可以更新配置来编写网络策略日志。  

1. 运行以下命令以启用网络策略。

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

kubectl  
如果已通过 `kubectl` 安装适用于 Kubernetes 的 Amazon VPC CNI 插件，则可以更新配置来编写网络策略日志。  

1. 在编辑器中打开 `aws-node` `DaemonSet`。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. 在 VPC CNI `aws-node` `DaemonSet` 清单中 `aws-network-policy-agent` 容器的 `args:` 中，将命令参数 `--enable-policy-event-logs=false` 中的 `false` 替换为 `true`。

   ```
        - args:
           - --enable-policy-event-logs=true
   ```

### 将网络策略日志发送到 Amazon CloudWatch Logs
<a name="network-policies-cloudwatchlogs"></a>

您可以使用 Amazon CloudWatch Logs 等服务监控网络策略日志。您可以使用以下方法将网络策略日志发送到 CloudWatch Logs。

对于 EKS 集群，策略日志将放在 `/aws/eks/cluster-name/cluster/` 下；对于自主管理型 K8S 集群，日志将放在 `/aws/k8s-cluster/cluster/` 下。

#### 使用适用于 Kubernetes 的 Amazon VPC CNI 插件发送网络策略日志
<a name="network-policies-cwl-agent"></a>

如果启用网络策略，则会将第二个容器添加到*节点代理*的 `aws-node` 容器组（pod）。此节点代理可将网络策略日志发送到 CloudWatch Logs。

**注意**  
节点代理仅发送网络策略日志。不包括 VPC CNI 生成的其它日志。

##### 先决条件
<a name="cni-network-policy-cwl-agent-prereqs"></a>
+ 将以下权限作为节或单独的策略添加到您用于 VPC CNI 的 IAM 角色中。

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "logs:DescribeLogGroups",
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": "*"
          }
      ]
  }
  ```

##### Amazon EKS 附加组件
<a name="cni-network-policy-cwl-agent-addon"></a>

 ** AWS 管理控制台 **   

1. 打开 [Amazon EKS 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

1. 在左侧导航窗格中，选择**集群**，然后选择要为其配置 Amazon VPC CNI 附加组件的集群名称。

1. 选择**附加组件**选项卡。

1. 选择附加组件框右上角的框，然后选择 **Edit**（编辑）。

1. 在**配置 *Amazon VPC CNI*** 页面上：

   1. 在**版本**下拉列表中选择 `v1.14.0-eksbuild.3` 或更高版本。

   1. 展开**可选配置设置**。

   1. 输入顶级 JSON 键 `"nodeAgent":`，值是一个在**配置值**中键为 `"enableCloudWatchLogs":` 且值为 `"true"` 的对象。生成的文本必须是有效的 JSON 对象。以下示例显示网络策略和网络策略日志已启用，并将日志发送到 CloudWatch Logs：

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true",
              "enableCloudWatchLogs": "true",
          }
      }
      ```
下面的屏幕截图为此场景的一个示例。

![\[<shared id="consolelong"/>在可选配置中显示带有网络策略和 CloudWatch Logs 的 VPC CNI 附加组件。\]](http://docs.aws.amazon.com/zh_cn/eks/latest/userguide/images/console-cni-config-network-policy-logs-cwl.png)


 ** AWSCLI**   

1. 运行以下 AWS CLI 命令。将 `my-cluster` 替换为集群的名称，并将 IAM 角色 ARN 替换为您正在使用的角色。

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true", "enableCloudWatchLogs": "true"}}'
   ```

##### 自主管理的附加组件
<a name="cni-network-policy-cwl-agent-selfmanaged"></a>

 **Helm**   
如果已通过 `helm` 安装适用于 Kubernetes 的 Amazon VPC CNI 插件，则可以更新配置，将网络策略日志发送至 CloudWatch 日志。  

1. 运行以下命令以启用网络策略日志并将它们发送到 CloudWatch Logs。

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true --set nodeAgent.enableCloudWatchLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

 **kubectl**   

1. 在编辑器中打开 `aws-node` `DaemonSet`。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. 在 VPC CNI `aws-node` `DaemonSet` 清单中 `aws-network-policy-agent` 容器的 `args:` 中，将两个命令参数 `--enable-policy-event-logs=false` 和 `--enable-cloudwatch-logs=false` 中的 `false` 替换为 `true`。

   ```
        - args:
           - --enable-policy-event-logs=true
           - --enable-cloudwatch-logs=true
   ```

#### 使用 Fluent Bit `DaemonSet` 发送网络策略日志
<a name="network-policies-cwl-fluentbit"></a>

如果在 `DaemonSet` 中使用 Fluent Bit 从节点发送日志，则可以添加配置，纳入来自网络策略的网络策略日志。您可以使用以下示例配置：

```
    [INPUT]
        Name              tail
        Tag               eksnp.*
        Path              /var/log/aws-routed-eni/network-policy-agent*.log
        Parser            json
        DB                /var/log/aws-routed-eni/flb_npagent.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10
```

## 包含的 eBPF SDK
<a name="network-policies-ebpf-sdk"></a>

适用于 Kubernetes 的 Amazon VPC CNI 插件在节点上安装 eBPF SDK 工具集。您可以使用 eBPF SDK 工具来识别网络策略问题。例如，以下命令列出了节点上正在运行的程序。

```
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
```

要运行此命令，您可以使用任何方法连接到节点。

## 已知问题和解决方案
<a name="network-policies-troubleshooting-known-issues"></a>

以下各节介绍了 Amazon VPC CNI 网络策略功能的已知问题及其解决方案。

### 尽管 enable-policy-event-logs 设置为 false，但仍会生成网络策略日志
<a name="network-policies-troubleshooting-policy-event-logs"></a>

 **问题**：即使将 `enable-policy-event-logs` 设置为 `false`，EKS VPC CNI 仍会生成网络策略日志。

 **解决方案**：`enable-policy-event-logs` 设置仅禁用策略“决策”日志，但不会禁用所有网络策略代理日志记录。此行为已在 GitHub 上的 [aws-network-policy-agent README](https://github.com/aws/aws-network-policy-agent/) 中记录。要完全禁用日志记录，您可能需要调整其他日志记录配置。

### 网络策略映射清理问题
<a name="network-policies-troubleshooting-map-cleanup"></a>

 **问题**：删除容器组后，网络 `policyendpoint` 仍存在且未被清理。

 **解决方案**：此问题是由于 VPC CNI 附加组件版本 1.19.3-eksbuild.1 的问题引起的。更新为较新版本的 VPC CNI 附加组件即可解决此问题。

### 网络策略未应用
<a name="network-policies-troubleshooting-policyendpoint"></a>

 **问题**：网络策略功能在 Amazon VPC CNI 附加组件中已启用，但未正确应用网络策略。

如果您制定了网络策略 `kind: NetworkPolicy`，但其对容器组没有影响，则请检查 policyendpoint 对象是否是在与容器组相同的命名空间中创建的。如果命名空间中没有 `policyendpoint` 对象，则网络策略控制器（EKS 集群的一部分）无法为网络策略代理（VPC CNI 的一部分）创建要应用的网络策略规则。

 **解决方案**：解决方案是修复 VPC CNI（`ClusterRole` : `aws-node`）和网络策略控制器（`ClusterRole` : `eks:network-policy-controller`）的权限，并允许在任何策略执行工具（例如 Kyverno）中执行这些操作。确保 Kyverno 策略不会阻止创建 `policyendpoint` 对象。有关[新的 `policyendpoints` CRD 和权限](#network-policies-troubleshooting-permissions)中所需的权限，请参阅上一节。

### 在严格模式下删除策略后，容器组不会恢复为默认拒绝状态
<a name="network-policies-troubleshooting-strict-mode-fallback"></a>

 **问题**：在严格模式下启用网络策略时，容器组以默认拒绝策略开头。应用策略后，允许流量到达指定的端点。但是，删除策略后，容器组不会恢复为默认拒绝状态，而是进入默认允许状态。

 **解决方案**：此问题在 VPC CNI 版本 1.19.3（包含网络策略代理 1.2.0 版本）中已修复。修复后，启用严格模式时，移除策略后，容器组将按预期恢复为默认拒绝状态。

### 容器组的安全组启动延迟
<a name="network-policies-troubleshooting-sgfp-latency"></a>

 **问题**：在 EKS 中使用容器组的安全组功能时，容器组启动延迟会增加。

 **解决方案**：延迟是由于资源控制器对 `CreateNetworkInterface` API 的速率限制（API 节流）造成的，VPC 资源控制器使用其为容器组创建分支 ENI。请查看您的账户针对此操作的 API 限制，并在需要时考虑申请提高限制。

### 由于 vpc.amazonaws.com/pod-eni 不足导致 FailedScheduling
<a name="network-policies-troubleshooting-insufficient-pod-eni"></a>

 **问题**：容器组无法调度，错误信息：`FailedScheduling 2m53s (x28 over 137m) default-scheduler 0/5 nodes are available: 5 Insufficient vpc.amazonaws.com/pod-eni. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod.`

 **解决方案**：与上一个问题类似，为容器组分配安全组会增加容器组调度延迟，并且添加每个 ENI 的时间可能会超出 CNI 阈值，从而导致容器组启动失败。这是使用容器组的安全组时的预期行为。在设计工作负载架构时，请考虑调度的影响。

### IPAM 连接问题和分段故障
<a name="network-policies-troubleshooting-systemd-udev"></a>

 **问题**：发生多个错误，包括 IPAM 连接问题、限制请求和分段故障：
+  `Checking for IPAM connectivity …​` 
+  `Throttling request took 1.047064274s` 
+  `Retrying waiting for IPAM-D` 
+  `panic: runtime error: invalid memory address or nil pointer dereference` 

 **解决方案**：如果您在 AL2023 上安装 `systemd-udev`，则会出现此问题，因为文件使用违反策略重写。更新为包含更新软件包的其他 `releasever` 或手动更新软件包本身时，可能会发生这种情况。避免在 AL2023 节点上安装或更新 `systemd-udev`。

### 无法按名称查找设备错误
<a name="network-policies-troubleshooting-device-not-found"></a>

 **问题**：错误消息：`{"level":"error","ts":"2025-02-05T20:27:18.669Z","caller":"ebpf/bpf_client.go:578","msg":"failed to find device by name eni9ea69618bf0: %!w(netlink.LinkNotFoundError={0xc000115310})"}`

 **解决方案**：此问题已发现并在最新版本的 Amazon VPC CNI 网络策略代理（v1.2.0）中修复。更新到最新版本的 VPC CNI 即可解决此问题。

### Multus CNI 映像中的 CVE 漏洞
<a name="network-policies-troubleshooting-cve-multus"></a>

 **问题**：增强版 EKS ImageScan CVE 报告发现 Multus CNI 映像版本 v4.1.4-eksbuild.2\$1thick 中存在漏洞。

 **解决方案**：更新为无漏洞的新版本 Multus CNI 映像和新的网络策略控制器映像。可以更新扫描器以修复先前版本中发现的漏洞。

### 日志中的 Flow Info DENY 裁决
<a name="network-policies-troubleshooting-flow-info-deny"></a>

 **问题**：网络策略日志显示 DENY 裁决：`{"level":"info","ts":"2024-11-25T13:34:24.808Z","logger":"ebpf-client","caller":"events/events.go:193","msg":"Flow Info: ","Src IP":"","Src Port":9096,"Dest IP":"","Dest Port":56830,"Proto":"TCP","Verdict":"DENY"}`

 **解决方案**：此问题已在新版本的网络策略控制器中得到解决。更新为最新的 EKS 平台版本即可解决日志记录问题。

### 从 Calico 迁移后容器组到容器组的通信问题
<a name="network-policies-troubleshooting-calico-migration"></a>

 **问题**：将 EKS 集群升级到版本 1.30 并将网络策略从 Calico 切换到 Amazon VPC CNI 后，应用网络策略后容器组到容器组的通信失败。删除网络策略后，通信即恢复。

 **解决方案**：VPC CNI 中的网络策略代理不能像 Calico 那样指定那么多的端口。相反，在网络策略中使用端口范围。网络策略中每个 `ingress:` 或 `egress:` 选择器中每个协议的唯一端口组合数最多为 24 个。使用端口范围可减少唯一端口的数量和避免此限制。

### 网络策略代理不支持独立容器组
<a name="network-policies-troubleshooting-standalone-pods"></a>

 **问题**：应用于独立容器组的网络策略可能存在不一致的行为。

 **解决方案**：网络策略代理目前仅支持作为部署/副本集一部分部署的容器组。如果将网络策略应用至独立容器组，则行为可能存在一些不一致。这将记录在本页顶部、[注意事项](cni-network-policy.md#cni-network-policy-considerations) 中和 GitHub 上的 [aws-network-policy-agent GitHub issue \$1327](https://github.com/aws/aws-network-policy-agent/issues/327) 中。将容器组作为部署或副本集的一部分进行部署，以实现一致的网络策略行为。