楠木軒

「容器平台」Kubernetes網絡策略101

由 司空梓瑤 發佈於 科技

什麼是Kubernetes網絡策略?

有幾家公司正在將他們的整個基礎設施轉移到Kubernetes。Kubernetes的目標是抽象通常在現代IT數據中心中找到的所有組件。因此,pods表示計算實例,網絡插件提供路由器和交換機,卷彌補SAN(存儲區域網絡),等等。但是,網絡安全呢?在數據中心中,這由一個或多個防火牆設備處理。在Kubernetes中,我們有網絡策略。

要在Kubernetes集羣中應用NetworkPolicy定義,網絡插件必須支持NetworkPolicy。否則,您應用的任何規則都是無用的。支持NetworkPolicy的網絡插件包括Calico, Cilium, Kube-router, Romana和Weave Net。

大多數網絡插件在OSI模型的網絡層(第3層)上工作。然而,你可能會發現一些模型也在其他層上工作(例如,第4層和第7層)。

您是否需要在集羣中定義NetworkPolicy資源?默認的Kubernetes策略允許pods接收來自任何地方的流量(這些被稱為非隔離的pods)。因此,除非您處於開發環境中,否則肯定需要適當的NetworkPolicy。

您的第一個NetworkPolicy定義

NetworkPolicy資源使用標籤來確定它將管理哪些pods。資源中定義的安全規則應用於pods組。這與雲提供商用於在資源組上執行策略的安全組的工作原理相同。

在第一個示例中,我們將使用NetworkPolicy來定位具有app=backend 標籤的pods。這些pods將被隔離在進入(進來)和出口(出去)流量一旦規則被應用。

該策略強制要求,在端口3000上,Pods可以接收來自相同名稱空間(默認)的其他Pods的流量,只要:

  • Traffic is from IPs in block 182.213.0.0/16
  • The client pod is in a namespace that is labeled project=mywebapp.
  • The client pod is labeled app=frontend and it is in the same namespace (default).

所有其他進入流量將被拒絕。

允許在端口80上的IP範圍為30.204.218.0/24。所有其他出口交通將被拒絕。

解決這些需求的NetworkPolicy定義文件如下所示:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-network-policy namespace: default spec: podSelector: matchLabels: app: backend policyTypes: - Ingress - Egress ingress: - from: - ipBlock: cidr: 182.213.0.0/16 - namespaceSelector: matchLabels: project: mywebapp - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 3000 egress: - to: - ipBlock: cidr: 30.204.218.0/24 ports: - protocol: TCP port: 80

下面是該網絡策略的可視化。

如何使用選擇器調整網絡策略?

允許或拒絕來自特定或多個來源的通信流的情況有很多。對於您希望允許流量到達的目的地,情況也是如此。Kubernetes NetworkPolicy資源為您提供了一組豐富的選擇器,您可以使用這些選擇器按照您想要的方式保護您的網絡路徑。NetworkPolicy選擇器可用於選擇源連接(入口)和目標連接(出口)。它們是:

  • podSelector:選擇相同名稱空間中的pods,該名稱空間在NetworkPolicy定義的元數據部分中定義。通過pod標籤進行選擇。
  • namespaceSelector:通過它的標籤選擇一個特定的名稱空間。該名稱空間中的所有pods都是匹配的。
  • podSelector與namespaceSelector組合:組合後,您可以在帶有特定標籤的名稱空間中選擇帶有特定標籤的pods。例如,假設我們希望將傳入數據庫(app=db)的流量限制為僅在一個名為env=prod的名稱空間中的pods。此外,pod必須具有app=web。NetworkPolicy定義中用於實現此目的的入口部分如下:

ingress: - from: - namespaceSelector: matchLabels: env: prod podSelector: matchLabels: app: web

請注意

您可能想知道:Kubernetes是否將其規則與AND或or操作符結合?這取決於規則是在單個數組項中,還是在多個數組項中。無論定義是在YAML還是JSON中,這都是一樣的。在本文中,我們將討論YAML。因此,在上面的代碼片段中,我們將namespaceSelector和podSelector都放在一個項中(在YAML中,數組項用破號' - '表示)。因此,Kubernetes將把這兩個規則與AND操作符結合起來。換句話説,傳入的連接必須匹配這兩個規則才能被接受。

另一方面,如果我們將上面的代碼段寫成

ingress:
- from:
- namespaceSelector:
matchLabels:
env: prod
podSelector:
matchLabels:
app: web

