作者:任雲康,青雲科技研發工程師
前言
對於項目下的網絡隔離,有用戶提出了以下疑問:
- 網絡隔離是針對 Pod 的嗎?
- 網絡隔離的最小配置是什麼?
- 配置後,哪些是可以訪問的,哪些是不可以訪問的?
- 通過 Ingress 暴露、LB 類型的 Service 暴露、NodePort 類型的 Service 暴露的流量的具體鏈路是什麼樣的?
KubeSphere 網絡策略的實現思路
KubeSphere 對於 NetworkPolicy 的集成中主要包含:
-
集羣網絡策略管理:主要提供一個原生的 NetworkPolicy 資源的管理,當 KubeSphere 租戶網絡隔離無法滿足用戶的全部需求時,可以在此通過 yaml 管理原生的 NetworkPolicy。
-
租戶網絡隔離管理:分爲企業空間網絡隔離和項目空間的網絡隔離。
- 當開啓企業空間網絡隔離時,會自動爲該企業空間的所有項目創建一條只允許本企業空間訪問的入站規則的網絡策略,默認不限制出站流量;
- 當開啓項目網絡隔離時,會自動爲該項目創建一條只允許項目訪問的入站規則的網絡策略;
- 項目網絡隔離下可以配置白名單列表,內部白名單允許當前項目中的容器組與當前企業空間其他項目中的服務進行通信,外部白名單允許當前項目中的容器組與企業空間外部的特定網段和端口進行通信;
- 默認不限制出站流量;如果配置出站白名單,那隻會放行白名單上的出站項。
出站:即對本項目下的 pod 是否可以訪問本項目外的 pod/ip/port 的限制。
入站:即對本項目外的 pod/ip 是否可以訪問本項目下的 pod 所提供的服務的限制。
注意:NetworkPolicy 是由具體的 CNI 來實現,KubeSphere 做了 UI 化的管理,同時封裝了一個項目級別的 NetworkPolicy,用作項目空間的網絡隔離。
因此,對前文的問題,我們有了答案:
- 網絡隔離是針對與 pod 的,而項目網絡隔離會匹配本項目下的所有 pod;也可以認爲此處的網絡隔離是針對項目的;
- 服務通過 Ingress、NodePort、LoadBalancer 暴露,表明 service 要給集羣外提供服務,如果使用 KubeSphere 項目網絡隔離進行管理的話,需要配置外部白名單。
配置
當我們通過 NodePort、LoadBalancer 暴露 Kubernetes 的 service 時,kube-proxy 會創建相應的 ipvs 或 iptables 規則來轉發流量。然而,當外部流量進入集羣並根據這些規則被轉發時,如果目標 pod 不在本地節點上,就會進行一次源網絡地址轉換(SNAT),這將導致 TCP 包中的源 IP 地址被替換爲節點 IP 或 overlay 封裝接口的 IP,從而丟失了客戶端的原始 IP。如果目標 pod 在本地節點上,可能會直接轉發到本機 pod,此時會保留客戶端 IP。
這裏以 Calico 舉例,如果使用的非 ipip/vxlan 模式,我們需要找到 node 上的 eth0 網口上的 IP;如果使用的是 ipip/vxlan 模式,需要找到 node 上的用於封裝網卡的 IP,然後添加到外部白名單中放行。同時也要把客戶端 IP 也添加到外部白名單中放行。
爲了總是保留客戶端的原始 IP,可以將 service 的外部訪問策略設置爲 Local。但是當流量進入沒有目標 pod 的節點上時,流量不再進行轉發導致請求失敗。
配置 NodePort 暴露
當配置 service 爲 NodePort 且配置外部訪問策略爲 Cluster 時,流量訪問如下:
當配置 service 爲 NodePort 且配置外部訪問策略爲 Local 時,流量訪問如下:
開啓項目網絡隔離後,
- 當外部訪問策略爲 Cluster ,需要在外部白名單中放行集羣的所有節點 IP 或 overlay 封裝接口的 IP、客戶端 IP,缺點是可能會丟失客戶端 IP,且由於 SNAT 的緣故無法攔截指定的 IP;
- 當外部訪問策略爲 Local ,需要在外部白名單中放行可以訪問該服務的客戶端 IP,缺點需要確保使用運行了 pod 的節點 IP:NodePort 來訪問 service,否則數據包會被丟棄,從而導致請求失敗。
配置 LoadBalancer 暴露
當 service 設置爲 LoadBalancer 時,你需要支持配置外部負載均衡器的環境,不同的環境技術實現也會有所不同,下面以 OpenELB 爲例說明。
當配置 service 爲 LoadBalancer 且配置外部訪問策略爲 Cluster 時,流量訪問如下:
當配置 service 爲 LoadBalancer 且配置外部訪問策略爲 Local 時,流量訪問如下:
開啓項目網絡隔離後,
- 當外部訪問策略爲 Cluster ,需要在外部白名單中放行集羣的所有節點 IP 或 overlay 封裝接口的 IP、客戶端 IP,缺點是可能會丟失客戶端 IP,且由於 SNAT 的緣故無法攔截指定的 IP;
- 當外部訪問策略爲 Local ,需要在外部白名單中放行可以訪問該服務的客戶端 IP,OpenELB 只會將訪問 LoadBalancer serviceip 的流量轉發到已經運行了 pod 的節點上。
配置 Ingress 暴露
當配置 Ingress 訪問時,集羣內部不同的 service 需要註冊相應的應用路由,同時 Ingress svc 依舊需要通過 LoadBalancer 或者 NodePort 對外暴露,訪問流量如下圖:
對於 LoadBalancer 或者 NodePort 對外暴露可見我們上述探討。
更多技術原理可參考 kubernetes networkpolicy:
- https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/create-external-load-balancer/
- https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/
本文由博客一文多發平臺 OpenWrite 發佈!