跳转到内容

命名空间隔离

本文通过一个最小示例演示如何使用 NetworkPolicy 为命名空间建立默认拒绝策略,并只放通指定来源。


  • 集群网络插件支持 NetworkPolicy
  • 已连接集群并具备创建 Namespace、Pod、NetworkPolicy 的权限
  • 业务 Pod 使用稳定 label,例如 approletier

Terminal window
kubectl create namespace demo-a
kubectl create namespace demo-b
kubectl label namespace demo-a access-zone=trusted
kubectl label namespace demo-b access-zone=untrusted

apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: demo-a
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: api
namespace: demo-a
spec:
selector:
app: api
ports:
- port: 80
targetPort: 80
Terminal window
kubectl apply -f api.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: demo-a
spec:
podSelector: {}
policyTypes:
- Ingress
Terminal window
kubectl apply -f default-deny-ingress.yaml

这条策略选择 demo-a 下所有 Pod,并拒绝未显式允许的入站流量。


apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-trusted-namespace
namespace: demo-a
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
access-zone: trusted
ports:
- protocol: TCP
port: 80
Terminal window
kubectl apply -f allow-trusted-namespace.yaml

Terminal window
kubectl run curl-a -n demo-a --rm -it --image=curlimages/curl:8.8.0 --restart=Never -- \
curl -m 3 http://api.demo-a.svc.cluster.local
kubectl run curl-b -n demo-b --rm -it --image=curlimages/curl:8.8.0 --restart=Never -- \
curl -m 3 http://api.demo-a.svc.cluster.local

demo-a 带有 access-zone=trusted,应可以访问;demo-b 不满足 namespaceSelector,应被拒绝或超时。


现象可能原因检查方式
策略创建后仍可访问CNI 不支持 NetworkPolicy 或策略未匹配 Podkubectl describe networkpolicy、检查 Pod label
DNS 解析失败出站策略阻断 CoreDNS放通 kube-system/CoreDNS 的 UDP/TCP 53
预期来源被拒绝namespace label 或 pod label 不匹配kubectl get ns --show-labels

Terminal window
kubectl delete namespace demo-a demo-b