Kubernetes將把這兩個規則與OR操作符結合起來。這意味着將允許名稱空間中標記為“env=production”的任何pod。同樣,在同一個NetworkPolicy命名空間中,任何標籤為app=web的pod都是允許的。在定義NetworkPolicy規則時,這是一個非常重要的區別。

  • ipBock:在這裏,您可以定義哪些IP CIDR塊是所選pods連接的源或目的地。傳統上,這些ip位於集羣外部,因為pods的ip時間很短,隨時都可能更改。

您應該知道,根據所使用的網絡插件,在數據包被NetworkPolicy規則分析之前,源IP地址可能會改變。一個示例場景是雲提供商的負載均衡器將包的源IP替換為它自己的。

ipBlock還可以用來阻止允許範圍內的特定ip。這可以使用except關鍵字來完成。例如,我們可以允許來自182.213.0.0/16的所有流量,但是拒絕182.213.50.43。這種配置的代碼片段如下:

-ipBlock:
cidr: 182.213.0.0/16
except:
-182.213.50.43/24

如您所見,您可以在excepted數組中添加多個IP地址甚至範圍作為項。

常見的Kubernetes NetworkPolicy用例

本文的其餘部分將討論在集羣中使用NetworkPolicy的一些常見用例。

拒絕沒有規則的進入流量

有效的網絡安全規則首先在默認情況下拒絕所有流量,除非明確允許。這就是防火牆的工作原理。默認情況下,Kubernetes認為任何沒有被NetworkPolicy選擇的pod都是“非隔離的”。這意味着所有進出交通都是允許的。因此,在默認情況下拒絕所有流量是一個很好的基礎,除非NetworkPolicy規則定義了應該通過哪些連接。拒絕所有接入流量的NetworkPolicy定義如下:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: namespace: default name: ingress-default-deny spec: podSelector: {} policyTypes: - Ingress

應用此策略的結果是,除非另一條規則允許,否則“默認”名稱空間中的所有pods將不接受任何流量。可以通過NetworkPolicy的元數據部分根據需要更改名稱空間。

請注意,這並不影響出口流量,出口流量必須通過其他規則進行控制,我們稍後將對此進行討論。

否認沒有規則的出口流量

我們也在做同樣的事情,只是在出口交通上。以下NetworkPolicy定義將拒絕所有流出流量,除非另有規則允許:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress

您可以將這兩種策略組合在一個定義中,該定義將拒絕所有進入和出口流量,如下所示:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
namespace: default
name: ingress-egress-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress

只允許所有進口流量

您可能想要覆蓋限制對pods通信的任何其他NetworkPolicy,也許是為了解決連接問題。這可以通過應用以下NetworkPolicy定義來實現:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: ingress-default-allow namespace: default spec: podSelector: {} ingress: - {} policyTypes: - Ingress

這裏唯一的區別是我們添加了一個沒有任何規則的ingress對象。

但是請注意,此策略將覆蓋同一名稱空間中的任何其他隔離策略。

只允許所有出口交通

就像我們在入口部分所做的一樣,有時您希望排他性地允許所有出口流量,即使其他一些策略拒絕它。以下網絡策略將覆蓋所有其他出口規則,並允許從所有吊艙到任何目的地的所有流量:

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: namespace: default name: egress-default-allow spec: podSelector: {} egress: - {} policyTypes: - Egress

在所有情況下,您都可以使用前面討論過的podSelector來修改允許-所有-否定-所有規則來匹配特定的pods。

TL;DR

Kubernetes使用NetworkPolicy資源來履行傳統數據中心中常見的防火牆角色。NetworkPolicy很大程度上依賴於網絡插件的功能。

NetworkPolicy定義可以在一個名稱空間中的所有pods上工作,也可以使用選擇器將規則應用到帶有特定標籤的pods上。

通過入口和出口規則,您可以定義從/到的傳入或傳出連接規則:

  • 帶有特定標籤的Pods (podSelector)
  • 屬於具有特定標籤的名稱空間的Pods (namespaceSelector)
  • 結合這兩種規則,將選擇範圍限制在帶標籤的名稱空間中帶標籤的pods。
  • IP範圍。通常,它們作為pods是外部ip。根據定義,ip是不穩定的。

網絡策略選擇的Pods被稱為“隔離的”。那些不匹配的稱為“非孤立”。Kubernetes允許非隔離艙接受所有的出口和入口交通。出於這個原因,建議對進出流量執行默認的“拒絕所有”策略,這樣未被任何NetworkPolicy匹配的pods將被鎖定,直到它們被匹配為止。

【來源:首席架構師智庫】

聲明:轉載此文是出於傳遞更多信息之目的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯繫,我們將及時更正、刪除,謝謝。 郵箱地址:newmedia@xxcb.cn