排查 Amazon EKS 的 Kubernetes 网络策略问题 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

帮助改进此页面

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

排查 Amazon EKS 的 Kubernetes 网络策略问题

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

本指南涵盖以下内容:

注意

请注意,网络策略仅适用于通过 Kubernetes 部署创建的容器组。有关 VPC CNI 中网络策略的更多限制,请参阅注意事项

您可以通过查看网络策略日志和运行 eBPF SDK 中的工具,对使用网络策略的网络连接进行问题排查和调查。

新的 policyendpoints CRD 和权限

  • CRD:policyendpoints.networking.k8s.aws

  • Kubernetes API:名为 v1.networking.k8s.ioapiservice

  • Kubernetes 资源:Kind: NetworkPolicy

  • RBAC:名为 aws-nodeClusterRole(VPC CNI),名为 eks:network-policy-controllerClusterRole(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 文件中提供。具体而言,VPC CNI 必须具有对 policyendpoints 执行“获取”、“列出”和“监控”操作的权限。

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

VPC CNI 权限位于名为 aws-nodeClusterRole 中。请注意,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-controllerClusterRole 的权限。以下显示了集群的 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

网络策略日志

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 附加组件

Amazon Web Services Management Console
  1. 打开 Amazon EKS 控制台

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

  3. 选择附加组件选项卡。

  4. 选择附加组件框右上角的框,然后选择 Edit(编辑)。

  5. 配置 Amazon VPC CNI 页面上:

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

    2. 展开可选配置设置

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

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

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

<shared id="consolelong"/>在可选配置中显示带有网络策略和 CloudWatch Logs 的 VPC CNI 附加组件。
Amazon CLI
  1. 运行以下 Amazon 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-cn:iam::123456789012:role/AmazonEKSVPCCNIRole \ --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true"}}'

自行管理的附加组件

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
  2. 在 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

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

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

使用适用于 Kubernetes 的 Amazon VPC CNI 插件发送网络策略日志

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

注意

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

先决条件
  • 将以下权限作为节或单独的策略添加到您用于 VPC CNI 的 IAM 角色中。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "logs:DescribeLogGroups", "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" } ] }
Amazon EKS 附加组件
Amazon Web Services Management Console
  1. 打开 Amazon EKS 控制台

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

  3. 选择附加组件选项卡。

  4. 选择附加组件框右上角的框,然后选择 Edit(编辑)。

  5. 配置 Amazon VPC CNI 页面上:

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

    2. 展开可选配置设置

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

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

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

<shared id="consolelong"/>在可选配置中显示带有网络策略和 CloudWatch Logs 的 VPC CNI 附加组件。
Amazon CLI
  1. 运行以下 Amazon 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-cn:iam::123456789012:role/AmazonEKSVPCCNIRole \ --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true", "enableCloudWatchLogs": "true"}}'
自行管理的附加组件
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
  2. 在 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 发送网络策略日志

如果在 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

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

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

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

已知问题和解决方案

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

尽管 enable-policy-event-logs 设置为 false,但仍会生成网络策略日志

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

解决方案enable-policy-event-logs 设置仅禁用策略“决策”日志,但不会禁用所有网络策略代理日志记录。此行为已在 GitHub 上的 aws-network-policy-agent README 中记录。要完全禁用日志记录,您可能需要调整其他日志记录配置。

网络策略映射清理问题

问题:删除容器组后,网络 policyendpoint 仍存在且未被清理。

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

网络策略未应用

问题:网络策略功能在 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 和权限中所需的权限,请参阅上一节。

在严格模式下删除策略后,容器组不会恢复为默认拒绝状态

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

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

容器组的安全组启动延迟

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

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

由于 vpc.amazonaws.com/pod-eni 不足导致 FailedScheduling

问题:容器组无法调度,错误信息: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 连接问题和分段故障

问题:发生多个错误,包括 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

无法按名称查找设备错误

问题:错误消息:{"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 漏洞

问题:增强版 EKS ImageScan CVE 报告发现 Multus CNI 映像版本 v4.1.4-eksbuild.2_thick 中存在漏洞。

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

日志中的 Flow Info DENY 裁决

问题:网络策略日志显示 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 迁移后容器组到容器组的通信问题

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

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

网络策略代理不支持独立容器组

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

解决方案:网络策略代理目前仅支持作为部署/副本集一部分部署的容器组。如果将网络策略应用至独立容器组,则行为可能存在一些不一致。这将记录在本页顶部、注意事项 中和 GitHub 上的 aws-network-policy-agent GitHub issue #327 中。将容器组作为部署或副本集的一部分进行部署,以实现一致的网络策略行为。