有幾家公司正在將他們的整個基礎設施轉移到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;DRKubernetes使用NetworkPolicy資源來履行傳統數據中心中常見的防火牆角色。NetworkPolicy很大程度上依賴於網絡插件的功能。
NetworkPolicy定義可以在一個名稱空間中的所有pods上工作,也可以使用選擇器將規則應用到帶有特定標籤的pods上。
通過入口和出口規則,您可以定義從/到的傳入或傳出連接規則:
- 帶有特定標籤的Pods (podSelector)
- 屬於具有特定標籤的名稱空間的Pods (namespaceSelector)
- 結合這兩種規則,將選擇範圍限制在帶標籤的名稱空間中帶標籤的pods。
- IP範圍。通常,它們作為pods是外部ip。根據定義,ip是不穩定的。
網絡策略選擇的Pods被稱為“隔離的”。那些不匹配的稱為“非孤立”。Kubernetes允許非隔離艙接受所有的出口和入口交通。出於這個原因,建議對進出流量執行默認的“拒絕所有”策略,這樣未被任何NetworkPolicy匹配的pods將被鎖定,直到它們被匹配為止。
【來源:首席架構師智庫】
聲明:轉載此文是出於傳遞更多信息之目的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯繫,我們將及時更正、刪除,謝謝。 郵箱地址:[email protected]