Google Kubernetes Engine (GKE) 网络使用并扩展了虚拟私有云 (VPC) 提供的软件定义网络 (SDN) 基础架构。借助 GKE 网络,您的组件可以在 Kubernetes 集群内以及与外部服务和网络进行通信。GKE 网络模型以 Kubernetes 网络原则(即每个 Pod 都有自己的 IP 地址)为基础,提供 IP 地址分配、负载均衡、DNS 解析和网络政策强制执行功能。本文档介绍了节点、Pod 和 Service 等核心组件如何在 GKE 网络环境中与控制平面互动,涵盖以下内容:
- 这些组件在 VPC 内的互动方式
- IP 地址的分配和管理方式
- 流量如何流入、流经和流出集群
GKE 网络的架构
GKE 网络基于 Google Cloud的虚拟私有云 (VPC) 构建。此基础架构可为所有容器化应用提供强大且可伸缩的连接。
VPC 基础和 IP 地址范围
在 VPC 内,您可以定义子网,即区域级 IP 地址范围。GKE 会在这些子网中战略性地使用不同的 IP 地址范围来分配给各种集群组件,通常会使用 VPC 别名 IP 地址范围:
- 节点 IP 地址范围:这是在其中部署集群节点的子网的主要 IP 地址范围。您的所有 GKE 工作器节点(即 Compute Engine 虚拟机)都会从此范围内获取主要 IP 地址。这些 IP 地址用于节点之间的通信以及负载均衡器的健康检查。节点 IP 地址也是源自节点本身的流量的来源。在 VPC 原生集群中,来自 Pod 的流量使用 Pod IP 地址作为源地址,除非 Pod IP 地址被 Cloud NAT 等功能转换。
- Pod IP 地址范围:子网内专用的次要 IP 地址范围,通常是较大的 CIDR 地址块。每个节点都会从此范围内接收一个 IP 地址池。GKE 会将这些 IP 地址分配给在该节点上运行的 Pod。集群中的每个 Pod 都会从该范围内获取其唯一的 IP 地址。这些 Pod IP 地址可在您的虚拟私有云中进行原生路由。默认情况下,每个节点都会获取一个
/24范围,其中包含 256 个 IP 地址。不过,GKE 将每个节点的 Pod 数上限限制为 110。此缓冲区有助于确保在快速创建和删除 Pod(也称为 churn)期间 IP 地址的可用性。这些 IP 地址可实现不同节点上的 Pod 之间的直接通信,而无需进行网络地址转换 (NAT)。 - 服务 IP 地址范围 (ClusterIP):一个次要 IP 地址范围,用于分配给 Kubernetes Service 的虚拟 IP 地址 (ClusterIP)。这些稳定的 IP 地址仅用于集群内的通信。
- 控制平面 IP 地址:每个控制平面都有一个公共或内部 IP 地址,具体取决于集群类型、版本和创建日期。工作节点和外部客户端(例如
kubectl)使用此 IP 地址与 Kubernetes API 服务器安全地通信。GKE 前端 (GKFE) 为每个集群提供基于 DNS 的端点,从而提供一种安全可靠的方式来访问控制平面,而无需直接管理 IP 地址。
GKE 网络的三大支柱
GKE 网络由三个相互关联的支柱组成,每个支柱代表一个不同的通信层。此框架可帮助您了解应用在集群内以及与外部网络之间的通信方式:
- Pod 网络:基础层,用于定义集群内的各个容器 (Pod) 如何相互通信。
- Service 网络:此层基于 Pod 网络构建,描述了 Kubernetes Service 如何提供稳定的端点来向内部或外部客户端公开应用,包括负载均衡和服务发现。
- 集群网络:最外层,涵盖整个 GKE 集群如何连接到更广泛的网络生态系统,包括管理来自互联网的入站流量、到外部服务的出站流量,以及与 Google Cloud 服务和本地系统的连接。
这些层共同构成了一个全面的通信模型,可支持内部和外部连接、安全性及可伸缩性。以下各部分将详细探讨每个支柱。
Pod 网络
Pod 网络是 GKE 集群内所有通信的基础。它定义了在 Pod 内运行的应用如何查找彼此并相互互动。在 Kubernetes 中,Pod 是最小且最基本的可部署单元。Pod 可充当应用的逻辑宿主。 它运行一个或多个共享网络资源的容器。当 Pod 被安排在某节点上运行时,Kubernetes 会在该节点的 Linux 内核中为其创建一个专用网络命名空间,以将其网络与同一节点上的其他 Pod 隔离开来。
Pod 网络的工作原理
Pod 网络通过独特的 IP 地址、虚拟网络设备和管理连接的专用插件组合而成。
容器网络接口 (CNI):GKE 使用 CNI 插件来实现和管理 Pod 网络。对于 VPC 原生集群,默认值为 Google CNI。其他选项包括 kubenet(适用于非 VPC 原生集群)、Calico 和 GKE Dataplane V2(基于 Cilium)。这些插件负责将 Pod 连接到网络并强制执行网络政策。
IP 地址分配:每个节点都会从 Pod IP 地址范围接收一个 IP 地址池,以分配给 Pod。GKE 会预留一部分此类地址,以创建一个缓冲区,确保在 Pod 快速流失(创建和销毁)期间 IP 地址可用。正是因为这种预留,每个节点的可分配 Pod IP 地址数量始终小于相应范围的大小。
网络命名空间和虚拟以太网 (veth) 对:为了方便通信,Kubernetes 会将 Pod 的隔离网络命名空间连接到节点的主网络命名空间(即根网络命名空间)。Kubernetes 通过使用虚拟以太网对(即 veth 对,其作用类似于虚拟网线)来建立此连接。该对的一端放置在 Pod 的命名空间内,并显示为
eth0。另一端连接到网络桥接或直接连接到节点根命名空间中的节点网络栈,从而允许数据包进出 Pod。特定连接方法取决于集群使用的 CNI 插件:
- Google CNI:这是 VPC 原生集群的默认 CNI。Pod 的 veth 对连接到节点的根网络命名空间。由于 Pod IP 地址是 VPC 网络已知的别名 IP 地址,因此节点上的标准 Linux 路由会将流量定向到 Pod 和从 Pod 定向流量。
- GKE Dataplane V2:它使用 eBPF 程序来处理 Pod 网络,通常会绕过传统的 Linux 网桥和 veth 对,直接管理内核中的数据包流,以实现更高的性能。
- Kubenet:它用于非 VPC 原生集群。veth pair 的另一端连接到节点根命名空间中称为
cbr0的 Linux 网桥设备。此网桥用于管理同一节点上 Pod 之间的流量,并使用 NAT 处理离开节点的流量。 - Calico:如果使用 Calico 启用网络政策,veth pair 的另一端会连接到节点的根命名空间,然后 Calico 会对主机路由进行编程,以将流量定向到正确的 Pod。
最大传输单元 (MTU):此设置决定了可通过网络发送的最大数据包大小(无需分段)。在 GKE 中,Pod 接口的 MTU 是一项关键设置,取决于集群使用的 GKE CNI 插件和底层 VPC 网络的 MTU 设置。MTU 值不匹配可能会导致丢包或性能下降。Pod 接口 MTU 值要么是固定的 1,460 个字节,要么是从节点的主要网络接口继承,如下表所示。
| CNI | MTU | 用法 |
|---|---|---|
| Google CNI | 1460 | 使用 1.26.1 之前版本的 GKE 的 VPC 原生集群的默认值。 |
| Google CNI | 继承 | 使用 GKE 1.26.1 版及更高版本的 VPC 原生集群的默认值。 |
| Calico | 1460 | 在启用网络政策 (--enable-network-policy) 时使用。 |
| GKE Dataplane V2 | 继承 | 在启用 GKE Dataplane V2 (--enable-dataplane-v2) 时使用。 |
| netd | 继承 | 在启用“节点内”可见性、Workload Identity Federation for GKE 或 IPv4/IPv6 双栈网络等功能时使用。 |
Pod 到 Pod 的通信流
Kubernetes 使用平面网络模型,其中每个 Pod 都有一个唯一的、可路由的 IP 地址。此模型有助于确保 Pod 之间的连接顺畅无缝。
同一节点内的通信
当一个 Pod 向同一节点上的另一个 Pod 发送流量时,请求会从第一个 Pod 的网络命名空间流经其 veth pair,然后进入节点的根网络命名空间。此流量保留在节点内。然后,CNI 插件会根据所使用的 CNI 插件将流量转发到第二个 Pod 的 veth pair。例如,使用 kubenet 时,网桥设备会转发流量。借助 GKE Dataplane V2,eBPF 程序可直接管理数据包流。
不同节点之间的通信
当一个节点上的 Pod 将流量发送到另一个节点上的 Pod 时,流量会流向第一个节点的根网络命名空间。然后,流量会离开第一个节点的主要网络接口,进入 VPC 网络。由于 Pod IP 地址可在 VPC 原生 GKE 集群中进行原生路由,因此 VPC 网络会将流量直接路由到第二个节点。然后,第二个节点将流量转发到目标 Pod。
主机网络 Pod
对于特定使用情形,您可以为 Pod 配置 hostNetwork: true 设置。此设置会绕过隔离的 Pod 网络,让 Pod 直接共享节点的网络命名空间。通过这种直接访问,Pod 使用节点的 IP 地址,无需 NAT 即可与所有其他 Pod 通信。在使用 kubenet CNI 插件的集群中,此行为与常规 Pod 不同。常规 Pod 需要 NAT 来处理出站流量,因为它们的 IP 地址无法在 VPC 网络上直接路由。相比之下,GKE 的 VPC 原生网络可让所有 Pod 无需进行此转换。不过,在为 Pod 配置 hostNetwork: true 设置时,请务必小心,以免端口与在同一节点上运行的其他进程或 Pod 发生冲突。在使用 kubenet CNI 的集群中,仅当节点具有设置了 hostNetwork: false 的 Pod 时,才会创建 cbr0 虚拟网络网桥。
服务网络
虽然 Pod 网络提供了各个 Pod 之间的基本连接,但不足以构建稳健、可扩缩的应用。Pod 是临时性的,可以随时创建、销毁和重新调度。此情况会导致其 IP 地址发生变化。Service 网络通过提供一种稳定可靠的方式来公开应用并管理它们在集群内部以及与外界的通信方式,从而解决此问题。
Kubernetes Service 是一个抽象概念,定义了一个逻辑 Pod 集及其访问政策。Service 使用标签将多个相关的 Pod 组合成单个逻辑单元。创建 Service 时,Kubernetes 会从为 Service 预留的地址池中为其分配一个稳定的虚拟 IP 地址,称为 ClusterIP。此 ClusterIP 以及关联的 DNS 名称在整个 Service 生命周期内保持不变,从而提供一致的端点,供其他应用用于连接到 Pod。
Service 网络的工作原理
Service 网络依赖于两种关键机制,以将流量从 Service 的稳定端点路由到其动态后端 Pod:服务发现和负载均衡。
服务发现:为了让应用能够相互查找和通信,GKE 提供内部 DNS 服务(kube-dns 或 Cloud DNS)。创建 Service 时,DNS 服务会自动创建相应的 DNS 记录。借助此记录,应用可以使用 Service 的 DNS 名称(例如 my-app-service)连接到 Service,而无需知道其 ClusterIP。虽然 kube-dns 是 Standard 集群的默认设置,但 Cloud DNS for GKE 是大多数生产环境的推荐解决方案。它也是 GKE Autopilot 集群唯一受支持的解决方案。此服务是全托管式服务,具有可伸缩性和高可用性。它可与 VPC 网络和 Cloud Logging 集成,从而在无需您管理 kube-dns Pod 的情况下,提供更高的性能和可观测性。
负载均衡机制:Service 负载均衡的实现取决于 GKE 集群的网络模式。
GKE Dataplane V2:使用 GKE Dataplane V2(基于 Cilium)的集群不使用
kube-proxy进行 Service 负载均衡。相反,GKE Dataplane V2 使用在 Linux 内核中运行的 eBPF 程序。这些 eBPF 程序可以高效地拦截流向 Service ClusterIP 的流量,并直接将流量负载均衡到适当的后端 Pod。此方法可带来更好的性能,并与 GKE Dataplane V2 的网络政策强制执行功能紧密集成。kube-proxy(适用于未使用 GKE Dataplane V2 的集群):在未使用 GKE Dataplane V2 的 GKE 集群中的每个节点上,称为kube-proxy的组件会为 Service 实现虚拟 IP 地址机制。kube-proxy会监视 Kubernetes API 服务器,以了解 Service 和端点的更改,然后在节点上对网络规则进行编程,以拦截发往 Service ClusterIP 的流量。kube-proxy可以在不同模式下运行,包括:iptables模式:这是默认模式。kube-proxy在节点的iptables子系统中添加和移除目标 NAT (DNAT) 规则。当流量到达 Service 的 ClusterIP 时,这些规则会执行 NAT 转换,并将目标 IP 地址更改为其中一个健康状况良好的后端 Pod。后端 Pod 之间的负载均衡通常是随机或轮询的。ipvs模式:此模式使用 Linux IP 虚拟服务器 (IPVS) 实现高性能负载均衡。kube-proxy用于配置 IPVS 规则,这些规则可以处理大量服务,并提供更复杂的负载均衡算法。
内部沟通流示例
以下列表介绍了在不使用 GKE Dataplane V2 的集群中,请求如何通过 Service 从客户端 Pod 流向服务器 Pod:
- 客户端应用针对
my-server-service发出 DNS 查询。 - 集群的内部 DNS 服务会将此名称解析为 Service 的稳定 ClusterIP(例如
10.0.32.8)。 - 客户端 Pod 向 Service 的 ClusterIP 发送请求。
- 客户端节点上由
kube-proxy管理的iptables规则会拦截此请求。 - 这些
iptables规则执行 DNAT,并为my-server-service选择其中一个健康状况良好的后端 Pod(例如,IP 地址为10.4.0.3的 Pod 2)。这些规则还会将数据包的目标 IP 地址重写为 Pod 的 IP 地址。 - 数据包通过平面 Pod 网络路由到 Pod 2,后者会处理该请求。
在使用 GKE Dataplane V2 的集群中,eBPF 程序会处理对 Service ClusterIP 的流量拦截和负载均衡,从而绕过 kube-proxy 和 iptables。
Service 清单示例
以下示例展示了 Service 清单。selector 字段用于指定哪些 Pod 根据标签接收流量。
apiVersion: v1
kind: Service
metadata:
name: my-server-service
spec:
selector:
app: my-server # This should match the labels on your server Pods
ports:
- protocol: TCP
port: 80 # The port the Service exposes
targetPort: 8080 # The port the containers in the Pods are listening on
Service 网络的功能
GKE Service 网络提供了多项功能,可用于管理流量并公开应用(无论是在内部还是外部)。
- 内部和外部负载均衡。对于仅需要从集群内访问的 Service,
kube-proxy(或 GKE Dataplane V2)会在内部处理负载均衡。对于需要向互联网公开的 Service,GKE 会自动预配云负载均衡器,以将外部流量分配到集群中的节点。 - 用于 HTTP(S) 路由的应用负载均衡器。对于 HTTP(S) 流量,GKE 使用专用的第 7 层负载均衡器,即应用负载均衡器。您可以使用 Kubernetes Gateway API 配置此负载均衡器,这是适用于所有新应用的建议方法。GKE Gateway 控制器是 Google 对 Gateway API 的实现,旨在成为 Ingress 资源更具表现力、更灵活且更可扩展的后继产品。Gateway API 使用以下资源来配置负载均衡器:
- 网关:定义监听器配置,例如端口、协议和主机名。它充当流量的入口点。
- HTTPRoute:指定网关接收的流量如何路由到 Service。 它支持基于路径的路由、标头匹配和流量分配等高级功能。
- 政策:通过附加到网关、路由或 Service,来定义底层 Google Cloud 基础设施的运行方式。
- 服务网格集成:对于复杂的微服务架构,GKE 支持服务网格技术。服务网格是一个可选的基础设施层,可提供流量管理、可观测性和安全性方面的高级功能。为了提供全托管式和支持体验,GKE 提供了基于 Istio 构建的 Cloud Service Mesh。
集群网络
集群网络是 GKE 网络的最外层。它侧重于整个 Kubernetes 集群如何与外部资源和网络互动,包括互联网客户端如何访问您的应用、您的 Pod 如何访问外部 API,以及您的集群如何连接到本地数据中心。集群网络基于 Google Cloud的 VPC 基础设施构建。
管理入站流量
入站流量是指从外部世界进入集群的流量。GKE 使用多项集成式 Google Cloud 功能来管理和保护此流量。
外部访问数据流:当互联网中的客户端向您的应用(通常通过类型为 LoadBalancer 的 Service 或者 Ingress 或网关资源公开)发送请求时,该请求首先会到达 Google Cloud 负载均衡器。
负载均衡器会将请求路由到集群中的健康状况良好的节点。节点将流量转发到适当的 Pod。kube-proxy 在不使用 GKE Dataplane V2 的集群上处理此转发;而在使用 GKE Dataplane V2 的集群中,则由 eBPF 程序处理此转发。目标 Pod 可能位于同一节点上,也可能位于不同节点上。
防火墙规则:GKE 集群使用 VPC 防火墙规则来控制入站流量。虽然 GKE 会自动创建一些默认防火墙规则以用于基本集群操作(例如允许控制平面访问节点),但您可以定义自定义规则来满足特定的安全要求。这些 VPC 防火墙规则可与 Kubernetes 网络政策搭配使用,通过在节点和 Pod 级控制流量来提供纵深防御。
优化外部流量:当负载均衡器将流量发送到节点时,该节点可能需要将流量转发到其他节点上的 Pod,这需要额外的网络跃点。为避免这种情况,请在 Service 清单中将 externalTrafficPolicy 字段设置为 Local。当此政策处于有效状态时,负载均衡器会使用健康检查来确定哪些节点具有目标 Service 的健康状况良好的 Pod。负载均衡器仅向健康状况良好的 Pod 发送流量,从而避免了额外的网络跃点。权衡之下,如果后端 Pod 未均匀分配在集群的各个节点中,此政策可能会导致流量分配不均。
管理出站流量
出站流量是指离开集群的流量。为了使 GKE 集群正常运行并使您的应用能够访问外部服务,您必须管理多个连接路径。
基本连接要求:所有 GKE 集群都需要与 *.googleapis.com、*.gcr.io 和 *.pkg.dev 网域建立出站连接。与控制平面 IP 地址的出站连接也必须正常运行。使用 Cloud NAT 为 Pod 提供互联网访问权限:在 Pod 没有公共 IP 地址的专用集群中,使用 Cloud NAT 启用出站互联网访问权限。Cloud NAT 是一项托管式服务,可让 Pod 连接到互联网以执行下载更新或访问外部 API 等任务,而无需将 Pod 暴露给传入连接。
与 Google Cloud Service 的连接:如果您需要允许集群与其他 Google Cloud 服务(例如 Cloud Storage 或 Cloud SQL)安全通信,而无需在公共互联网中传输,请使用专用 Google 访问通道。对于与 Google API 互动的专用集群,这是一个重要的出站流量机制。
混合和多集群连接
如需将 GKE 集群连接到本地基础设施,请使用 Cloud VPN 来建立加密隧道,或使用 Cloud Interconnect 来建立专用高带宽连接。如需在多个 GKE 集群之间实现通信,请使用多集群服务,该服务有助于在不同集群、区域或项目之间进行服务发现和流量。
网络安全控制
为了保护您的集群和在其中运行的应用,GKE 为内部(东西)和外部(南北)流量提供了多层安全控制。
使用网络政策保护内部流量(东西)
默认情况下,GKE 集群中的所有 Pod 都可以自由相互通信。为了保护内部流量并强制实施最小权限原则,您可以使用 NetworkPolicy。NetworkPolicy 是一种 Kubernetes 资源,可通过控制 Pod 之间的网络流量来充当 Pod 的防火墙。借助 NetworkPolicy 资源,您可以定义规则,根据标签、IP 地址范围和端口号的组合来限制所选 Pod 群组的入站流量和出站流量。当您在命名空间中创建第一个 NetworkPolicy 时,系统会拒绝该政策未明确允许的所有流量。这些政策的强制执行直接内置于 GKE Dataplane V2 中,或由集群的 CNI 插件(例如 Calico)处理。
NetworkPolicy 清单示例
以下示例展示了 NetworkPolicy 清单。此政策适用于带有 app: backend 标签的 Pod,且仅允许来自 TCP 端口 6379 上带有 app: frontend 标签的 Pod 的入站流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 6379
保护对集群的外部访问安全
控制进出集群的流量对于保护应用免受外部威胁至关重要。
VPC 防火墙规则
GKE 集群位于 Google Cloud VPC 网络中,并受 VPC 防火墙规则的保护,这些规则可控制进出集群节点的流量。VPC 防火墙规则和网络政策协同工作,提供纵深防御。VPC 防火墙在节点(第 3 层或第 4 层)级运行,并控制流向虚拟机本身的流量。网络政策在 Pod(第 3 层或第 4 层)级运行,可更精细地控制集群内应用之间的流量。
kubectl exec 等功能。限制对负载均衡器的访问
使用 Kubernetes Service 或 Ingress 公开应用时,您可以在负载均衡器级应用额外的安全控制措施。对于外部负载均衡器,请考虑以下选项:
- 如果您使用
type: LoadBalancer字段公开 Service,则可以在 Service 清单中指定loadBalancerSourceRanges字段。此字段用于将对 Service 的访问仅限为您定义的 IP 地址范围。 对于应用负载均衡器 (Ingress),您可以在公开 HTTP(S) 应用时使用更高级安全服务:
- Google Cloud Armor:此服务是一项 Web 应用防火墙 (WAF),可帮助保护您的应用免遭 DDoS 攻击和其他基于 Web 的威胁。
- Identity-Aware Proxy (IAP):如需进行精细的访问权限控制,您可以在端点上启用 IAP。IAP 会验证用户的身份,并使用该身份来确定是否应允许用户访问应用。
后续步骤
- 了解如何创建 VPC 原生集群。
- 详细了解 GKE Dataplane V2。
- 实现网络政策,以保护 Pod 到 Pod 的通信。
- 探索使用 Service 公开应用的不同方式,并使用 Gateway API 配置 Ingress。