学习笔记(第八期):集群治理与控制(上篇):网络策略——NetworkPolicy)
kubernetesK8s学习笔记第八期集群治理与控制上篇网络策略——NetworkPolicy本笔记为 Kubernetes 系列第八期聚焦集群网络安全的核心机制——NetworkPolicy。涵盖Kubernetes 网络基础单主机/跨主机、CNM vs CNI、网络策略规约详解、四种选择器、多个实战实验Pod 标签/Namespace/IP 段限定、默认策略配置。所有命令和 YAML 示例均已经过整理和注释。全文约3200 字包含12 个 YAML 示例、30 命令示例和10 张对比表格是 Kubernetes 网络安全的入门指南。— Compiled and Authored by Whisky — June 30th, 2026目录Kubernetes 网络基础网络策略概述网络策略规约详解网络策略实战实验默认策略总结与知识点一览表一、Kubernetes 网络基础在理解网络策略之前先回顾 Kubernetes 网络的基本原理。1.1 单主机网络通信无论是 Docker 还是 Containerd容器网络接口默认都是虚拟接口。Linux 内核通过 veth pair虚拟以太网对技术在宿主机和容器之间建立通信通道。核心原理数据包在宿主机内核中直接复制不经过外部物理网络设备因此转发效率极高。以 Docker 为例Docker 服务默认创建docker0Linux 网桥每个容器有一个虚拟接口eth0连接到网桥宿主机和容器之间通过 veth pair 通信Containerd 的网络模型与 Docker 类似使用nerdctl0网桥。1.2 跨主机网络通信跨主机容器通信有两大方案方案原理代表技术Overlay 网络建立主机间 VxLAN 隧道封装数据包Flannel(vxlan)、WeaveUnderlay 网络依赖三层 IP 转发不封装数据包Flannel(host-gw)、Calico性能对比Underlay 网络性能优于 Overlay 网络无需封装/解封装Overlay 网络支持更多二层网段避免物理交换机 MAC 表耗尽选型建议若追求性能且网络环境支持三层互通优先选择 CalicoBGP 模式若需要跨子网通信且对性能要求不高Overlay 方案更灵活。1.3 CNM vs CNI容器网络模型经历了两个重要标准特点CNMContainer Network ModelCNIContainer Network Interface提出方Docker 公司Google CoreOS最小单元容器Pod守护进程依赖 dockerd不依赖任何守护进程扩展性被 Docker 绑定插件可随意替换适用平台DockerKubernetes关键理解Kubernetes 采用 CNI 标准这也是为什么我们可以灵活选择 Calico、Flannel、Weave 等不同网络插件。1.4 Kubernetes 网络模型核心要求Kubernetes 对网络模型有四个基本要求源自 CNI 规范所有 Pod 可以不经过 NAT 直接通信所有节点可以不经过 NAT 直接与所有 Pod 通信Pod 看到的自身 IP 与其他 Pod 看到的一致每个 Pod 拥有独立的 IP 地址这些要求确保了网络行为的可预测性也为 NetworkPolicy 的实现奠定了基础。二、网络策略概述2.1 默认网络行为默认情况下Kubernetes 集群的网络连通性是全开放的集群外部主机可以访问集群内部应用通过 NodePort/LoadBalancer集群内部应用可以访问集群外部主机各个 Namespace 之间没有做任何隔离策略这意味着任何 Pod 可以与集群中的任何其他 Pod 通信。这在生产环境中存在安全隐患。2.2 什么是网络策略NetworkPolicy是 Kubernetes 用于控制 Pod 之间网络通信的 API 对象。它允许你在 IP 地址或端口层面定义哪些流量被允许、哪些被拒绝。NetworkPolicy 是一种以应用为中心的结构适用于一端或两端与 Pod 的连接前提条件必须使用支持 NetworkPolicy 的网络插件如 Calico通俗理解NetworkPolicy 就像 Pod 的“防火墙规则”——你告诉 Kubernetes“谁可以访问我、我可以访问谁”Kubernetes 在网络层执行这些规则。2.3 两种隔离类型隔离类型方向默认行为受 NetworkPolicy 影响后入口隔离Ingress流入 Pod允许所有入站连接仅允许策略中指定的连接出口隔离Egress流出 Pod允许所有出站连接仅允许策略中指定的连接2.4 关键原则策略是相加的NetworkPolicy 是相加的不会产生冲突。如果多个策略适用于同一个 Pod所有策略允许的连接的并集就是最终生效的规则。重要要允许从源 Pod 到目的 Pod 的连接源 Pod 的出口策略和目的 Pod 的入口策略都需要允许连接。任何一方不允许连接都会失败。三、网络策略规约详解3.1 完整 YAML 示例apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:test-network-policynamespace:defaultspec:podSelector:matchLabels:role:dbpolicyTypes:-Ingress-Egressingress:-from:-ipBlock:cidr:172.17.0.0/16except:-172.17.1.0/24-namespaceSelector:matchLabels:project:myproject-podSelector:matchLabels:role:frontendports:-protocol:TCPport:6379egress:-to:-ipBlock:cidr:10.0.0.0/24ports:-protocol:TCPport:59783.2 核心字段详解字段说明spec.podSelector策略适用的 Pod。{}表示命名空间中的所有 Podspec.policyTypesIngress、Egress 或两者兼具。默认有 Ingress 规则时自动包含 Ingressspec.ingress入站规则白名单。匹配from和ports的流量才被允许spec.egress出站规则白名单。匹配to和ports的流量才被允许3.3 四种选择器选择器作用示例podSelector选择同一 Namespace 中的特定 Podrole: frontendnamespaceSelector选择特定 Namespace 中的所有 Podproject: myprojectnamespaceSelector podSelector选择特定 Namespace 中的特定 Pod组合使用ipBlock选择特定 IP CIDR 范围通常用于集群外部 IP172.17.0.0/16组合示例ingress:-from:-namespaceSelector:matchLabels:user:alice-podSelector:matchLabels:role:client含义允许来自任何Namespace 中标有useralice的 Pod 的流量或来自本地Namespace 中标有roleclient的 Pod 的流量。四、网络策略实战实验4.1 实验环境准备环境说明namespace-webweb1、web2、test 三个 Podnamespace-whiskytest 一个 Pod默认 Namespace 是web# 创建命名空间rootmaster30:~# kubectl create ns webrootmaster30:~# kubectl create ns whiskyrootmaster30:~# kubens web# 创建 web1rootmaster30:~# kubectl run web1 --imagenginx --image-pull-policyIfNotPresentrootmaster30:~# kubectl exec -it web1 -- bash -c echo Hello web1 /usr/share/nginx/html/index.html# 创建 web2rootmaster30:~# kubectl run web2 --imagenginx --image-pull-policyIfNotPresentrootmaster30:~# kubectl exec -it web2 -- bash -c echo Hello web2 /usr/share/nginx/html/index.html# 创建 test同一 Namespacerootmaster30:~# kubectl run test --imagebusybox -- sleep 3600# 在 whisky Namespace 创建 test不同 Namespacerootmaster30:~# kubectl run test -n whisky --imagebusybox -- sleep 3600# 创建 ServiceNodePort 用于外部访问验证rootmaster30:~# kubectl expose pod web1 --port80 --target-port80 --typeNodePortrootmaster30:~# kubectl expose pod web2 --port80 --target-port80 --typeNodePort4.2 实验一根据 Pod 标签限定目标允许同一 Namespace 中具有标签run: test的 Pod 访问web1的 80 端口其他 Pod 禁止。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:my-network-policynamespace:webspec:podSelector:matchLabels:run:web1policyTypes:-Ingressingress:-from:-podSelector:matchLabels:run:testports:-protocol:TCPport:80# 应用策略rootmaster30:~# kubectl apply -f netpol.yaml# 验证test 可以访问 web1rootmaster30:~# kubectl exec test -- wget -q -O- web1Hello web1# 验证web2 无法访问 web1rootmaster30:~# kubectl exec web2 -- wget -q -O- web1wget: cant connect to remote host (10.103.36.143): Connection timed out # 修改 test 的标签使其不再匹配 rootmaster30:~# kubectl label pod test runweb2 --overwrite # 再次验证test 无法访问 web1 rootmaster30:~# kubectl exec test -- wget -q -O- web1 wget: cant connect to remotehost(10.103.36.143): Connection timed out关键理解NetworkPolicy 通过标签选择器动态匹配 Pod。当 Pod 标签变更时策略实时生效无需重启 Pod 或重新应用策略。4.3 实验二根据 Namespace 限定目标允许具有标签project: myproject的 Namespace 中的所有 Pod 访问web1。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:my-network-policynamespace:webspec:podSelector:matchLabels:run:web1policyTypes:-Ingressingress:-from:-namespaceSelector:matchLabels:project:myprojectports:-protocol:TCPport:80# 应用策略rootmaster30:~# kubectl apply -f netpol.yaml# 验证web 命名空间中的 Pod 无法访问rootmaster30:~# kubectl exec test -- wget -q -O- web1wget: cant connect...# 给 whisky 命名空间添加标签rootmaster30:~# kubectl label namespace whisky projectmyproject# 验证whisky 命名空间中的 Pod 可以访问rootmaster30:~# kubectl exec -n whisky test -- wget -q -O- web1.webHello web14.4 实验三根据 IP 段限定目标允许10.1.8.0/24网段但不包括10.1.8.128/26子网访问web1。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:my-network-policynamespace:webspec:podSelector:matchLabels:run:web1policyTypes:-Ingressingress:-from:-ipBlock:cidr:10.1.8.0/24except:-10.1.8.128/26ports:-protocol:TCPport:80# 应用策略rootmaster30:~# kubectl apply -f netpol.yaml# 验证节点 IP 在允许范围内可以访问rootclient:~# curl http://10.1.8.30:30790 # 取决于 nodePortHello web1⚠️ 注意ipBlock 策略对集群外部访问 NodePort 的实际效果取决于流量来源 IP。实验中通过节点 IP 访问时源 IP 会被 SNAT 转换因此建议在验证时使用 Pod IP 直连测试。4.5 实验四限定所有端口目标允许特定 Pod 访问web1的所有端口不限制端口范围。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:my-network-policynamespace:webspec:podSelector:matchLabels:run:web1policyTypes:-Ingressingress:-from:-podSelector:matchLabels:run:test# 不指定 ports → 允许所有端口# 应用策略rootmaster30:~# kubectl apply -f netpol.yaml# 验证可以 ping 通 Pod IPICMP 协议不经过端口rootmaster30:~# kubectl get pod web1 -o wideweb11/1 Running082m10.224.193.67 rootmaster30:~# kubectl run --rm -it ubuntu -l runtest --imageubuntu -- bashrootubuntu:/# apt update apt install -y iputils-pingrootubuntu:/# ping -c1 10.224.193.67PING10.224.193.67(10.224.193.67)56(84)bytes of data.64bytes from10.224.193.67:icmp_seq1ttl62time0.831ms4.6 实验五限定端口范围目标允许访问web1的32000-32768端口范围。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:my-network-policynamespace:webspec:podSelector:matchLabels:run:web1policyTypes:-Ingressingress:-from:-podSelector:matchLabels:run:testports:-protocol:TCPport:32000endPort:32768说明endPort支持指定端口范围适用于 NodePort 等需要开放端口的场景。此特性需要 Kubernetes 1.24 版本支持。五、默认策略5.1 默认允许所有入站流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-all-ingressspec:podSelector:{}policyTypes:-Ingressingress:-{}5.2 默认拒绝所有入站流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:default-deny-ingressspec:podSelector:{}policyTypes:-Ingress5.3 默认允许所有出站流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-all-egressspec:podSelector:{}policyTypes:-Egressegress:-{}5.4 默认拒绝所有出站流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:default-deny-egressspec:podSelector:{}policyTypes:-Egress5.5 默认拒绝所有入口和出口流量apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:default-deny-allspec:podSelector:{}policyTypes:-Ingress-Egress生产推荐在关键 Namespace 中部署default-deny-all策略然后按需添加允许策略白名单模式实现零信任网络隔离。六、总结与知识点一览表6.1 NetworkPolicy 核心字段速查字段作用示例podSelector策略作用的 Pod 范围matchLabels: {role: db}policyTypes策略类型[Ingress, Egress]ingress.from允许的入站来源podSelector/namespaceSelector/ipBlockingress.ports允许的入站端口{protocol: TCP, port: 80}egress.to允许的出站目标ipBlock: {cidr: 10.0.0.0/24}egress.ports允许的出站端口{protocol: TCP, port: 443}6.2 四种选择器对比选择器匹配范围适用场景podSelector同一 Namespace 的特定 Pod微服务间访问控制namespaceSelector特定 Namespace 的所有 Pod多租户隔离namespaceSelector podSelector特定 Namespace 的特定 Pod精确控制ipBlock特定 IP 段含 except集群外部来源控制6.3 默认策略模板一览场景模板允许所有入站ingress: [{}]拒绝所有入站不指定ingress允许所有出站egress: [{}]拒绝所有出站不指定egress完全隔离policyTypes: [Ingress, Egress]不指定规则6.4 常见错误排查错误现象可能原因解决方法策略不生效网络插件不支持 NetworkPolicy确认使用 Calico 等支持 NetworkPolicy 的插件Pod 无法访问入口/出口策略未同时允许检查源 Pod 出口策略和目的 Pod 入口策略ipBlock 不生效流量来源 IP 被 SNAT检查实际来源 IP使用 Pod IP 直连测试策略冲突误以为策略是拒绝的记住策略是相加的只能添加允许规则6.5 生产环境最佳实践启用网络策略前确保使用支持 NetworkPolicy 的网络插件如 Calico采用白名单模式先部署default-deny-all再按需开放命名空间级别隔离在不同 Namespace 中部署不同的默认策略监控策略影响使用网络策略可视化工具如 Calico Cloud 或 Cilium Hubble逐步推广先在测试环境验证策略再逐步应用到生产环境下一期预告kubernetesK8s学习笔记集群治理与控制下篇调度与节点管理——Scheduler 污点容忍 节点维护。涵盖kube-scheduler 调度过程、nodeName/nodeSelector/亲和性控制 Pod 位置、污点与容忍度、cordon/drain 节点维护操作。— Compiled and Authored by Whisky — June 30th, 2026