本页面介绍如何使用完全限定的域名 (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
以获取最新版本。
- 按照说明启用 GKE Enterprise。
要求和限制
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
NetworkPolicy
的IPBlock
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 网络政策
对于 Autopilot 集群和 Standard 集群,都使用
--enable-fqdn-network-policy
标志更新集群:gcloud container clusters update CLUSTER_NAME \ --enable-fqdn-network-policy
将
CLUSTER_NAME
替换为您的集群名称。仅对于 Standard 集群,重启 GKE Dataplane V2
anetd
DaemonSet:kubectl rollout restart ds -n kube-system anetd
创建 FQDNNetworkPolicy
将以下清单保存为
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 地址建立连接,则名称解析有效,但数据平面会阻止出站连接。此字段是可选字段。
验证网络政策是否选择您的工作负载:
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 请求的能力。nslookup
或 dig
等命令适用于任何网域,且不受政策影响。但是,对未在允许者中的 IP 地址支持网域的后续请求将被丢弃。
比方说,如果 FQDNNetworkPolicy
允许流向 www.github.com
的出站流量,则允许发出针对所有网域的 DNS 请求,但发送到支持 twitter.com
的 IP 地址的流量会被丢弃。
TTL 到期
FQDNNetworkPolicy
遵循 DNS 记录提供的 TTL。如果 Pod 尝试在 DNS 记录的 TTL 经过后与过期的 IP 地址联系,则新连接会被拒绝。持续时间超过 DNS 记录的 TTL 的长期有效连接在 conntrack 认为连接仍处于活动状态时,不会出现流量中断。
FQDNNetworkPolicy 和 NetworkPolicy
当 FQDNNetworkPolicy
和 NetworkPolicy
同时应用于同一 Pod 时,这意味着 Pod 的标签与政策中配置的内容一致,只要它与其中一个政策匹配,就允许出站流量。指定 IP 地址或标签选择器的出站流量 NetworkPolicies
与 FQDNNetworkPolicies
之间没有层次结构。
共享 IP 地址端点(负载均衡器、CDN、VPN 网关等)
许多网域没有为它们提供支持的专用 IP 地址,而是使用共享 IP 地址进行公开。当应用由负载均衡器或 CDN 提供服务时,这种情况尤其常见。例如,Google Cloud API(compute.googleapis.com
、container.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.com
到 example.cdn.com
到 1.2.3.4
),FQDN 网络政策仍将允许您的流量通过。
已知问题
本部分列出了有关完全限定域名 (FQDN) 的所有已知问题。
指定 protocol: ALL
会导致该政策被忽略
此已知问题已在 GKE 1.27.10-gke.1055000+ 和 1.28.3-gke.1055000+ 版中得到修复
如果您创建在 ports
部分中指定 protocol: ALL
的 FQDNNetworkPolicy
,则 GKE 不会强制执行该政策。此问题会因解析政策时出现问题而发生。指定 TCP
或 UDP
不会导致此问题。
作为一种解决方案,如果您未在 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+ 版中,此错误已得到修复。现在,当 NetworkPolicy
或 FQDNNetworkPolicy
选择流量时,DNS 连接会正确记录为 ALLOWED。