如何在Kubernetes中跨命名空间隔离DB Pod与Service(含DNS控制)
嘿,我来帮你搞定这个跨租户DB访问的问题!看起来你已经做了基础的命名空间隔离,但现有网络策略的粒度不够精准,导致Grafana依然能通过FQDN访问其他租户的Postgres。咱们一步步调整策略,实现严格的访问控制:
先分析现有策略的不足
你当前的deny-from-other-namespaces策略虽然尝试限制跨命名空间访问,但存在两个关键问题:
- 它的
podSelector是空的(匹配所有Pod),但没有针对Postgres Pod做精准的入口限制,等于允许同命名空间所有Pod访问所有服务,没有区分Grafana和其他Pod的权限。 - 你没有限制Grafana的出口流量——默认情况下K8s允许所有Pod向外发起请求,所以Grafana能随意访问其他命名空间的服务。
另外,web-allow-external策略只处理了Grafana的外部访问入口,没涉及到它的内部访问权限控制。
正确的网络策略配置方案
我们需要给Postgres配置入口白名单,只允许同命名空间的Grafana访问;同时给Grafana配置出口限制,只允许它访问同命名空间的Postgres(还要保留DNS解析能力,否则FQDN无法生效)。
前提:确保Pod有正确的标签
首先确认你的Pod都带有对应的标签(如果没有,先给Pod/Deployment加上):
- Postgres Pod标签:
app: postgres-app - Grafana Pod标签:
app: grafana-app
1. 给Postgres配置入口限制策略
针对每个租户的命名空间,创建只允许同命名空间Grafana访问的策略:
tenant1-namespace的Postgres策略:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: postgres-allow-same-namespace-grafana namespace: tenant1-namespace spec: podSelector: matchLabels: app: postgres-app # 匹配当前命名空间的Postgres Pod policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: grafana-app # 仅允许同命名空间的Grafana访问 ports: - protocol: TCP port: 5432 # 仅开放Postgres的5432端口
tenant2-namespace的Postgres策略:
把上面的namespace字段改成tenant2-namespace即可,其他内容一致。
2. 给Grafana配置出口限制策略
每个租户的Grafana需要限制出口流量,仅能访问同命名空间的Postgres和K8s DNS服务(否则无法解析服务名):
tenant1-namespace的Grafana策略:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: grafana-restrict-to-same-namespace-postgres namespace: tenant1-namespace spec: podSelector: matchLabels: app: grafana-app # 匹配当前命名空间的Grafana Pod policyTypes: - Ingress - Egress # 保留外部访问Grafana的能力(和你之前的web-allow-external策略一致) ingress: - from: [] # 限制出口流量 egress: # 允许访问同命名空间的Postgres - to: - podSelector: matchLabels: app: postgres-app ports: - protocol: TCP port: 5432 # 允许访问K8s DNS服务,保证FQDN解析正常 - to: - namespaceSelector: {} podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53
tenant2-namespace的Grafana策略:
同样修改namespace字段为tenant2-namespace即可。
验证配置是否生效
部署完策略后,你可以在tenant1的Grafana Pod里测试:
# 尝试访问其他租户的Postgres,应该连接失败 nc -zv postgres-app.tenant2-namespace.svc.cluster.local 5432 # 访问自身租户的Postgres,应该连接成功 nc -zv postgres-app.tenant1-namespace.svc.cluster.local 5432
额外提醒
确保你的K8s集群使用的网络插件(比如Calico、Cilium、Weave Net)支持NetworkPolicy资源——如果用的是默认的Docker bridge网络,网络策略不会生效哦!
内容的提问来源于stack exchange,提问作者Developer Desk




