使用 FQDN 网络政策控制 Pod 出站流量


本页面介绍如何使用完全限定的域名 (FQDN) 控制 Pod 与 Google Kubernetes Engine (GKE) 集群外部资源之间的出站通信。用于配置 FQDN 的自定义资源是 FQDNNetworkPolicy 资源。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

要求和限制

FQDNNetworkPolicy 资源有以下要求和限制:

  • 您必须有一个运行以下版本的 GKE 集群:
    • 1.26.4-gke.500 或更高版本
    • 1.27.1-gke.400 或更高版本
  • 您的集群必须使用 GKE Dataplane V2
  • 您必须使用 GKE 集群中的一个 DNS 提供商:kube-dns 或 Cloud DNS。不支持自定义 kube-dns 或核心 DNS 部署。
  • Google Cloud CLI 462.0.0 版或更高版本。
  • 不支持 Windows 节点池。
  • 不支持 Anthos Service Mesh。
  • 如果您的应用中包含硬编码的 IP 地址,请使用 Kubernetes NetworkPolicyIPBlock field,而不是 FQDNNetworkPolicy
  • 非集群 DNS 域名服务器(例如 resolv.conf 中的备用域名服务器)返回的结果不被视为可在 GKE 数据平面的许可名单中编程。
  • FQDNNetworkPolicy 可以解析为最多 50 个 IPv4 和 IPv6 IP 地址。
  • 您不能允许流向 ClusterIP 或无头服务的流量作为 FQDNNetworkPolicy 中的出站流量目的地,因为 GKE 在评估网络政策规则之前会将服务虚拟 IP 地址 (VIP) 转换为后端 Pod IP 地址。请改用基于 Kubernetes 标签的 NetworkPolicy
  • 每个主机名最多只能有 100 个 IP 地址。
  • FQDN 网络政策不支持节点间透明加密。

启用 FQDN 网络政策

您可以在新集群或现有集群上启用 FQDN 网络政策。

在新集群中启用 FQDN 网络政策

使用 --enable-fqdn-network-policy 标志创建集群:

gcloud container clusters create CLUSTER_NAME  \
    --enable-fqdn-network-policy

CLUSTER_NAME 替换为您的集群名称。

在现有集群中启用 FQDN 网络政策

  1. 对于 Autopilot 集群和 Standard 集群,都使用 --enable-fqdn-network-policy 标志更新集群:

    gcloud container clusters update CLUSTER_NAME  \
        --enable-fqdn-network-policy
    

    CLUSTER_NAME 替换为您的集群名称。

  2. 对于 Standard 集群,重启 GKE Dataplane V2 anetd DaemonSet:

    kubectl rollout restart ds -n kube-system anetd
    

创建 FQDNNetworkPolicy

  1. 将以下清单保存为 fqdn-network-policy.yaml

    apiVersion: networking.gke.io/v1alpha1
    kind: FQDNNetworkPolicy
    metadata:
      name: allow-out-fqdnnp
    spec:
      podSelector:
        matchLabels:
          app: curl-client
      egress:
      - matches:
        - pattern: "*.yourdomain.com"
        - name: "www.google.com"
        ports:
        - protocol: "TCP"
          port: 443
    

    此清单具有以下属性:

    • name: www.google.com:完全限定域名。允许使用与 www.google.com 关联的域名服务器提供的 IP 地址。您必须指定 name 和/或 pattern
    • pattern: "*.yourdomain.com":允许使用符合此模式的域名服务器提供的 IP 地址。您可以对模式键使用以下正则表达式:^([a-zA-Z0-9*]([-a-zA-Z0-9_*]*[a-zA-Z0-9*])*\.?)*$。匹配条件是累加的。您可以使用多个 pattern 字段。您必须指定 name 和/或 pattern
    • protocol: "TCP"port: 443:指定协议和端口。如果 Pod 尝试使用此协议和端口的组合与 IP 地址建立连接,则名称解析有效,但数据平面会阻止出站连接。此字段是可选字段。
  2. 验证网络政策是否选择您的工作负载:

    kubectl describe fqdnnp
    

    输出类似于以下内容:

    Name:         allow-out-fqdnnp
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1alpha1
    Kind:         FQDNNetworkPolicy
    Metadata:
    ...
    Spec:
      Egress:
        Matches:
          Pattern:  *.yourdomain.com
          Name:     www.google.com
        Ports:
          Port:      443
          Protocol:  TCP
      Pod Selector:
        Match Labels:
          App: curl-client
    Events:     <none>
    

删除 FQDNNetworkPolicy

您可以使用 kubectl delete fqdnnp 命令删除 FQDNNetworkPolicy

kubectl delete fqdnnp FQDN_POLICY_NAME

FQDN_POLICY_NAME 替换为 FQDNNetworkPolicy 的名称。

GKE 会从强制执行政策中删除规则,但现有连接在按照 conntrack 标准协议准则关闭之前会保持活跃状态。

FQDN 网络政策的工作原理

