新聞中心
網(wǎng)絡(luò)策略
如果你希望在 IP 地址或端口層面(OSI 第 3 層或第 4 層)控制網(wǎng)絡(luò)流量, 則你可以考慮為集群中特定應(yīng)用使用 Kubernetes 網(wǎng)絡(luò)策略(NetworkPolicy)。 NetworkPolicy 是一種以應(yīng)用為中心的結(jié)構(gòu),允許你設(shè)置如何允許 Pod 與網(wǎng)絡(luò)上的各類網(wǎng)絡(luò)“實(shí)體” (我們這里使用實(shí)體以避免過度使用諸如“端點(diǎn)”和“服務(wù)”這類常用術(shù)語, 這些術(shù)語在 Kubernetes 中有特定含義)通信。

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的固安網(wǎng)站設(shè)計(jì)、移動媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
Pod 可以通信的 Pod 是通過如下三個標(biāo)識符的組合來辯識的:
- 其他被允許的 Pods(例外:Pod 無法阻塞對自身的訪問)
- 被允許的名字空間
- IP 組塊(例外:與 Pod 運(yùn)行所在的節(jié)點(diǎn)的通信總是被允許的, 無論 Pod 或節(jié)點(diǎn)的 IP 地址)
在定義基于 Pod 或名字空間的 NetworkPolicy 時,你會使用 選擇算符 來設(shè)定哪些流量 可以進(jìn)入或離開與該算符匹配的 Pod。
同時,當(dāng)基于 IP 的 NetworkPolicy 被創(chuàng)建時,我們基于 IP 組塊(CIDR 范圍) 來定義策略。
前置條件
網(wǎng)絡(luò)策略通過網(wǎng)絡(luò)插件 來實(shí)現(xiàn)。要使用網(wǎng)絡(luò)策略,你必須使用支持 NetworkPolicy 的網(wǎng)絡(luò)解決方案。 創(chuàng)建一個 NetworkPolicy 資源對象而沒有控制器來使它生效的話,是沒有任何作用的。
Pod 隔離的兩種類型
Pod 有兩種隔離: 出口的隔離和入口的隔離。它們涉及到可以建立哪些連接。 這里的“隔離”不是絕對的,而是意味著“有一些限制”。 另外的,“非隔離方向”意味著在所述方向上沒有限制。這兩種隔離(或不隔離)是獨(dú)立聲明的, 并且都與從一個 Pod 到另一個 Pod 的連接有關(guān)。
默認(rèn)情況下,一個 Pod 的出口是非隔離的,即所有外向連接都是被允許的。如果有任何的 NetworkPolicy 選擇該 Pod 并在其 ?policyTypes ?中包含 “Egress”,則該 Pod 是出口隔離的, 我們稱這樣的策略適用于該 Pod 的出口。當(dāng)一個 Pod 的出口被隔離時, 唯一允許的來自 Pod 的連接是適用于出口的 Pod 的某個 NetworkPolicy 的 ?egress ?列表所允許的連接。 這些 ?egress ?列表的效果是相加的。
默認(rèn)情況下,一個 Pod 對入口是非隔離的,即所有入站連接都是被允許的。如果有任何的 NetworkPolicy 選擇該 Pod 并在其 ?policyTypes ?中包含 “Ingress”,則該 Pod 被隔離入口, 我們稱這種策略適用于該 Pod 的入口。 當(dāng)一個 Pod 的入口被隔離時,唯一允許進(jìn)入該 Pod 的連接是來自該 Pod 節(jié)點(diǎn)的連接和適用于入口的 Pod 的某個 NetworkPolicy 的 ?ingress ?列表所允許的連接。這些 ?ingress ?列表的效果是相加的。
網(wǎng)絡(luò)策略是相加的,所以不會產(chǎn)生沖突。如果策略適用于 Pod 某一特定方向的流量, Pod 在對應(yīng)方向所允許的連接是適用的網(wǎng)絡(luò)策略所允許的集合。 因此,評估的順序不影響策略的結(jié)果。
要允許從源 Pod 到目的 Pod 的連接,源 Pod 的出口策略和目的 Pod 的入口策略都需要允許連接。 如果任何一方不允許連接,建立連接將會失敗。
NetworkPolicy 資源
下面是一個 NetworkPolicy 的示例:
apiVersion: networking.K8S.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- 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
除非選擇支持網(wǎng)絡(luò)策略的網(wǎng)絡(luò)解決方案,否則將上述示例發(fā)送到API服務(wù)器沒有任何效果。
必需字段:與所有其他的 Kubernetes 配置一樣,NetworkPolicy 需要 ?apiVersion?、 ?kind ?和 ?metadata ?字段。
spec:NetworkPolicy 規(guī)約 中包含了在一個名字空間中定義特定網(wǎng)絡(luò)策略所需的所有信息。
podSelector:每個 NetworkPolicy 都包括一個 ?podSelector?,它對該策略所 適用的一組 Pod 進(jìn)行選擇。示例中的策略選擇帶有 "role=db" 標(biāo)簽的 Pod。 空的 ?podSelector ?選擇名字空間下的所有 Pod。
policyTypes: 每個 NetworkPolicy 都包含一個 ?policyTypes ?列表,其中包含 ?Ingress ?或 ?Egress ?或兩者兼具。?policyTypes ?字段表示給定的策略是應(yīng)用于 進(jìn)入所選 Pod 的入站流量還是來自所選 Pod 的出站流量,或兩者兼有。 如果 NetworkPolicy 未指定 ?policyTypes ?則默認(rèn)情況下始終設(shè)置 ?Ingress?; 如果 NetworkPolicy 有任何出口規(guī)則的話則設(shè)置 ?Egress?。
ingress: 每個 NetworkPolicy 可包含一個 ?ingress ?規(guī)則的白名單列表。 每個規(guī)則都允許同時匹配 ?from ?和 ?ports ?部分的流量。示例策略中包含一條 簡單的規(guī)則: 它匹配某個特定端口,來自三個來源中的一個,第一個通過 ?ipBlock ?指定,第二個通過 ?namespaceSelector ?指定,第三個通過 ?podSelector ?指定。
egress: 每個 NetworkPolicy 可包含一個 ?egress ?規(guī)則的白名單列表。 每個規(guī)則都允許匹配 ?to ?和 ?port ?部分的流量。該示例策略包含一條規(guī)則, 該規(guī)則將指定端口上的流量匹配到 ?10.0.0.0/24? 中的任何目的地。
所以,該網(wǎng)絡(luò)策略示例:
- 隔離 "default" 名字空間下 "role=db" 的 Pod (如果它們不是已經(jīng)被隔離的話)。
- (Ingress 規(guī)則)允許以下 Pod 連接到 "default" 名字空間下的帶有 "role=db" 標(biāo)簽的所有 Pod 的 6379 TCP 端口:
- "default" 名字空間下帶有 "role=frontend" 標(biāo)簽的所有 Pod
- 帶有 "project=myproject" 標(biāo)簽的所有名字空間中的 Pod
- IP 地址范圍為 172.17.0.0–172.17.0.255 和 172.17.2.0–172.17.255.255 (即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16)
- (Egress 規(guī)則)允許從帶有 "role=db" 標(biāo)簽的名字空間下的任何 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口的連接。
選擇器 to 和 from 的行為
可以在 ?ingress ?的 ?from ?部分或 ?egress ?的 ?to ?部分中指定四種選擇器:
podSelector: 此選擇器將在與 NetworkPolicy 相同的名字空間中選擇特定的 Pod,應(yīng)將其允許作為入站流量來源或出站流量目的地。
namespaceSelector:此選擇器將選擇特定的名字空間,應(yīng)將所有 Pod 用作其 入站流量來源或出站流量目的地。
namespaceSelector 和 podSelector: 一個指定 ?namespaceSelector ?和 ?podSelector ?的 ?to?/?from ?條目選擇特定名字空間中的特定 Pod。 注意使用正確的 YAML 語法;下面的策略:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...在 ?from ?數(shù)組中僅包含一個元素,只允許來自標(biāo)有 ?role=client? 的 Pod 且 該 Pod 所在的名字空間中標(biāo)有 ?user=alice? 的連接。但是 這項(xiàng) 策略:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...在 ?from ?數(shù)組中包含兩個元素,允許來自本地名字空間中標(biāo)有 ?role=client? 的 Pod 的連接,或 來自任何名字空間中標(biāo)有 ?user=alice? 的任何 Pod 的連接。
如有疑問,請使用 ?kubectl describe? 查看 Kubernetes 如何解釋該策略。
ipBlock: 此選擇器將選擇特定的 IP CIDR 范圍以用作入站流量來源或出站流量目的地。 這些應(yīng)該是集群外部 IP,因?yàn)?nbsp;Pod IP 存在時間短暫的且隨機(jī)產(chǎn)生。
集群的入站和出站機(jī)制通常需要重寫數(shù)據(jù)包的源 IP 或目標(biāo) IP。 在發(fā)生這種情況時,不確定在 NetworkPolicy 處理之前還是之后發(fā)生, 并且對于網(wǎng)絡(luò)插件、云提供商、?Service ?實(shí)現(xiàn)等的不同組合,其行為可能會有所不同。
對入站流量而言,這意味著在某些情況下,你可以根據(jù)實(shí)際的原始源 ?IP ?過濾傳入的數(shù)據(jù)包, 而在其他情況下,NetworkPolicy 所作用的 源IP 則可能是 ?LoadBalancer ?或 Pod 的節(jié)點(diǎn)等。
對于出站流量而言,這意味著從 Pod 到被重寫為集群外部 IP 的 ?Service ?IP 的連接可能會或可能不會受到基于 ?ipBlock ?的策略的約束
默認(rèn)策略
默認(rèn)情況下,如果名字空間中不存在任何策略,則所有進(jìn)出該名字空間中 Pod 的流量都被允許。 以下示例使你可以更改該名字空間中的默認(rèn)行為。
默認(rèn)拒絕所有入站流量
你可以通過創(chuàng)建選擇所有容器但不允許任何進(jìn)入這些容器的入站流量的 NetworkPolicy 來為名字空間創(chuàng)建 “default” 隔離策略。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
這樣可以確保即使容器沒有選擇其他任何 NetworkPolicy,也仍然可以被隔離。 此策略不會更改默認(rèn)的出口隔離行為。
默認(rèn)允許所有入站流量
如果要允許所有流量進(jìn)入某個名字空間中的所有 Pod(即使添加了導(dǎo)致某些 Pod 被視為 “隔離”的策略),則可以創(chuàng)建一個策略來明確允許該名字空間中的所有流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
默認(rèn)拒絕所有出站流量
你可以通過創(chuàng)建選擇所有容器但不允許來自這些容器的任何出站流量的 NetworkPolicy 來為名字空間創(chuàng)建 “default” 隔離策略。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
此策略可以確保即使沒有被其他任何 NetworkPolicy 選擇的 Pod 也不會被允許流出流量。 此策略不會更改默認(rèn)的入站流量隔離行為。
默認(rèn)允許所有出站流量
如果要允許來自名字空間中所有 Pod 的所有流量(即使添加了導(dǎo)致某些 Pod 被視為“隔離”的策略), 則可以創(chuàng)建一個策略,該策略明確允許該名字空間中的所有出站流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
默認(rèn)拒絕所有入口和所有出站流量
你可以為名字空間創(chuàng)建“默認(rèn)”策略,以通過在該名字空間中創(chuàng)建以下 NetworkPolicy 來阻止所有入站和出站流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
此策略可以確保即使沒有被其他任何 NetworkPolicy 選擇的 Pod 也不會被 允許入站或出站流量。
SCTP 支持
FEATURE STATE: Kubernetes v1.20 [stable]
作為一個穩(wěn)定特性,SCTP 支持默認(rèn)是被啟用的。 要在集群層面禁用 SCTP,你(或你的集群管理員)需要為 API 服務(wù)器指定 ?--feature-gates=SCTPSupport=false,...? 來禁用 ?SCTPSupport ?特性門控。 啟用該特性門控后,用戶可以將 NetworkPolicy 的 ?protocol ?字段設(shè)置為 ?SCTP?。
你必須使用支持 SCTP 協(xié)議網(wǎng)絡(luò)策略的 CNI 插件。
針對某個端口范圍
FEATURE STATE: Kubernetes v1.22 [beta]
在編寫 NetworkPolicy 時,你可以針對一個端口范圍而不是某個固定端口。
這一目的可以通過使用 ?endPort ?字段來實(shí)現(xiàn),如下例所示:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-port-egress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 32000
endPort: 32768上面的規(guī)則允許名字空間 ?default ?中所有帶有標(biāo)簽 ?role=db ?的 Pod 使用 TCP 協(xié)議 與 ?10.0.0.0/24? 范圍內(nèi)的 IP 通信,只要目標(biāo)端口介于 32000 和 32768 之間就可以。
使用此字段時存在以下限制:
- 作為一種 Beta 階段的特性,端口范圍設(shè)定默認(rèn)是被啟用的。要在整個集群 范圍內(nèi)禁止使用 ?
endPort?字段,你(或者你的集群管理員)需要為 API 服務(wù)器設(shè)置 ?-feature-gates=NetworkPolicyEndPort=false,...?以禁用 ?NetworkPolicyEndPort?特性門控。 - ?
endPort?字段必須等于或者大于 ?port?字段的值。 - 兩個字段的設(shè)置值都只能是數(shù)字。
你的集群所使用的 CNI 插件 必須支持在 NetworkPolicy 規(guī)約中使用 ?
endPort?字段。 如果你的網(wǎng)絡(luò)插件 不支持 ?endPort?字段,而你指定了一個包含 ?endPort?字段的 NetworkPolicy, 策略只對單個 ?port?字段生效。
基于名字指向某名字空間
FEATURE STATE: Kubernetes 1.22 [stable]
只要 ?NamespaceDefaultLabelName ?特性門控 被啟用,Kubernetes 控制面會在所有名字空間上設(shè)置一個不可變更的標(biāo)簽 ?kubernetes.io/metadata.name?。該標(biāo)簽的值是名字空間的名稱。
如果 NetworkPolicy 無法在某些對象字段中指向某名字空間,你可以使用標(biāo)準(zhǔn)的 標(biāo)簽方式來指向特定名字空間。
通過網(wǎng)絡(luò)策略(至少目前還)無法完成的工作
到 Kubernetes 1.24 為止,NetworkPolicy API 還不支持以下功能,不過 你可能可以使用操作系統(tǒng)組件(如 SELinux、OpenVSwitch、IPTables 等等) 或者第七層技術(shù)(Ingress 控制器、服務(wù)網(wǎng)格實(shí)現(xiàn))或準(zhǔn)入控制器來實(shí)現(xiàn)一些 替代方案。 如果你對 Kubernetes 中的網(wǎng)絡(luò)安全性還不太了解,了解使用 NetworkPolicy API 還無法實(shí)現(xiàn)下面的用戶場景是很值得的。
- 強(qiáng)制集群內(nèi)部流量經(jīng)過某公用網(wǎng)關(guān)(這種場景最好通過服務(wù)網(wǎng)格或其他代理來實(shí)現(xiàn));
- 與 TLS 相關(guān)的場景(考慮使用服務(wù)網(wǎng)格或者 Ingress 控制器);
- 特定于節(jié)點(diǎn)的策略(你可以使用 CIDR 來表達(dá)這一需求不過你無法使用節(jié)點(diǎn)在 Kubernetes 中的其他標(biāo)識信息來辯識目標(biāo)節(jié)點(diǎn));
- 基于名字來選擇服務(wù)(不過,你可以使用 標(biāo)簽 來選擇目標(biāo) Pod 或名字空間,這也通常是一種可靠的替代方案);
- 創(chuàng)建或管理由第三方來實(shí)際完成的“策略請求”;
- 實(shí)現(xiàn)適用于所有名字空間或 Pods 的默認(rèn)策略(某些第三方 Kubernetes 發(fā)行版本 或項(xiàng)目可以做到這點(diǎn));
- 高級的策略查詢或者可達(dá)性相關(guān)工具;
- 生成網(wǎng)絡(luò)安全事件日志的能力(例如,被阻塞或接收的連接請求);
- 顯式地拒絕策略的能力(目前,NetworkPolicy 的模型默認(rèn)采用拒絕操作, 其唯一的能力是添加允許策略);
- 禁止本地回路或指向宿主的網(wǎng)絡(luò)流量(Pod 目前無法阻塞 localhost 訪問, 它們也無法禁止來自所在節(jié)點(diǎn)的訪問請求)。
名稱欄目:創(chuàng)新互聯(lián)kubernetes教程:Kubernetes 網(wǎng)絡(luò)策略
URL分享:http://m.fisionsoft.com.cn/article/cdjiish.html


咨詢
建站咨詢
