| name | implementing-kubernetes-network-policy-with-calico |
| description | 使用 Calico NetworkPolicy 和 GlobalNetworkPolicy 实施 Kubernetes 网络分段,实现 Pod 间零信任通信。 |
| domain | cybersecurity |
| subdomain | container-security |
| tags | ["calico","kubernetes","network-policy","network-segmentation","zero-trust","cni"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
使用 Calico 实施 Kubernetes 网络策略
概述
Calico 是一个开源 CNI 插件,为 Kubernetes 集群提供细粒度网络策略执行能力。它实现了完整的 Kubernetes NetworkPolicy API,并通过 Calico 专属的 GlobalNetworkPolicy 进行了扩展,支持策略排序、拒绝规则和基于服务账户的选择器。
前提条件
- Kubernetes 集群(v1.24+)
- 已安装 Calico CNI(v3.26+)
kubectl 和 calicoctl CLI 工具
- 集群管理员 RBAC 权限
安装 Calico
基于 Operator 的安装(推荐)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
kubectl get pods -n calico-system
watch kubectl get pods -n calico-system
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calicoctl.yaml
验证 Calico 运行状态
kubectl get pods -n calico-system
kubectl exec -n calico-system calicoctl -- calicoctl node status
kubectl exec -n calico-system calicoctl -- calicoctl get ippool -o wide
Kubernetes NetworkPolicy
默认拒绝所有流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
允许特定 Pod 间通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
允许 DNS 出口流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
命名空间隔离
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
Calico 专属策略
GlobalNetworkPolicy(集群级别)
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-external-ingress
spec:
order: 100
selector: "projectcalico.org/namespace != 'ingress-nginx'"
types:
- Ingress
ingress:
- action: Deny
source:
nets:
- 0.0.0.0/0
destination: {}
带拒绝规则的 Calico NetworkPolicy
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: deny-database-from-frontend
namespace: production
spec:
order: 10
selector: app == 'database'
types:
- Ingress
ingress:
- action: Deny
source:
selector: app == 'frontend'
- action: Allow
source:
selector: app == 'backend'
destination:
ports:
- 5432
基于服务账户的策略
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-by-service-account
namespace: production
spec:
selector: app == 'api'
ingress:
- action: Allow
source:
serviceAccounts:
names:
- frontend-sa
- monitoring-sa
egress:
- action: Allow
destination:
serviceAccounts:
names:
- database-sa
主机端点保护
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: restrict-host-ssh
spec:
order: 10
selector: "has(kubernetes.io/hostname)"
applyOnForward: false
types:
- Ingress
ingress:
- action: Allow
protocol: TCP
source:
nets:
- 10.0.0.0/8
destination:
ports:
- 22
- action: Deny
protocol: TCP
destination:
ports:
- 22
Calico 策略层级
apiVersion: projectcalico.org/v3
kind: Tier
metadata:
name: security
spec:
order: 100
---
apiVersion: projectcalico.org/v3
kind: Tier
metadata:
name: platform
spec:
order: 200
监控与故障排查
kubectl get networkpolicy --all-namespaces
kubectl exec -n calico-system calicoctl -- calicoctl get networkpolicy --all-namespaces -o wide
kubectl exec -n calico-system calicoctl -- calicoctl get globalnetworkpolicy -o wide
kubectl exec -n calico-system calicoctl -- calicoctl get workloadendpoint -n production -o yaml
kubectl logs -n calico-system -l k8s-app=calico-node --tail=100
kubectl exec -n production frontend-pod -- wget -qO- --timeout=2 http://backend-svc:8080/health
最佳实践
- 从默认拒绝开始 - 对每个命名空间应用拒绝所有策略,再允许特定流量
- 统一使用标签 - 为 app、tier、environment 定义标签规范
- 排序策略 - 使用 Calico 策略排序(
order 字段)控制评估优先级
- 先允许 DNS - 在应用出口拒绝策略前,始终先创建 DNS 出口规则
- 使用 GlobalNetworkPolicy 建立集群级安全基线
- 在预发布环境测试策略 - 应用策略后验证网络连通性
- 监控被拒绝的流量 - 启用 Calico 流量日志以了解被阻断的连接
- 使用层级 - 将策略组织为安全、平台和应用层级