FQDNNetworkPolicies 是仅限出站流量的政策,用于控制所选 Pod 可以将流量发送到哪些端点。与 Kubernetes NetworkPolicy 类似,选择工作负载的 FQDNNetworkPolicy 会针对未指定为允许的出站流量目的地的端点创建隐含拒绝规则。FQDNNetworkPolicies 可与 Kubernetes NetworkPolicies 搭配使用(如 FQDNNetworkPolicy 和 NetworkPolicy 中所述)。

FQDNNetworkPolicies 在 IP 地址和端口级别上强制执行。系统不会使用任何第 7 层协议信息(例如 HTTP 请求中的 Request-URI)来强制执行它们。系统会使用 GKE 集群的 DNS 提供商所提供的 DNS 信息将指定域名转换为 IP 地址。

DNS 请求

选择工作负载的活跃 FQDNNetworkPolicy 不会影响工作负载发出 DNS 请求的能力。nslookupdig 等命令适用于任何网域,且不受政策影响。但是,对未在允许者中的 IP 地址支持网域的后续请求将被丢弃。

比方说,如果 FQDNNetworkPolicy 允许流向 www.github.com 的出站流量,则允许发出针对所有网域的 DNS 请求,但发送到支持 twitter.com 的 IP 地址的流量会被丢弃。

TTL 到期

FQDNNetworkPolicy 遵循 DNS 记录提供的 TTL。如果 Pod 尝试在 DNS 记录的 TTL 经过后与过期的 IP 地址联系,则新连接会被拒绝。持续时间超过 DNS 记录的 TTL 的长期有效连接在 conntrack 认为连接仍处于活动状态时,不会出现流量中断。

FQDNNetworkPolicy 和 NetworkPolicy

FQDNNetworkPolicyNetworkPolicy 同时应用于同一 Pod 时,这意味着 Pod 的标签与政策中配置的内容一致,只要它与其中一个政策匹配,就允许出站流量。指定 IP 地址或标签选择器的出站流量 NetworkPoliciesFQDNNetworkPolicies 之间没有层次结构。

共享 IP 地址端点(负载均衡器、CDN、VPN 网关等)

许多网域没有为它们提供支持的专用 IP 地址,而是使用共享 IP 地址进行公开。当应用由负载均衡器或 CDN 提供服务时,这种情况尤其常见。例如,Google Cloud API(compute.googleapis.comcontainer.googleapis.com 等)没有针对每个 API 的唯一 IP 地址。相反,所有 API 都使用共享范围进行公开。

配置 FQDNNetworkPolicies 时,请务必考虑允许的网域所使用的是专用 IP 地址还是共享 IP 地址。由于 FQDNNetworkPolicies 在 IP 地址和端口级别上强制执行,因此它们无法区分由同一 IP 地址提供服务的多个网域。如果允许访问由共享 IP 地址提供支持的网域,则您的 Pod 可以与由该 IP 地址提供服务的所有其他网域通信。例如,允许流量流向 compute.googleapis.com 也会允许 Pod 与其他 Google Cloud API 通信。

CNAME 追踪

如果 FQDNNetworkPolicy 中的 FQDN 对象包含 DNS 记录中包含 CNAME 的网域,则必须使用 Pod 可以直接查询的所有域名(包括所有可能的别名)配置 FQDNNetworkPolicy,以确保 FQDNNetworkPolicy 行为具有可靠性。

如果您的 Pod 查询 example.com,则您应在规则中写入 example.com。即使您从上游 DNS 服务器获取别名链(例如 example.comexample.cdn.com1.2.3.4),FQDN 网络政策仍将允许您的流量通过。

已知问题

本部分列出了有关完全限定域名 (FQDN) 的所有已知问题。

指定 protocol: ALL 会导致该政策被忽略

此已知问题已在 GKE 1.27.10-gke.1055000+ 和 1.28.3-gke.1055000+ 版中得到修复

如果您创建在 ports 部分中指定 protocol: ALLFQDNNetworkPolicy,则 GKE 不会强制执行该政策。此问题会因解析政策时出现问题而发生。指定 TCPUDP 不会导致此问题。

作为一种解决方案,如果您未在 ports 条目中指定 protocol,则规则会默认匹配所有协议。移除 protocol: ALL 可绕过解析问题,GKE 会强制执行 FQDNNetworkPolicy

在 GKE 1.27.10-gke.1055000+ 和 1.28.3-gke.1055000+ 版中,具有 protocol: ALL 的政策可正确解析并强制执行。

网络政策日志记录导致日志不正确或缺失

此已知问题已在 GKE 1.27.10-gke.1055000+ 和 1.28.2-gke.1157000+ 版中得到修复

如果您的集群使用网络政策日志记录和 FQDN 网络政策,则存在一个错误,它可能会导致日志条目缺失或不正确。

在无委托的情况下使用网络政策日志记录时,离开工作负载的 DNS 连接的政策日志会错误地声明流量被丢弃。允许流量本身(根据 FQDNNetworkPolicy),但日志不正确。

在有委托的情况下使用网络政策日志记录时,政策日志会缺失。流量本身不受影响。

在 GKE 1.27.10-gke.105500+ 和 1.28.2-gke.1157000+ 版中,此错误已得到修复。现在,当 NetworkPolicyFQDNNetworkPolicy 选择流量时,DNS 连接会正确记录为 ALLOWED。

后续步骤