Kubernetes 網絡政策(NetworkPolicy)
網絡政策(網絡隔離政策)
網絡政策 | Kubernetes
指定Pod間的網絡隔離政策,預設是所有互通。
Pod 之間互通,是通過如下三個辨別符的組合來辯識的:
- 其他被允許的 Pods(例外:Pod 無法阻塞對自身的通路)
- 被允許的名稱空間
- IP 組塊(例外:與 Pod 運作所在的節點的通信總是被允許的, 無論 Pod 或節點的 IP 位址)
一、Pod隔離與非隔離
- 預設情況下,Pod網絡都是非隔離的(non-isolated),可以接受來自任何請求方的網絡請求。
- 如果一個 NetworkPolicy 的标簽選擇器選中了某個 Pod,則該 Pod 将變成隔離的(isolated),并将拒絕任何不被 NetworkPolicy 許可的網絡連接配接。
二、規約
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector: ## 選中指定Pod
matchLabels:
role: db
policyTypes: ## 定義上面Pod的入站出站規則
- Ingress
- Egress
ingress: ## 定義入站白名單
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress: ## 定義出站白名單
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
複制
- 基本資訊: 同其他的 Kubernetes 對象一樣,
需要NetworkPolicy
、apiVersion
、kind
字段metadata
- spec:
的spec字段包含了定義網絡政策的主要資訊:NetworkPolicy
- podSelector: 同名稱空間中,符合此标簽選擇器
的 Pod 都将應用這個.spec.podSelector
。上面的 Example中的 podSelector 選擇了NetworkPolicy
的 Pod。如果該字段為空,則将對名稱空間中所有的 Pod 應用這個role=db
NetworkPolicy
- policyTypes:
是一個數組類型的字段,該數組中可以包含.spec.policyTypes
、Ingress
中的一個,也可能兩個都包含。該字段辨別了此Egress
是否應用到 入方向的網絡流量、出方向的網絡流量、或者兩者都有。如果不指定NetworkPolicy
字段,該字段預設将始終包含policyTypes
,當Ingress
中包含出方向的規則時,NetworkPolicy
也将被添加到預設值。Egress
- ingress:ingress是一個數組,代表入方向的白名單規則。每一條規則都将允許與
和from
比對的入方向的網絡流量發生。例子中的ports
包含了一條規則,允許的入方向網絡流量必須符合如下條件:ingress
- Pod 的監聽端口為
6379
- 請求方可以是如下三種來源當中的任意一種:
- ipBlock 為
網段,但是不包括172.17.0.0/16
網段172.17.1.0/24
- namespaceSelector 标簽選擇器,比對标簽為
project=myproject
- podSelector 标簽選擇器,比對标簽為
role=frontend
- ipBlock 為
- Pod 的監聽端口為
- egress:
是一個數組,代表出方向的白名單規則。每一條規則都将允許與egress
和to
比對的出方向的網絡流量發生。例子中的ports
允許的出方向網絡流量必須符合如下條件:egress
- 目标端口為
5978
- 目标 ipBlock 為
網段10.0.0.0/24
- 目标端口為
- podSelector: 同名稱空間中,符合此标簽選擇器
是以,例子中的
NetworkPolicy
對網絡流量做了如下限制:
- 隔離了
名稱空間中帶有default
标簽的所有 Pod 的入方向網絡流量和出方向網絡流量role=db
- Ingress規則(入方向白名單規則):
- 當請求方是如下三種來源當中的任意一種時,允許通路
名稱空間中所有帶default
标簽的 Pod 的6379端口:role=db
- ipBlock 為
網段,但是不包括172.17.0.0/16
網段172.17.1.0/24
- namespaceSelector 标簽選擇器,比對标簽為
project=myproject
- podSelector 标簽選擇器,比對标簽為
role=frontend
- ipBlock 為
- 當請求方是如下三種來源當中的任意一種時,允許通路
- Egress規則(出方向白名單規則):
- 當如下條件滿足時,允許出方向的網絡流量:
- 目标端口為
5978
- 目标 ipBlock 為
網段10.0.0.0/24
- 目标端口為
- 當如下條件滿足時,允許出方向的網絡流量:
三、to和from選擇器的行為
NetworkPolicy 的
.spec.ingress.from
和
.spec.egress.to
字段中,可以指定 4 種類型的标簽選擇器:
- podSelector 選擇與
同名稱空間中的 Pod 作為入方向通路控制規則的源或者出方向通路控制規則的目标NetworkPolicy
- namespaceSelector 選擇某個名稱空間(其中所有的Pod)作為入方向通路控制規則的源或者出方向通路控制規則的目标
- namespaceSelector 和 podSelector 在一個
/to
條目中同時包含from
和namespaceSelector
将選中指定名稱空間中的指定 Pod。此時請特别留意 YAML 的寫法,如下所示:podSelector
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
複制
該例子中,podSelector 前面沒有
-
減号,namespaceSelector 和 podSelector 是同一個 from 元素的兩個字段,将選中帶
user=alice
标簽的名稱空間中所有帶
role=client
标簽的 Pod。但是,下面的這個 NetworkPolicy 含義是不一樣的:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
複制
後者,podSelector 前面帶
-
減号,說明 namespaceSelector 和 podSelector 是 from 數組中的兩個元素,他們将選中 NetworkPolicy 同名稱空間中帶
role=client
标簽的對象,以及帶
user=alice
标簽的名稱空間的所有 Pod。
前者是交集關系(且),後者是并集關系(或)
- ipBlock 可選擇 IP CIDR 範圍作為入方向通路控制規則的源或者出方向通路控制規則的目标。這裡應該指定的是叢集外部的 IP,因為叢集内部 Pod 的 IP 位址是臨時配置設定的,且不可預測。
叢集的入方向和出方向網絡機制通常需要重寫網絡封包的 source 或者 destination IP。kubernetes 并未定義應該在處理
NetworkPolicy
之前還是之後再修改 source / destination IP,是以,在不同的雲供應商、使用不同的網絡插件時,最終的行為都可能不一樣。這意味着:
- 對于入方向的網絡流量,某些情況下,你可以基于實際的源 IP 位址過濾流入的封包;在另外一些情況下,NetworkPolicy 所處理的 "source IP" 可能是 LoadBalancer 的 IP 位址,或者其他位址
- 對于出方向的網絡流量,基于 ipBlock 的政策可能有效,也可能無效
四、場景
參考官網文檔:
網絡政策 | Kubernetes