内容提要
本文介绍如何在Kubernetes中通过NetworkPolicies实现零信任网络模型。实验使用Calico CNI,在命名空间内设置默认拒绝规则,再基于标签允许特定流量:前端访问后端80端口,后端访问数据库5432端口,并配置出站策略及DNS例外。验证表明,标签是身份标识,通信需源端出站和目标端入站规则同时匹配,且需注意端口限制和CoreDNS访问。
延伸解读
默认拒绝与标签白名单的配合
文章强调,零信任网络模型的核心是先通过空的podSelector实现命名空间级默认拒绝,再基于标签精确放行。这种“先关后开”的策略避免了遗漏风险。但要注意,标签是唯一身份标识,若攻击者能修改标签(如通过RBAC漏洞),就可能绕过策略。因此,必须严格控制标签的修改权限,防止身份伪造。
出入站规则需成对匹配
实验验证了在完全锁定的集群中,通信成功需要源端的出站规则和目标端的入站规则同时允许。仅配置一方会导致连接失败。这提醒运维人员,在排查网络问题时,需同时检查两端策略,避免只关注单一方向而忽略另一侧的隐式拒绝。
端口限制与DNS例外
NetworkPolicy不仅控制连接对象,还严格限制端口。即使标签匹配,若端口不符(如用80访问数据库的5432)也会被拒绝。此外,出站策略若未放行UDP/TCP 53到kube-system,会导致CoreDNS解析失败,服务发现静默中断。配置出站规则时,务必包含DNS例外,否则应用可能因无法解析域名而出现难以排查的故障。
Q&A
如何在Kubernetes中实现零信任网络模型?
在Kubernetes中实现零信任网络模型需要从默认允许所有流量转变为基于标签的显式微隔离。具体做法是使用NetworkPolicy,首先在命名空间级别应用默认拒绝规则,然后根据工作负载的标签(如tier: frontend)创建精细的入站和出站策略,只允许必要的通信。
Kubernetes NetworkPolicy中的默认拒绝规则如何配置?
默认拒绝规则通过创建一个podSelector为空的NetworkPolicy来实现,例如: ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} policyTypes: - Ingress ``` 这会匹配命名空间中的所有Pod,拒绝所有入站流量,除非有其他策略显式允许。
在Kubernetes中,如何允许前端Pod访问后端Pod的80端口?
需要同时配置后端Pod的入站策略和前端Pod的出站策略。后端入站策略允许来自标签为tier=frontend的Pod访问TCP 80端口;前端出站策略允许访问标签为tier=backend的Pod的80端口。例如: 后端入站: ```yaml spec: podSelector: matchLabels: tier: backend ingress: - from: - podSelector: matchLabels: tier: frontend ports: - protocol: TCP port: 80 ``` 前端出站类似,但方向相反。
为什么在配置Kubernetes网络策略时,出站规则中需要允许DNS(端口53)?
因为如果限制了出站流量,默认会阻止Pod访问集群内的CoreDNS服务,导致服务发现失败。因此,在出站策略中必须显式允许UDP/TCP流量到kube-system命名空间的53端口,以确保Pod能够解析服务名称。
Kubernetes网络策略中,标签在身份识别中扮演什么角色?
标签是NetworkPolicy中用于识别Pod和命名空间的主要机制。策略通过匹配标签来决定允许或拒绝流量。因此,标签相当于Pod的身份标识,必须确保RBAC控制谁能修改标签,因为更改标签可能绕过防火墙规则。
在Kubernetes中,为什么即使前端Pod被允许访问后端,但访问数据库仍然失败?
因为网络策略不仅控制谁可以连接,还控制端口。前端Pod的出站策略只允许访问后端的80端口,而数据库的入站策略只允许来自后端Pod的5432端口。因此,前端直接访问数据库会被拒绝,因为既不符合出站策略的端口限制,也不符合数据库的入站来源限制。
在Kubernetes中,如何验证网络策略是否生效?
可以通过创建测试Pod并尝试发起连接来验证。例如,使用无标签的测试Pod尝试访问后端,应该被默认拒绝;使用带正确标签的Pod访问允许的端口,应该成功。还可以使用bash的/dev/tcp工具测试TCP连接。