大家好!在云原生环境中开发和运营应用程序时,我们经常会面临一个安全问题:“谁可以访问我们的服务?” Kubernetes 的基本理念是“允许所有 Pod 之间的通信(Any-to-Any)”,但在实际运营环境中,这是一个非常危险的想法。
今天,我们将彻底剖析 NetworkPolicy,它是 CKAD 考试的必考项,也是零信任(Zero Trust)安全的起点。

1. 什么是 NetworkPolicy?
Kubernetes NetworkPolicy 充当 L3/L4 防火墙,定义允许 Pod 组之间网络流量流动的规则。
核心特点
- 白名单(Whitelist)方式: 默认情况下,一旦 NetworkPolicy 生效,所有未明确指定的流量都将被阻止。
- 基于标签选择器(Label Selector): 通过 Pod 的标签而不是 IP 地址来指定目标。这是一种针对动态 Kubernetes 环境优化的方式。
- 网络插件依赖性: 重要!集群中必须安装支持 NetworkPolicy 的网络解决方案(例如 Calico、Cilium、Weave Net 等),实际的阻止功能才能生效。
2. NetworkPolicy 的主要组成部分
编写 NetworkPolicy YAML 时,必须理解以下四个核心区域:
- podSelector: 选择要应用策略的目标 Pod。
- policyTypes: 指明此策略是针对入站流量(Ingress)还是出站流量(Egress)。
- Ingress: 定义允许的入站流量的来源(from)和端口(ports)。
- Egress: 定义允许的出站流量的目的地(to)和端口(ports)。
3. 通过实战示例学习通信控制
场景 1:仅允许来自特定 Pod 的请求(Ingress)
当您希望拥有 app: database 标签的 Pod 仅接受来自拥有 app: backend 标签的 Pod 的 5432 端口连接时。
YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-allow-backend
namespace: default
spec:
podSelector:
matchLabels:
app: database # 应用策略的目标(DB Pod)
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend # 允许连接的来源(后端 Pod)
ports:
- protocol: TCP
port: 5432 # 允许的端口
场景 2:阻止所有流量(Default Deny)
最安全的策略是阻止所有通信,只开放必要的。
YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {} # 选择命名空间内的所有 Pod
policyTypes:
- Ingress
- Egress
# 如果 ingress/egress 子项留空,所有流量都将被阻止。
4. CKAD 考试中容易出错的要点(小贴士)
为了避免在考场上慌乱,您需要明确区分以下三个条件:
- podSelector vs namespaceSelector: * 如果只使用
podSelector,它会在同一命名空间内查找 Pod。 - 要允许来自其他命名空间的 Pod,必须同时使用
namespaceSelector。 - 数组(-)的存在与否:
- YAML
- podSelector: {…}
- podSelector: {…}
- namespaceSelector: {…} # 2:两个条件是“OR”关系(当前 NS 的特定 Pod 或特定 NS 的所有 Pod)
- DNS 检查 (Egress): 当控制 Pod 的出站流量时,如果不允许 DNS 查询(UDP 53),基于域名的通信将失败。在 Egress 策略中务必检查这一点!
`
from:
namespaceSelector: {…} # 1:两个条件是“AND”关系(特定 NS 内的特定 Pod)
from:
`
5. 总结
NetworkPolicy 不仅仅是阻止通信的工具,它是在微服务架构中建立服务间信任边界的非常重要的手段。如果您正在准备 CKAD 考试,建议您充分练习通过各种标签组合来分析 kubectl describe netpol 的结果。
希望今天整理的内容能帮助您的集群更加安全!
发表回复