背景
我有一个包含两个 GKE 集群的 GCP 项目:public-cluster
和private-cluster
。public-cluster
运行一个 API 网关,该网关执行集中身份验证、日志记录、速率限制等,并将请求重新路由到在上运行的后端微服务private-cluster
。API 网关是使用构建的山猫。
public-cluster
面向互联网并使用 ingress-nginx 公开公共外部 IP 地址,该地址接受端口 80/443 上的 HTTP/s 流量。
的目的private-cluster
是它只能接受来自 的端口 80/443 流量public-cluster
。我们不希望从其他任何地方访问此集群,即没有private-cluster
来自 VPC 内部或外部的直接 HTTP/s 请求,除非流量来自。我已使用public-cluster
公开了在 上运行的服务private-cluster
内部负载均衡器,因此每个服务都有自己的内部 IP。API 网关使用这些内部 IP 将入站请求重新路由到后端微服务。
public-cluster
并且private-cluster
位于同一 VPC 内同一区域内的不同子网中。
预期的架构如下所示:
。
问题
我正在尝试创建防火墙规则,该规则将阻止所有到的流量,private-cluster
除非它来自public-cluster
,如下所示:
- 一个低优先级的入口规则,拒绝所有流量
private-cluster
(使用网络标签作为目标)和0.0.0.0/0
源 IP 范围 - 更高优先级的入口规则,其中:
- 目标 =
private-cluster
- 源过滤器 =
public-cluster
- 允许端口 80 和 443 上的 TCP 流量
- 目标 =
如果我通过 SSH 连接到 中的节点public-cluster
并向 上的服务发送 curl 请求private-cluster
(使用该服务的内部负载均衡器 IP),则上述防火墙规则会正确允许流量。但是,如果我从本地计算机向public-cluster
API 网关发送请求,防火墙规则会阻止流量。在这种情况下,防火墙规则中的网络标记似乎被忽略了。
我尝试了一些方法来使规则发挥作用(但均未成功),例如:
- 使用 public-cluster 所在的子网 IP 范围作为源过滤器 IP 范围
- 使用子网的网关 IP 作为源过滤器 IP
- 使用
public-cluster
nginx 的外部 IP 作为源 IP
问题
所以,我的问题是:
- 定义此防火墙规则的正确方法是什么,以便从正在运行的 API 网关重新路由的请求
public-cluster
可以通过防火墙private-cluster
? - 更一般地讲,这是 Kubernetes 集群的典型架构模式吗(即,有一个面向公众的集群运行 API 网关,将请求重新路由到后端非面向公众的集群),如果不是,有没有更好的方法来构建它?(我知道这是一个非常主观的问题,但我有兴趣听听其他方法)
答案1
我通过添加一条防火墙规则来实现这一点,该规则允许从 的public-cluster
pod 地址范围到private-cluster
的网络标签的端口 80/443。
- 获取 的
public-clusters
pod 地址范围:
gcloud container clusters describe public-cluster --zone europe-west2-a | grep clusterIpv4Cidr
- 创建防火墙规则(替换
--source-ranges=XX.XX.X.X/XX
为 pod 地址范围):
gcloud compute firewall-rules create allow-public-cluster-to-private-cluster \
--direction=INGRESS \
--priority=1000 \
--network=custom-vpc \
--action=ALLOW \
--rules=tcp:80,tcp:443 \
--source-ranges=XX.XX.X.X/XX \
--target-tags=private-cluster
答案2
最好的方法是将标签应用于公共集群的节点,然后在私有集群上打开一个仅允许给定标签的端口。所有 gcp 防火墙都可以基于标签、非仅基于 ip 或基于类。
答案3
对于 vpc 原生集群,私有集群节点将能够与该 vpc 上的每个其他实例通信,但不能与 vpc 之外的任何目的地通信。如果您甚至想锁定该 vpc 内部,您可以相应地标记节点并将防火墙规则应用于带有这些标记的虚拟机。