DockOne微信分享(一三三):深入理解Kubernetes網路策略
【3 天燒腦式基於Docker的CI/CD實戰訓練營 | 北京站】本次培訓圍繞基於Docker的CI/CD實戰展開,具體內容包括:持續整合與持續交付(CI/CD)概覽;持續整合系統介紹;客戶端與服務端的 CI/CD 實踐;開發流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及實踐經驗分享。
CNI
Kubernetes 對網路做了較好的抽象。它將對網路的需求交給外部的元件完成,也就是 CNI driver。
Pod 的網路必須滿足以下三個需求:
- 所有 Pod 之間無需 NAT 即可互通
- 主機和 Pod 之間無需 NAT 即可互通
- Pod 自省的 IP 地址和之外部看到該 Pod 的地址一致
CNI 對網路的實現做了詳細的定義。CNI 的實現可以被分成三種:
- 3 層路由實現
- Overlay 實現
- 2 層交換實現
現在比較常用的 CNI 實現有:Flannel、Calico、Weave。 Flannel 通過 VXLan Overlay 來實現跨主機 Pod 網路, Calico 則完全通過 3 層路由來實現了跨主機的容器網路,Weave也是 Overlay 的實現。
什麼是Network Policy
隨著業務邏輯的複雜化,微服務的流行,越來越多的雲服務平臺需要大量模組之間的網路呼叫。
傳統的單一外部防火牆,或依照應用分層的防火牆的做法漸漸無法滿足需求。在一個大的叢集裡面,各模組,業務邏輯層,或者各個職能團隊之間的網路策略的需求越來越強。
Kubernetes 在 1.3 引入了 Network Policy 這個功能來解決這個問題。這些 Policy 允許使用者在同一個 Cluster 內實現網路的隔離。也就是在某些需要的 Pod 之間架起防火牆。可以簡單的理解為各個微服務之間的動態防火牆。也有人把這叫做分散式防火牆。
並非所有的網路驅動都支援這個功能。比如大家比較熟悉的,比較流行的 Flannel 就還沒有加入對 Network Policy 的支援。Calico 和 Weave 都各自實現了 NPC(network policy controller)。雖然 Flannel 不支援 Network Policy。但是,可以使用 Flannel 提供網路方案,同時使用 Calico 或者Weave 的 NPC 元件來共同完成。Canal 就提供了將 Flannel 和 Calico NPC 組合的方案。
DEMO
下面我們就以Calico為基礎,給大家做一個demo。
這裡我已經搭好了一個 Kubernetes 的簡單的叢集:只有一個 master 和兩個 minion。我們先來部署 Calico。這裡要注意的是,由於我們要 demo 的是最新的 Kubernetes API,我們必須使用 Kubernetes 1.7 和 Calico 2.3,並且,Calico只能配置成 Kubernetes Datastore 的模式。在這種模式下,Calico 對網路狀態的控制是通過 Kubernetes API 來完成的。另外還有一種模式是通過 etcd 叢集。那種模式暫時還不支援最新的API。Kubernetes Datastore 這種方式有時也叫做KDD — Kubernetes datastore driver。
在進行 KDD 模式的 Calico 安裝時要注意以下這麼幾點:
- IPAM 要使用 host-local
- 通過 controller manager 來分配 CIDR
細節請點選:http://docs.projectcalico.org/ … tore/
配置好 Calico之後,我們來看一個簡單的 demo,實際操作一下 Network Policy:
為了簡單起見,我們會直接使用 default namespace。如果你在一個現有的環境裡面, 可以將以下的命令在一個獨立的 namespace 裡面執行。
建立 namespace 使用這個命令:
kubectl create ns np-demo
接下來執行一個簡單的 nginx deployment 並用80埠暴露服務:
kubectl run nginx --replicas=2 --image=nginx deployment "nginx" created kubectl expose deploy nginx --port=80 service "nginx" exposed
現在我們還沒有做任何的限制,所以 Kubernetes 預設情況是所有 Pod 都是開放的。
我們來用一個 BusyBox 的 Pod 驗證一下:
kubectl run busy --rm -ti --image busybox /bin/sh If you don`t see a command prompt, try pressing enter. / # wget -q nginx -O - | head -4
上面的 Wget 命令是在 BusyBox 這個 Pod 裡面執行的。-q
和 -O -
的組合會使這個命令在命令列輸出 nginx 的預設首頁,這表明我們的驗證是成功的。用 Ctl-D 退出容器。
接下來我們就要加入限制了。我們的做法是先限制對所有 Pod 的訪問,然後建立白名單。 kubectl apply下面的 YAML 檔案就可以限制所有訪問:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: default-deny spec: podSelector:
注意我們提供了一個空的 podSelector。
我們再試著用之前的 BusyBox 的方式來訪問一下:
kubectl run busy --rm -ti --image busybox /bin/sh / # wget -q --timeout=5 nginx -O -
這此我們設定了 5 秒的超時。因為訪問被拒接,所以確實會超時:
wget: download timed out
好,我們的第一個 Network Policy 已經生效了。然而,限制對所有 Pod 的訪問顯然是沒有意義的。接下來我們建立一個白名單 . apply 下面的 YAML 檔案:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: run: access
這個 Network Policy 的意思是:標籤 run:access 選中的 Pod 可以訪問標籤 run:nginx 的 Pod,也就是我們 demo 開始時建立的 Nginx 的 Pod。這些 label 都是 kubectl run 命令自動 新增的。
接下來我們試試看能否成功地訪問了:
kubectl run access --rm -ti --image busybox /bin/sh wget -q nginx -O -
我們依然會看到熟悉的 Nginx 預設首頁。如果我們執行一個不符合上述 selector 的 Pod,就無法訪問。這個留給有興趣的同學自己回去驗證。
如果你接觸過 1.7 之前的 Network Policy 的話,你可能會發現這裡的 API 有些不同。Kubernetes 1.7 已經將 Network Policy 正式提升到 GA。
正式的 API 和之前的 API 區別有:
- 不再使用 Annotation 來表達 default-deny 等這樣的規則
- API version 從 extension/beta1 升級到了 networking.k8s.io/v1
實現
Calico 的實現是基於 iptables 的。在每個 chain 的頂端,Calico 都插入了一條定製的 chain,從而使得 packet 優先經過 Calico 定義的規則。我們在其中一個 minion 上面執行 iptables-save -c 就可以檢查這些規則。可以看出 kube-proxy 和 Calico 都定義了大量的 iptable 規則。
這裡細節很多,我們只需要關注這幾點:
Calico 使用 conntrack 來優化。就是說,一旦一個連線已經建立,之後的packet都會直接被允許通過。比如:
-A cali-fw-cali7af3f94d3a1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A cali-fw-cali7af3f94d3a1 -m conntrack --ctstate INVALID -j DROP
名為 cali-pi-xxxx 的規則是負責 Network Policy Ingress 的。我們可以想見,如果我們定義了很多 Policy,一個一個單獨定義的規則會導致效能下降。這裡 Calico 利用了 iptables 的 ipset 特性。使得一個 rule 可以通過 hash 表來匹配多種地址。
-A cali-pi-_G7e-YAvXRsfDoqGDf36 -m set --match-set cali4-s:2I5R46OBA_TBIUlpH0dCd_n src -j MARK --set-xmark 0x1000000/0x1000000 -A cali-pi-_G7e-YAvXRsfDoqGDf36 -m mark --mark 0x1000000/0x1000000 -j RETURN
Weave 的實現也類似。底層還是使用了 iptables 和 netfilter。Weave 也建立了自定義的 chain。但由於一個是 Overlay 一個是路由,規則還是有些不同的。
另外一個細微的不同是,Weave使用了 -m state 而不是 -m conntrack。conntrack 是比較新的語法,但實際使用中功能是一樣的。下面是幾個 Weave 安裝的 iptables rules 的例子:
FORWARD chain: -o weave -j WEAVE-NPC -o weave -j DROP WEAVE_NPC chain: -m state --state RELATED,ESTABLISHED -j ACCEPT -m state --state NEW -j WEAVE-NPC-DEFAULT -m state --state NEW -j WEAVE-NPC-INGRESS -m set --match-set weave-v/q_G.;Q?uK]BuDs2 dst -j ACCEPT -m set --match-set weave-k?Z;25^M}|1s7P3|H dst -j ACCEPGo
Q&A
Q:Calico 和 Weave 從 Policy 處理效能來看,兩者哪個更優?
A:兩者在 iptables 層面上的實現原理是一樣的。都用了-m
state 和 ipset 優化,效能差別不大。
Q:Calico 結合 Kubernetes 怎麼實現多租戶,比如網路隔離之類的?
A:可以考慮用 namespace 來隔離。沒有 Network Policy 的情況下當然是互通的。但是 Kubernetes 的 Network Policy 支援 namespaceSelector,可以輕鬆搞定。
Q:Weave、Calico、Flannel 比較,適用場景和優缺點是什麼,Flannel out了麼?
A:各有各的市場 :-)。
Flannel 比較簡單,資源消耗也會小些。Flannel 不能算 out 了。Cannel 的出現將 Flannel 和 Calico 整合了起來。
Q:NPC 必須用 iptables 實現嗎?在某些情況下,Pod 出向流量並不會由主機協議棧,這樣 iptables 就用不了,這種情況下 NPC 怎麼實現呢 ?
A:Calico、Weave、Romana 的 NPC 都是通過 iptables 實現的。Pod
egress 不通過主機協議棧也會通過 netfilter。
以上內容根據2017年07月20日晚微信群分享內容整理。分享人樑文智:睿雲智合研發顧問。 DockOne每週都會組織定向的技術分享,歡迎感興趣的同學加微信:liyingjiesa,進群參與,您有想聽的話題或者想分享的話題都可以給我們留言。
原文釋出時間為:2017-07-21
本文作者:樑文智
本文來自雲棲社群合作伙伴Dockerone.io,瞭解相關資訊可以關注Dockerone.io。
原文標題:DockOne微信分享(一三三):深入理解Kubernetes網路策略
相關文章
- DockOne微信分享(一零五):度量驅動的DevOps轉型dev
- Kubernetes Egress 網路策略指南
- DockOne微信分享(六十八):應用容器env化實戰
- 深入淺出Kubernetes網路:容器網路初探
- 深入理解hadoop網路Hadoop
- 機器學習:深入理解LSTM網路 (二)機器學習
- DockOne微信分享(八十九):恆生金融交易系統的Docker化實踐Docker
- 附029.Kubernetes安全之網路策略
- 深入淺出Kubernetes網路:跨節點網路通訊之Flannel
- 計算機網路——深入理解TCP/IP計算機網路TCP
- 深入理解Hadoop叢集和網路Hadoop
- 深入理解Kubernetes資源限制:CPU
- DockOne微信分享(一三五):求取一份極致的簡單:海量應用容器化改造之路
- 【Kubernetes系列】第10篇 網路原理解析(下篇)
- 【Kubernetes系列】第9篇 網路原理解析(上篇)
- 深入理解JVM(三)——垃圾收集策略詳解JVM
- 計算機網路——深入理解HTTP以及HTTPs計算機網路HTTP
- 深入理解Kubernetes資源限制:記憶體記憶體
- kubernetes網路解析
- Kubernetes網路概述
- Kubernetes網路解決方案技術原理深入剖析-Kubernetes商業環境實戰
- 網路安全策略
- 深入理解Linux網路內幕-PART I -通用背景(轉)Linux
- Knative = Kubernetes網路++
- Kubernetes網路概念初探
- Kubernetes 網路型別型別
- 微信吧,一個有逼格的網際網路行業微信公眾賬號分享聚集地!行業
- 【技術分享】《深入理解Elasticsearch》讀書筆記Elasticsearch筆記
- 從零開始入門 K8s | Kubernetes 網路概念及策略控制K8S
- 深入理解Prometheus: Kubernetes環境中的監控實踐Prometheus
- Kubernetes網路分析之Flannel
- Kubernetes CNI網路外掛
- 微信分享
- 理解策略模式模式
- 網路爬蟲的反扒策略爬蟲
- 企業網路安全策略
- Linux網路安全策略Linux
- 深入理解Java虛擬機器 --- 記憶體分配與回收策略Java虛擬機記憶體