在容器时代,传统的"边界防护"思维已经不足以保障服务间通信的安全。尤其在 Kubernetes 中,Pod 天然可以互相访问,这种"全可达"的网络模型虽然方便,但也潜藏巨大风险。借助 Calico 的网络策略能力,我们可以在集群中构建真正的"零信任"网络访问控制体系。
一、零信任安全模型简介
"零信任(Zero Trust) "并不是让系统完全不信任一切,而是一种不默认信任、基于验证和最小权限的安全原则。核心思想包括:
- 默认拒绝:所有请求默认不被允许,只有显式声明的才放行;
- 最小授权:每个组件、服务、用户仅拥有完成任务所需的最少访问权限;
- 动态验证:访问控制不仅基于身份,还包括上下文、行为模式等。
在 Kubernetes 中,要落地零信任原则,最直接可执行的一步就是:限制服务间通信,只允许明确授权的流量通行,这正是 Calico 所擅长的。
二、Calico 与 Kubernetes NetworkPolicy 的增强能力
Kubernetes 原生支持 NetworkPolicy
资源,但其能力比较基础。而 Calico 作为强大的 CNI 插件,不仅支持 K8s 的原生策略,还提供了自己的策略模型:GlobalNetworkPolicy
和 NetworkSet
,能力更丰富:
能力维度 | Kubernetes NetworkPolicy | Calico NetworkPolicy |
---|---|---|
命名空间隔离 | 支持 | 支持,支持全局策略 |
Egress 控制 | 支持 | 支持,支持更细粒度控制 |
IP Block 匹配 | 支持 | 支持 CIDR、IPSet |
DNS 基于域名规则 | 不支持 | ✅ 支持 FQDN 动态域名 |
流量日志 / 审计 | 不支持 | ✅ 支持 |
策略优先级 | 不支持 | ✅ 支持定义优先级 |
Stateful + Deny | 不支持 | ✅ 支持拒绝动作 |
通过 Calico,我们可以实现精确到"服务-A 的 Pod 只能访问服务-B 的某个端口,且只允许 TLS 端口访问",这是构建零信任微服务网络的基础。
三、零信任落地步骤:从"开放"到"默认拒绝"
我们可以通过以下步骤逐步落地零信任访问控制:
✅ 第一步:设置默认拒绝策略
目的:确保所有未被显式授权的访问都会被拦截。
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # 匹配所有 pod
policyTypes:
- Ingress
- Egress
这是基础中的基础。如果你没设置任何策略,Pod 默认全可达;一旦启用这一策略,未被允许的通信将全部拒绝。
✅ 第二步:定义服务间白名单通信策略
例如:frontend
服务只允许访问 backend
的 8080 端口。
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
这可以防止其它服务(如 monitoring、log agent)"意外访问" backend。
✅ 第三步:使用 Calico 的 GlobalNetworkPolicy 做跨命名空间控制
有些场景下,某些服务需要跨多个 namespace 访问,例如统一认证服务、日志收集器等。K8s 自带的策略作用域局限于 namespace,而 Calico 支持跨命名空间的全局策略:
yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-auth-to-any
spec:
selector: "app == 'auth-service'"
egress:
- action: Allow
destination: {}
ingress:
- action: Deny
types:
- Egress
这条策略允许 auth-service
访问任意服务,但不允许其他服务访问它,从而形成单向通路。
✅ 第四步:按需放行对外访问(DNS、Webhook、数据库)
默认拒绝策略将会屏蔽包括 DNS 在内的所有流量,我们可以按需放行:
yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-dns
spec:
selector: all()
egress:
- action: Allow
protocol: UDP
destination:
ports:
- 53
selector: "k8s-app == 'kube-dns'"
types:
- Egress
或者使用 Calico 特有的 FQDN 策略,动态允许访问外部域名(例如访问公网 webhook):
yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-to-webhook
spec:
selector: all()
egress:
- action: Allow
protocol: TCP
destination:
nets:
- 0.0.0.0/0
ports:
- 443
fqdn:
- "api.my-webhook.com"
types:
- Egress
四、策略调试技巧:别让网络策略变"断网神器"
💡 常用调试方法:
- 使用 network-policy-viewer 生成图形化策略图;
- 借助
kubectl exec
+curl
测试跨服务访问; - 结合 Calico 的流量日志,开启策略审计;
- 使用 Calico
policy-order
设置明确优先级,避免策略冲突。
五、实战经验总结与建议
我在多个项目中实施 Calico 策略体系时,总结出几个关键要点:
- 策略应服务化、组件化管理,避免集中配置造成混乱;
- 将策略配置纳入 GitOps 管理流程,可审计、可回滚;
- 从 deny all 起步、逐步放行,避免策略遗漏;
- 不要相信默认规则,定期进行策略审计与测试;
- 对核心服务(如 DNS、认证)要配置专属策略,避免误拦截。
六、结语:网络安全,从"默认信任"到"最小授权"的转变
Kubernetes 的自由通信模型虽然带来了灵活性,但同时也埋下了安全隐患。在现代微服务架构下,我们必须抛弃"默认互信"的幻想,构建真正可控、可观测、可追踪的访问体系。
使用 Calico 的网络策略机制,结合 Kubernetes 的声明式资源管理能力,可以有效地实现:
- 最小权限原则(Least Privilege)
- 显式授权原则(Explicit Grant)
- 最小可见原则(Minimized Blast Radius)
零信任不是一条捷径,而是一条从"开箱即用"到"精细治理"的进化路径。如果你还没启用任何网络策略,现在就可以开始这场"安全重构"之旅。