网络安全
概述
网络安全是Kubernetes集群安全的重要组成部分。通过网络策略(NetworkPolicy),可以控制Pod之间的网络流量,实现网络隔离和访问控制。网络策略允许你定义哪些Pod可以相互通信,从而实现细粒度的网络安全控制。
核心概念
1. NetworkPolicy(网络策略)
NetworkPolicy是Kubernetes中用于控制Pod之间网络流量的资源。它定义了Pod如何与其他网络端点通信的规则。
2. 网络插件要求
NetworkPolicy需要支持的网络插件(CNI)才能生效,如:
- Calico
- Cilium
- Weave Net
- Flannel(需要额外配置)
3. 入站规则(Ingress)
控制进入Pod的流量,指定允许哪些源Pod或命名空间访问目标Pod。
4. 出站规则(Egress)
控制从Pod发出的流量,指定目标Pod可以访问哪些外部端点。
5. 默认策略
如果没有定义NetworkPolicy,所有Pod之间默认可以互相通信。
NetworkPolicy工作原理
┌─────────────────────────────────────────────────────┐
│ Namespace A │
│ │
│ ┌──────────┐ NetworkPolicy ┌──────────┐│
│ │ Pod A │◄─────────────────────────►│ Pod B ││
│ │ │ 允许通信 │ ││
│ └──────────┘ └──────────┘│
│ │
└─────────────────────────────────────────────────────┘
│ ▲
│ 拒绝 │ 允许
▼ │
┌─────────────────────────────────────────────────────┐
│ Namespace B │
│ │
│ ┌──────────┐ ┌──────────┐│
│ │ Pod C │ │ Pod D ││
│ │ │ │ ││
│ └──────────┘ └──────────┘│
│ │
└─────────────────────────────────────────────────────┘YAML配置示例
示例1:拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: default
spec:
podSelector: {} # 选择所有Pod
policyTypes:
- Ingress
# 没有ingress规则,表示拒绝所有入站流量示例2:拒绝所有出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
# 没有egress规则,表示拒绝所有出站流量示例3:允许特定Pod访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080示例4:允许特定命名空间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-namespace
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: development
ports:
- protocol: TCP
port: 80示例5:允许特定IP段访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-ip
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.168.1.0/24
except:
- 192.168.1.100/32
ports:
- protocol: TCP
port: 80示例6:完整的网络策略配置
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: complete-policy
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
- namespaceSelector:
matchLabels:
env: production
- ipBlock:
cidr: 10.0.0.0/8
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8443
egress:
- to:
- podSelector:
matchLabels:
role: database
ports:
- protocol: TCP
port: 3306
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53示例7:多端口和多协议配置
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-port-policy
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
- protocol: TCP
port: 8080kubectl操作命令
查看网络策略
# 查看所有NetworkPolicy
kubectl get networkpolicies --all-namespaces
# 查看特定命名空间的NetworkPolicy
kubectl get networkpolicies -n default
# 简写形式
kubectl get netpol -n default
# 查看NetworkPolicy详细信息
kubectl describe networkpolicy deny-all-ingress -n default
# 以YAML格式查看NetworkPolicy
kubectl get networkpolicy deny-all-ingress -n default -o yaml
# 查看NetworkPolicy的选择器
kubectl get networkpolicy -n default -o jsonpath='{.items[*].spec.podSelector}'创建和删除网络策略
# 通过YAML文件创建NetworkPolicy
kubectl apply -f networkpolicy.yaml
# 删除NetworkPolicy
kubectl delete networkpolicy deny-all-ingress -n default
# 删除命名空间中的所有NetworkPolicy
kubectl delete networkpolicies --all -n default测试网络策略
# 创建测试Pod
kubectl run test-pod --image=busybox --rm -it --restart=Never -- sh
# 在测试Pod中测试连接
wget -qO- http://backend-service:8080
nc -zv backend-service 8080
curl http://backend-service:8080
# 测试DNS解析
nslookup backend-service
dig backend-service.default.svc.cluster.local
# 测试外部连接
curl http://example.com查看Pod的网络标签
# 查看Pod的标签
kubectl get pods --show-labels
# 根据标签选择Pod
kubectl get pods -l app=backend
# 查看命名空间的标签
kubectl get namespace --show-labels
# 为命名空间添加标签
kubectl label namespace development name=development调试网络策略
# 查看Pod的IP地址
kubectl get pods -o wide
# 查看Service的ClusterIP
kubectl get svc
# 查看网络插件状态
kubectl get pods -n kube-system | grep -E 'calico|cilium|weave|flannel'
# 查看网络策略影响的Pod
kubectl get pods -l app=backend -n default
# 进入Pod测试网络连接
kubectl exec -it <pod-name> -- sh真实场景实践示例
场景1:多层级应用网络隔离
需求:三层架构应用,前端只能访问后端,后端只能访问数据库,数据库不接受任何入站连接(除了后端)。
解决方案:
---
# 前端网络策略:允许外部访问,可以访问后端
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
egress:
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 8080
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 后端网络策略:只接受前端访问,可以访问数据库
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 3306
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 数据库网络策略:只接受后端访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 3306
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53验证:
# 应用配置
kubectl apply -f multi-tier-networkpolicy.yaml
# 创建测试Pod
kubectl run test-frontend --image=busybox --rm -it --restart=Never --labels="tier=frontend" -- sh
# 在Pod中测试:可以访问后端
wget -qO- http://backend:8080
kubectl run test-backend --image=busybox --rm -it --restart=Never --labels="tier=backend" -- sh
# 在Pod中测试:可以访问数据库
nc -zv database 3306场景2:命名空间隔离
需求:不同命名空间之间完全隔离,但允许访问公共服务(如监控、日志)。
解决方案:
---
# 为命名空间添加标签
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: production
env: prod
---
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: development
env: dev
---
# 生产环境:拒绝其他命名空间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-isolation
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
egress:
- to:
- namespaceSelector:
matchLabels:
name: production
- to:
- namespaceSelector:
matchLabels:
name: monitoring
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 开发环境:拒绝其他命名空间访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: development-isolation
namespace: development
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: development
egress:
- to:
- namespaceSelector:
matchLabels:
name: development
- to:
- namespaceSelector:
matchLabels:
name: monitoring
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53验证:
# 应用配置
kubectl apply -f namespace-isolation.yaml
# 测试命名空间隔离
kubectl run test-prod --image=busybox --rm -it --restart=Never -n production -- sh
# 在Pod中测试:无法访问开发环境
wget -qO- http://service.development.svc.cluster.local
# 应该失败
# 测试可以访问监控
kubectl run test-monitoring --image=busybox --rm -it --restart=Never -n monitoring -- sh场景3:限制外部访问
需求:只允许特定IP范围的外部流量访问Web服务。
解决方案:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-external-access
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 10.0.0.0/8 # 内部网络
- ipBlock:
cidr: 192.168.0.0/16 # VPN网络
- ipBlock:
cidr: 172.16.0.0/12 # 办公网络
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443验证:
# 应用配置
kubectl apply -f restrict-external-access.yaml
# 从允许的IP测试
curl http://web-service.default.svc.cluster.local
# 从不允许的IP测试(应该失败)
# 需要从外部网络测试场景4:允许访问外部服务
需求:应用需要访问外部API服务,但不能访问其他外部地址。
解决方案:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-api
namespace: default
spec:
podSelector:
matchLabels:
app: api-client
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- protocol: TCP
port: 443
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53验证:
# 应用配置
kubectl apply -f allow-external-api.yaml
# 创建测试Pod
kubectl run api-client --image=curlimages/curl --rm -it --restart=Never --labels="app=api-client" -- sh
# 测试访问外部API
curl https://api.example.com
# 应该成功
# 测试访问内部服务
curl http://internal-service.default.svc.cluster.local
# 应该失败场景5:数据库访问控制
需求:数据库只允许特定的应用Pod访问,且只能访问特定端口。
解决方案:
---
# MySQL数据库网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mysql-policy
namespace: default
spec:
podSelector:
matchLabels:
app: mysql
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
- podSelector:
matchLabels:
app: admin
ports:
- protocol: TCP
port: 3306
---
# PostgreSQL数据库网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: postgres-policy
namespace: default
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
---
# Redis网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: redis-policy
namespace: default
spec:
podSelector:
matchLabels:
app: redis
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 6379验证:
# 应用配置
kubectl apply -f database-networkpolicy.yaml
# 测试后端可以访问数据库
kubectl run backend --image=mysql:5.7 --rm -it --restart=Never --labels="app=backend" -- mysql -h mysql -u root -p
# 测试其他应用无法访问数据库
kubectl run unauthorized --image=mysql:5.7 --rm -it --restart=Never --labels="app=unauthorized" -- mysql -h mysql -u root -p
# 应该失败场景6:监控和日志服务访问
需求:允许Prometheus和Fluentd访问所有Pod收集指标和日志。
解决方案:
---
# 允许Prometheus访问所有Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
- protocol: TCP
port: 8080
---
# 允许Fluentd访问所有Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-fluentd
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: logging
podSelector:
matchLabels:
app: fluentd验证:
# 应用配置
kubectl apply -f monitoring-access.yaml
# 检查Prometheus是否可以访问目标
kubectl logs -n monitoring prometheus-pod | grep "target health"故障排查指南
问题1:网络策略不生效
症状:创建了NetworkPolicy但Pod之间仍然可以互相访问。
排查步骤:
# 1. 检查网络插件是否支持NetworkPolicy
kubectl get pods -n kube-system | grep -E 'calico|cilium|weave'
# 2. 检查NetworkPolicy是否正确创建
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>
# 3. 检查Pod的标签是否匹配
kubectl get pods --show-labels -n <namespace>
# 4. 检查命名空间的标签
kubectl get namespace --show-labels
# 5. 检查网络插件日志
kubectl logs -n kube-system <network-plugin-pod>
# 6. 查看网络策略的详细信息
kubectl get networkpolicy <policy-name> -n <namespace> -o yaml解决方案:
- 确保使用支持NetworkPolicy的网络插件
- 检查Pod标签是否正确匹配
- 检查命名空间标签是否正确配置
- 重启网络插件Pod
问题2:Pod无法访问DNS
症状:应用无法解析域名。
排查步骤:
# 1. 测试DNS解析
kubectl exec -it <pod-name> -- nslookup kubernetes
# 2. 检查DNS服务
kubectl get svc -n kube-system kube-dns
# 3. 检查DNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 4. 检查网络策略是否阻止了DNS
kubectl get networkpolicy -n <namespace> -o yaml | grep -A 10 "port: 53"
# 5. 测试直接访问DNS
kubectl exec -it <pod-name> -- nslookup kubernetes.default.svc.cluster.local 10.96.0.10解决方案:
# 确保网络策略允许DNS访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53问题3:无法访问外部服务
症状:Pod无法访问外部API或服务。
排查步骤:
# 1. 测试外部连接
kubectl exec -it <pod-name> -- curl -v https://api.example.com
# 2. 检查网络策略的egress规则
kubectl get networkpolicy -n <namespace> -o yaml | grep -A 20 "egress"
# 3. 检查是否有默认拒绝策略
kubectl get networkpolicy -n <namespace>
# 4. 测试IP连接
kubectl exec -it <pod-name> -- ping -c 3 8.8.8.8
# 5. 检查NAT配置
kubectl exec -it <pod-name> -- ip route解决方案:
# 允许访问外部服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16问题4:Service无法访问
症状:无法通过Service访问Pod。
排查步骤:
# 1. 检查Service是否存在
kubectl get svc -n <namespace>
# 2. 检查Service的Endpoints
kubectl get endpoints <service-name> -n <namespace>
# 3. 检查Pod是否健康
kubectl get pods -l app=<app-name> -n <namespace>
# 4. 测试直接访问Pod IP
kubectl exec -it <test-pod> -- curl http://<pod-ip>:<port>
# 5. 测试访问Service ClusterIP
kubectl exec -it <test-pod> -- curl http://<service-name>:<port>
# 6. 检查网络策略
kubectl describe networkpolicy -n <namespace>解决方案:
- 确保网络策略允许访问Service端口
- 检查Pod标签是否正确
- 确保Service selector正确匹配Pod
问题5:命名空间隔离失败
症状:不同命名空间的Pod仍然可以互相访问。
排查步骤:
# 1. 检查命名空间标签
kubectl get namespace --show-labels
# 2. 检查网络策略的namespaceSelector
kubectl get networkpolicy -n <namespace> -o yaml | grep -A 5 "namespaceSelector"
# 3. 测试跨命名空间访问
kubectl exec -it <pod-name> -n namespace-a -- curl http://service.namespace-b.svc.cluster.local
# 4. 检查网络插件配置
kubectl get configmap -n kube-system <network-plugin-config>解决方案:
# 确保命名空间有正确的标签
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: production
---
# 网络策略使用正确的namespaceSelector
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-namespace
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production问题6:网络策略冲突
症状:多个NetworkPolicy导致预期之外的行为。
排查步骤:
# 1. 列出所有NetworkPolicy
kubectl get networkpolicy -n <namespace>
# 2. 查看每个NetworkPolicy的详细配置
kubectl describe networkpolicy -n <namespace>
# 3. 检查Pod匹配的所有NetworkPolicy
kubectl get networkpolicy -n <namespace> -o json | \
jq -r '.items[] | select(.spec.podSelector.matchLabels.app=="<app-name>") | .metadata.name'
# 4. 测试网络连接
kubectl exec -it <pod-name> -- curl -v http://<target-service>解决方案:
- NetworkPolicy是累加的,多个策略会合并
- 删除冲突的策略
- 使用更精确的podSelector
最佳实践建议
1. 默认拒绝所有流量
# 第一步:创建默认拒绝策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 第二步:逐个添加允许规则
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend2. 始终允许DNS访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-access
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 533. 使用命名空间标签
# 为命名空间添加标签
kubectl label namespace production env=prod
kubectl label namespace development env=dev
# 在网络策略中使用
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-prod
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: prod4. 分层管理网络策略
# 基础策略:允许DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: baseline-allow-dns
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 应用策略:允许特定应用通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-policy
namespace: default
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
egress:
- to:
- podSelector:
matchLabels:
app: database5. 使用注释记录策略用途
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: default
annotations:
description: "允许前端访问后端API"
owner: "backend-team@example.com"
created-by: "admin"
last-updated: "2024-01-15"
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend6. 定期审计网络策略
# 列出所有NetworkPolicy
kubectl get networkpolicies --all-namespaces
# 检查没有NetworkPolicy的命名空间
kubectl get namespaces -o json | \
jq -r '.items[] | select(.metadata.name != "kube-system") | .metadata.name' | \
while read ns; do
count=$(kubectl get networkpolicy -n $ns -o json | jq '.items | length')
if [ "$count" -eq 0 ]; then
echo "Namespace $ns has no NetworkPolicy"
fi
done
# 检查过于宽松的策略
kubectl get networkpolicies --all-namespaces -o json | \
jq -r '.items[] | select(.spec.podSelector=={}) | "\(.metadata.namespace)/\(.metadata.name)"'7. 测试网络策略
# 创建测试脚本
cat > test-network-policy.sh << 'EOF'
#!/bin/bash
NAMESPACE=$1
SOURCE_POD=$2
TARGET_SERVICE=$3
PORT=$4
echo "Testing connection from $SOURCE_POD to $TARGET_SERVICE:$PORT"
kubectl exec -n $NAMESPACE $SOURCE_POD -- \
nc -zv $TARGET_SERVICE $PORT
if [ $? -eq 0 ]; then
echo "Connection successful"
else
echo "Connection failed (expected behavior if blocked by NetworkPolicy)"
fi
EOF
chmod +x test-network-policy.sh8. 使用版本控制
# 将网络策略纳入Git管理
git add networkpolicies/
git commit -m "Update network policies for production namespace"
# 使用GitOps工具管理网络策略
# 例如:ArgoCD, Flux9. 监控网络策略效果
# 使用Prometheus监控网络连接
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-rules
namespace: monitoring
data:
network.rules: |
groups:
- name: network
rules:
- alert: NetworkPolicyBlockingTraffic
expr: rate(connection_refused_total[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Network policy may be blocking traffic"
description: "High rate of connection refused errors detected"10. 文档化网络策略
# 在README中记录网络策略设计
# network-policy-design.md
# 网络策略设计文档
## 概述
本文档描述了生产环境的网络策略设计。
## 策略层级
1. 基础策略:默认拒绝所有流量
2. DNS策略:允许所有Pod访问DNS
3. 应用策略:根据应用需求添加特定规则
## 命名空间隔离
- production: 完全隔离
- development: 允许访问测试服务
- monitoring: 可以访问所有命名空间
## 应用通信矩阵
| 源应用 | 目标应用 | 端口 | 说明 |
|--------|----------|------|------|
| frontend | backend | 8080 | API调用 |
| backend | database | 3306 | 数据库访问 |
| backend | redis | 6379 | 缓存访问 |网络策略设计模式
模式1:零信任网络
# 默认拒绝所有流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: zero-trust
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# 只允许明确授权的流量模式2:分层安全
# 前端层
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-layer
spec:
podSelector:
matchLabels:
layer: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
egress:
- to:
- podSelector:
matchLabels:
layer: backend
---
# 后端层
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-layer
spec:
podSelector:
matchLabels:
layer: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
layer: frontend
egress:
- to:
- podSelector:
matchLabels:
layer: database模式3:服务网格集成
# 允许Istio sidecar通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-istio
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: istio-system
ports:
- protocol: TCP
port: 15090总结
网络安全策略是Kubernetes集群安全的关键组成部分,通过网络策略可以实现:
- 网络隔离:控制Pod之间的网络流量
- 访问控制:限制哪些Pod可以访问服务
- 多租户安全:实现命名空间级别的隔离
- 零信任架构:默认拒绝,按需允许
关键要点
- NetworkPolicy需要支持的网络插件
- 默认情况下所有Pod可以互相通信
- NetworkPolicy是累加的,多个策略会合并
- 始终允许DNS访问
- 使用标签选择器精确控制流量
- 定期审计和测试网络策略
下一步学习
- RBAC基础 - 深入了解权限管理
- ServiceAccount - 学习Pod身份认证
- Pod安全 - 掌握Pod安全策略
- SecurityContext - 配置容器安全上下文