關于NetworkPolicy工作原理解讀
NetworkPolicy 是 Kubernetes 中用于控制 Pod 間網(wǎng)絡流量的核心資源對象,它通過定義規(guī)則來允許或拒絕 Pod 之間、Pod 與外部服務之間的網(wǎng)絡通信。其本質是為 Kubernetes 集群提供網(wǎng)絡微分段(Micro-segmentation) 能力,確保只有授權的流量才能在 Pod 間流動,是實現(xiàn)集群網(wǎng)絡安全的關鍵組件。
一、NetworkPolicy 的核心定位與依賴前提
在理解工作原理前,需先明確其 “角色” 和 “運行條件”:
1. 核心定位
NetworkPolicy 本身不直接實現(xiàn)流量控制,而是一個 “規(guī)則定義層”—— 它僅聲明 “哪些流量允許 / 拒絕”,真正執(zhí)行流量過濾的是支持 NetworkPolicy 的網(wǎng)絡插件(CNI)。
2. 依賴前提:CNI 插件支持
并非所有 Kubernetes 網(wǎng)絡插件都支持 NetworkPolicy,只有實現(xiàn)了 Kubernetes NetworkPolicy API 的插件才能生效。
常見支持的插件包括:
- Calico(應用最廣泛,支持豐富的策略規(guī)則)
- Flannel(需配合
flannel-vxlan+policy或第三方組件才支持) - Cilium(基于 eBPF,性能優(yōu)異,支持 L3/L4/L7 層策略)
- Weave Net(原生支持 NetworkPolicy)
如果使用不支持的插件(如原生 Flannel),創(chuàng)建的 NetworkPolicy 會處于 “空轉” 狀態(tài),無法對流量產生任何影響。
二、NetworkPolicy 的核心概念與規(guī)則模型
NetworkPolicy 通過 “選擇目標 Pod” 和 “定義流量規(guī)則” 兩個核心步驟工作,先明確控制對象,再限定流量范圍。
1. 核心概念:目標 Pod 選擇(Pod Selector)
NetworkPolicy 首先需要通過 podSelector 字段指定要控制的 Pod—— 只有匹配該選擇器的 Pod,才會應用此策略的流量規(guī)則。
示例:通過 labels 匹配 Pod(標簽為 app: nginx 的所有 Pod)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nginx-policy
spec:
podSelector: # 選擇目標 Pod
matchLabels:
app: nginx
policyTypes: # 策略類型:Ingress(入站)、Egress(出站)
- Ingress
- Egress
# ... 后續(xù)規(guī)則省略特殊情況:若 podSelector 為空(podSelector: {}),則策略會應用于同一 Namespace 下的所有 Pod。
2. 核心概念:策略類型(Policy Types)
NetworkPolicy 支持兩種流量方向的控制,通過 policyTypes 聲明:
- Ingress:控制 “進入目標 Pod 的流量”(即其他 Pod / 外部服務向目標 Pod 發(fā)送的請求)。
- Egress:控制 “從目標 Pod 發(fā)出的流量”(即目標 Pod 向其他 Pod / 外部服務發(fā)送的請求)。
注意:若未顯式聲明 policyTypes,Kubernetes 會默認規(guī)則:
- 若策略中定義了
ingress規(guī)則,則自動添加Ingress類型; - 若策略中定義了
egress規(guī)則,則自動添加Egress類型。
3. 規(guī)則模型:“默認拒絕,顯式允許”
NetworkPolicy 遵循最小權限原則,默認規(guī)則是 “拒絕所有未授權流量”:
- 若某 Namespace 下存在針對 Pod 的 Ingress 策略,默認拒絕所有入站流量,僅允許策略中顯式聲明的入站流量;
- 若存在 Egress 策略,默認拒絕所有出站流量,僅允許策略中顯式聲明的出站流量;
- 若某 Pod 未被任何 NetworkPolicy 匹配,則該 Pod 的流量不受限制(允許所有入站和出站)。
三、Ingress 規(guī)則:控制入站流量
Ingress 規(guī)則定義 “哪些來源的流量可以進入目標 Pod”,核心是通過 from(流量來源)和 ports(目標端口)組合限制。
1. Ingress 規(guī)則結構
spec:
ingress:
- from: # 允許的流量來源(可多個)
- podSelector: # 來源1:集群內的其他 Pod(通過標簽匹配)
matchLabels:
app: client
- namespaceSelector: # 來源2:指定 Namespace 下的所有 Pod
matchLabels:
env: prod
- ipBlock: # 來源3:外部 IP 段(支持 CIDR 格式)
cidr: 192.168.0.0/16
except: # 排除該段中的部分 IP
- 192.168.1.0/24
ports: # 允許訪問的目標 Pod 端口(可多個)
- protocol: TCP # 協(xié)議:TCP/UDP/SCTP
port: 80 # 端口號(可寫具體數(shù)字或容器端口名,如 "http")2. 流量來源(from)的三種類型
from 字段用于定義 “允許哪些對象向目標 Pod 發(fā)送流量”,支持三種來源:
| 來源類型 | 作用 | 示例場景 |
|---|---|---|
| podSelector | 匹配同一 Namespace下的特定 Pod | 允許 “前端 Pod(app: frontend)” 訪問 “后端 Pod(app: backend)” |
| namespaceSelector | 匹配特定 Namespace下的所有 Pod | 允許 “測試環(huán)境 Namespace(env: test)” 的所有 Pod 訪問 “生產環(huán)境的數(shù)據(jù)庫 Pod” |
| ipBlock | 匹配外部 IP 段(集群外的流量) | 允許公司辦公網(wǎng)(10.0.0.0/8)訪問集群內的 Nginx Pod |
組合使用:podSelector 和 namespaceSelector 可組合(邏輯 “與”),例如:
yaml
from:
- podSelector: {matchLabels: {app: client}}
namespaceSelector: {matchLabels: {env: prod}}含義:僅允許 “prod 命名空間下,標簽為 app: client 的 Pod” 訪問目標 Pod。
3. 目標端口(ports)
ports 字段定義 “允許訪問目標 Pod 的哪些端口”,支持:
- 具體端口號:如
port: 80; - 容器端口名:如
port: http(需在 Pod 的containers.ports.name中定義該名稱); - 協(xié)議指定:默認 TCP,可顯式指定
protocol: UDP或SCTP。
四、Egress 規(guī)則:控制出站流量
Egress 規(guī)則定義 “目標 Pod 可以向哪些目的地發(fā)送流量”,核心是通過 to(流量目的地)和 ports(目標端口)組合限制。
1. Egress 規(guī)則結構
spec:
egress:
- to: # 允許的流量目的地(可多個)
- podSelector: # 目的地1:集群內的其他 Pod
matchLabels:
app: db
- namespaceSelector: # 目的地2:指定 Namespace 下的所有 Pod
matchLabels:
env: prod
- ipBlock: # 目的地3:外部 IP 段(如公網(wǎng)服務、數(shù)據(jù)庫)
cidr: 10.244.0.0/16
ports: # 允許訪問的目的地端口(可多個)
- protocol: TCP
port: 5432 # 例如:允許目標 Pod 訪問數(shù)據(jù)庫的 5432 端口(PostgreSQL)2. 流量目的地(to)的三種類型
to 字段與 Ingress 的 from 邏輯完全對稱,支持三種目的地:
podSelector:同一 Namespace 下的特定 Pod;namespaceSelector:特定 Namespace 下的所有 Pod;ipBlock:外部 IP 段(如集群外的數(shù)據(jù)庫、API 服務)。
3. 常見場景:限制 Pod 訪問外部服務
例如,限制 “應用 Pod” 僅能訪問 “公網(wǎng)的支付 API(IP: 203.0.113.0/24,端口 443)”,則 Egress 規(guī)則如下:
egress:
- to:
- ipBlock:
cidr: 203.0.113.0/24
ports:
- protocol: TCP
port: 443五、NetworkPolicy 的執(zhí)行邏輯與優(yōu)先級
當多個 NetworkPolicy 同時匹配一個 Pod 時,流量規(guī)則的執(zhí)行需遵循 “疊加允許、無拒絕疊加” 的原則。
1. 規(guī)則疊加邏輯
- 允許規(guī)則疊加:多個 Ingress/Egress 策略中,只要有一個策略允許某類流量,該流量就會被允許(邏輯 “或”);
- 拒絕規(guī)則不疊加:NetworkPolicy 僅支持 “顯式允許”,不支持 “顯式拒絕”(沒有
deny字段)。若需實現(xiàn) “拒絕特定流量”,需通過 “先允許所有,再排除特定” 的方式間接實現(xiàn)(例如:ipBlock.cidr: 0.0.0.0/0允許所有 IP,再通過except排除特定 IP 段)。
2. 優(yōu)先級規(guī)則
Kubernetes 本身不直接支持 NetworkPolicy 的優(yōu)先級聲明(如 priority 字段),但部分 CNI 插件(如 Calico)擴展了優(yōu)先級功能:
- 高優(yōu)先級策略的規(guī)則會先于低優(yōu)先級策略執(zhí)行;
- 若高優(yōu)先級策略拒絕某流量,低優(yōu)先級策略的允許規(guī)則無法覆蓋。
若使用原生 Kubernetes NetworkPolicy(無擴展),則所有匹配的策略規(guī)則平等疊加,允許規(guī)則 “取并集”。
六、NetworkPolicy 的底層執(zhí)行流程(以 Calico 為例)
不同 CNI 插件的執(zhí)行細節(jié)不同,但核心邏輯都是 “將 NetworkPolicy 規(guī)則轉化為節(jié)點上的網(wǎng)絡過濾規(guī)則”。以最常用的 Calico 為例,流程如下:
- 用戶創(chuàng)建 NetworkPolicy:通過
kubectl apply提交 NetworkPolicy YAML 到 Kubernetes API Server; - CNI 插件監(jiān)聽策略變化:Calico 的
calico-kube-controllers組件持續(xù)監(jiān)聽 API Server 中的 NetworkPolicy 資源,實時獲取策略更新; - 規(guī)則轉化:Calico 將 NetworkPolicy 規(guī)則轉化為 Linux iptables 規(guī)則(或 eBPF 程序,取決于 Calico 模式);
- 規(guī)則下發(fā)到節(jié)點:Calico 通過
calico-node守護進程(每個節(jié)點上運行),將轉化后的 iptables/eBPF 規(guī)則下發(fā)到目標 Pod 所在的節(jié)點; - 流量過濾執(zhí)行:當流量到達節(jié)點時,節(jié)點的內核通過 iptables/eBPF 規(guī)則檢查流量的 “源 / 目的 Pod、端口、協(xié)議”,符合規(guī)則則放行,否則拒絕。
關鍵細節(jié):為何基于節(jié)點執(zhí)行規(guī)則?
Kubernetes Pod 的網(wǎng)絡是 “Overlay 網(wǎng)絡”(如 Calico 的 BGP 模式、Flannel 的 VXLAN 模式),Pod 的 IP 是虛擬 IP,流量最終需通過節(jié)點的物理網(wǎng)卡轉發(fā)。因此,在節(jié)點上通過 iptables/eBPF 攔截流量,是最高效的執(zhí)行方式。
七、常見誤區(qū)與注意事項
- Namespace 隔離性:NetworkPolicy 是 ** Namespace 級別的資源 **,僅對同一 Namespace 下的 Pod 生效。若需跨 Namespace 控制,需通過
namespaceSelector匹配目標 Namespace。 - 不影響 HostNetwork Pod:使用
hostNetwork: true的 Pod(直接使用節(jié)點網(wǎng)絡)不受 NetworkPolicy 控制,因為其流量不經(jīng)過集群的 Overlay 網(wǎng)絡,無法被 CNI 插件攔截。 - 不控制 Kubernetes 系統(tǒng)組件流量:默認情況下,kube-proxy、etcd、kube-apiserver 等系統(tǒng)組件的流量不受 NetworkPolicy 限制(需手動配置策略控制)。
- L7 層策略支持有限:原生 NetworkPolicy 僅支持 L3(IP)和 L4(端口、協(xié)議)層的控制;若需 L7 層(HTTP 路徑、域名、請求頭)的策略(如 “僅允許訪問
/api/v1路徑”),需使用 Cilium(基于 eBPF)或 Istio(服務網(wǎng)格)等擴展方案。
八、總結
NetworkPolicy 的工作原理可歸納為三句話:
- 通過
podSelector鎖定目標 Pod,明確要控制的對象; - 通過 Ingress/Egress 規(guī)則定義 “允許的流量方向、來源 / 目的地、端口”,遵循 “默認拒絕,顯式允許”;
- 依賴 CNI 插件將規(guī)則轉化為節(jié)點的網(wǎng)絡過濾規(guī)則(如 iptables),在流量轉發(fā)時執(zhí)行過濾。
它是 Kubernetes 集群網(wǎng)絡安全的基石,通過精細化的流量控制,可有效防范 “橫向滲透攻擊”(如某 Pod 被入侵后,限制其訪問其他核心 Pod),是生產環(huán)境中不可或缺的配置。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Kubernetes?Ingress實現(xiàn)細粒度IP訪問控制
這篇文章主要為大家介紹了Kubernetes?Ingress實現(xiàn)細粒度IP訪問控制,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
Kubernetes存儲系統(tǒng)數(shù)據(jù)持久化管理詳解
這篇文章主要為大家介紹了Kubernetes存儲系統(tǒng)數(shù)據(jù)持久化管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
IoT邊緣集群Kubernetes?Events告警通知實現(xiàn)示例
這篇文章主要為大家介紹了IoT邊緣集群Kubernetes?Events告警通知實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02

