實現網絡策略是構建基於kubernetes的安全平臺的關鍵部分,但是從簡單的示例到更復雜的現實策略的學習曲線是陡峭的。不僅要使YAML語法和格式正確,而且更重要的是,在網絡策略規範的行爲中有許多微妙之處(例如默認允許/拒絕、名稱空間、通配符、規則組合等)。即使是經驗豐富的Kubernetes YAML-wrangler也可以輕鬆地通過高級網絡策略用例進行思考。
在過去的幾年裏,當我們與你們中的許多人一起在Cilium社區中執行Kubernetes網絡策略時,我們已經瞭解了許多關於網絡策略挑戰的知識。今天,我們很興奮地宣佈一個新的免費工具,用於社區,幫助您Kubernetes網絡策略編寫旅程:editor.cilium.io
Kubernetes網絡策略編輯器幫助您構建、可視化和理解Kubernetes網絡策略。
-
教程:遵循輔助教程,從還沒有使用網絡策略到一個良好的安全態勢。 -
互動創建:以輔助和互動的方式創建策略。 -
可視化和更新:上傳現有的策略,以驗證和更好地理解它們。 -
安全性評分:檢查策略的安全性評分,以瞭解它們添加到集羣的安全性級別。 -
YAML下載:將策略作爲YAML下載,以便在您最喜歡的CNI的集羣中執行。 -
共享:通過GitHub gist在團隊之間共享策略,並創建鏈接來可視化您自己的網絡策略。 -
自動創建策略:上傳哈勃流量日誌,根據觀察到的網絡流量自動生成網絡策略。
嘗試網絡策略編輯器
網絡策略編輯器,真的有用嗎?
爲了更具體地說明這一點,讓我們來探討一下在使用網絡策略時遇到的5個常見問題,無論是新手還是已經使用了一段時間的人。在每個錯誤的背後,你會在工具中找到一個簡短(3-5分鐘)的教程鏈接,引導你完成修復錯誤所需的每個步驟。
錯誤1:沒有使用命名空間選擇器
考慮這樣一個場景:我們希望運行在monitoring
命名空間中的集中式Prometheus實例能夠從運行在default
命名空間中的Redis Pod中獲取度量數據。請看下面的網絡策略,它應用於default
名稱空間中。它允許標籤爲app=prometheus的Pods從標籤爲app=redis的Pods中獲取度量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-from-prometheus
namespace: default
spec:
podSelector:
matchLabels:
app: redis
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: prometheus
正如您在編輯器的可視化中所看到的,上面的網絡策略只有在兩個pod位於相同名稱空間中時纔有效。除非顯式地使用namespaceSelector來選擇其他名稱空間,否則podSelector的作用域是策略的名稱空間。
這樣做是正確的嗎?
一個常見的錯誤可能是使用podSelector創建一個入口規則,如當前策略所示。然而,正如您在可視化中看到的,這個網絡策略只允許從默認名稱空間的app=prometheus輸入流量。爲了創建一個跨命名空間允許規則,你必須添加namespaceSelector:{}
。
具體答案請點擊:https://editor.cilium.io/?policy-tutorial=allow-cross-namespace
錯誤2:不可能是DNS…
通常情況下,工作負載必須被鎖定以限制外部訪問(即egress
默認拒絕)。如果希望防止應用程序將通信發送到除同一名稱空間中的Pods之外的任何地方,可以創建以下策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-kube-dns
namespace: default
spec:
podSelector:
matchLabels:
app: foo
egress:
- to:
- podSelector: {}
然而,一旦您部署了這個網絡策略,您的應用程序連接可能會中斷。爲什麼?Pod通常會通過服務的DNS名稱到達其他Kubernetes服務(例如service1.tenant-a.svc.cluster.local),解析這個名稱需要Pod將出口流量發送到在kube-system名稱空間中標籤爲k8s-app=kube-dns的Pod。
如何修復這個問題呢?
策略將添加如下網絡策略出口規則:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
注意:該規則明確地只允許對Kubernetes DNS進行DNS查詢,它不允許出口DNS流量到Kubernetes以外的DNS服務器。這是防止DNS流量攻擊的推薦方法。
具體答案請點擊:https://editor.cilium.io/?policy-tutorial=allow-kube-dns
錯誤3:使用傳統的網絡結構
如果您使用傳統的網絡環境,那麼使用32 CIDR規則允許流量到Pod的IP地址,如kubectl描述Pod的輸出所示。例如:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-pod
spec:
podSelector:
matchLabels:
app: foo
egress:
- to:
- ipBlock:
cidr: 10.0.2.125/32
然而,Pod ip是短暫的和不可預測的,並且取決於網絡插件的實現,ipBlock規則可能只允許出口流量到集羣之外的目的地。Kubernetes文檔建議僅對集羣外的IP地址使用ipblock。
怎麼解決這個問題呢?
使用podSelector和namespaceSelector來代替ipBlock:
-
只允許特定Pod的進出 -
允許同一命名空間內的所有出口通信 -
允許集羣內的所有出口流量
具體答案請點擊:https://editor.cilium.io/?policy-tutorial=allow-egress-to-pod
錯誤4:網絡規則如何結合使用
讓我們看一下另一個出口策略示例,該示例試圖允許標籤爲app=foo的Pods建立到端口443上IP爲192.168.1.22的外部VM的出口連接
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-to-private-vm-443
spec:
podSelector:
matchLabels:
app: foo
egress:
- to:
- ipBlock:
cidr: 192.168.1.22/32
- ports:
- port: 443
等等……雖然這是有效的YAML和有效的網絡策略,但YAML中的一個額外字符帶來了巨大的不同,最終允許了比我預期更多的連接。端口
前面的-
被解釋爲兩個不同的規則,一個允許所有流量到VM IP(在任何端口上),另一個允許所有流量到443端口(不管IP地址是什麼)。網絡策略規範規定規則在邏輯上是或
的(而不是與
),這意味着Pod工作負載具有比預期更多的連接。你如何防止這些錯誤? 請查看如下yaml:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-to-private-vm-443
spec:
podSelector:
matchLabels:
app: foo
egress:
- to:
- ipBlock:
cidr: 192.168.1.22/32
ports:
- port: 443
具體答案請點擊:https://editor.cilium.io/?policy-tutorial=combine-policy-rules
錯誤5:混淆了{}
的不同用法
在網絡策略中,空花括號(即{})在不同的上下文中有不同的含義,這導致了很多困惑。我們將用最後一個例子作爲一個小測驗。這兩個看起來相似的網絡策略規則都利用了{},它們之間的區別是什麼?猜測一下,然後在下面的網絡策略編輯器中查看每條規則,看看您是否正確。
乍一看,空花括號(例如:{})可能意味着匹配所有內容
。然而,這並不總是正確的;
ingress:
- {}
空花括號在規則級別使用,它們被轉換爲空規則。理論上,它應該匹配所有內容:同一名稱空間中的所有pod,其他名稱空間中的所有pod,甚至來自或來自集羣外部的通信流。然而,實際上它們只匹配集羣中的所有pod,並且有效地表示了以下策略規則:
ingress:
- from:
- podSelector: {}
namespaceSelector: {}
注意:它不包括ipBlock,因此該規則不會匹配任何集羣外的流量。
同時,下面的規則可能看起來幾乎相同:
ingress:
- from:
- podSelector: {}
但是,它只在相同名稱空間中的pods上匹配,而不會在來自其他名稱空間的輸入流量上匹配。
具體答案請點擊:https://editor.cilium.io/?policy-tutorial=empty-selectors
總結
希望您覺得這些示例有用,如果您有其他常見的網絡策略陷阱
的例子或其他有趣的策略可以與社區分享,我們將非常樂意聽取您的意見。您可以隨意嘗試制定自己的網絡策略或刪除現有的策略,以可視化方式檢查它們是否執行您希望它們執行的操作。
另外,送福利了,最近我準備了關於各大廠的雲原生技術最佳實踐資料,請點擊關注如下公衆號,回覆【雲原生】獲取
本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。