<th id="0poub"></th>
  1. <th id="0poub"><track id="0poub"><dl id="0poub"></dl></track></th><dd id="0poub"><track id="0poub"></track></dd>

    <dd id="0poub"></dd>
    <dd id="0poub"><pre id="0poub"></pre></dd><th id="0poub"></th>
    <th id="0poub"><track id="0poub"></track></th>
    <tbody id="0poub"><pre id="0poub"></pre></tbody>
    <em id="0poub"><acronym id="0poub"><kbd id="0poub"></kbd></acronym></em>
    logo

    地址:深圳南山區大沖國際中心21樓

    聯系我們 : contact@wise2c.com

    產品支持 : service@wise2c.com

    售前咨詢 : sales@wise2c.com

    電話: +86 (755) 33268246

    粵ICP備16049363號

    深入理解Kubernetes網絡策略

    深圳睿云智合科技有限公司 > 睿云新聞  > 深入理解Kubernetes網絡策略

    深入理解Kubernetes網絡策略

    梁文智-睿云智合研發顧問

    分享人:梁文智-睿云智合研發顧問

     

    時間:2017-7-20

     

    當我們逐漸向著微服務、云原生邁進的時候,傳統靜態的、相對簡單的網絡安全策略開始顯得吃力。?Kubernetes 的?Network Policy 特性正是來解決這個問題的。在剛剛出爐不久的1.7版本中,該特性也被扶正成為GA。讓我們來一起看看?Network Policy 是什么,能為我們做什么,以及是如何實現的。

     

    CNI

     

     

    Kubernetes 對網絡做了較好的抽象。它將對網絡的需求交給外部的組件完成,也就是?CNI driver。

     

    Pod 的網絡必須滿足以下三個需求:

     

    1 所有?Pod 之間無需?NAT 即可互通

    2 主機和?Pod 之間無需?NAT 即可互通

    3 Pod 自省的?IP 地址和之外部看到該?Pod 的地址一致

     

    CNI 對網絡的實現做了詳細的定義。CNI 的實現可以被分成三種:

     

    1 3 層路由實現

    2 Overlay 實現

    3 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 安裝時要注意以下這么幾點:

     

    1 IPAM 要使用?host-local

    2 通過?controller manager 來分配?CIDR

     

    細節請點擊:http://t.cn/R97OVqc

     

    配置好?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 區別有:

     

    1 不再使用?Annotation 來表達?default-deny 等這樣的規則

    2 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

     

     

    QCalico ?Weave ?Policy 處理性能來看,兩者哪個更優?

    A:兩者在?iptables 層面上的實現原理是一樣的。都用了-m

    state 和?ipset 優化,性能差別不大。

     

    QCalico 結合?Kubernetes 怎么實現多租戶,比如網絡隔離之類的?

    A:可以考慮用?namespace 來隔離。沒有?Network Policy 的情況下當然是互通的。但是?Kubernetes 的?Network Policy 支持?namespaceSelector,可以輕松搞定。

     

    QWeave、Calico、Flannel 比較,適用場景和優缺點是什么,Flannel out了么?

    A:各有各的市場?:-)。

     

    Flannel 比較簡單,資源消耗也會小些。Flannel 不能算?out 了。Cannel 的出現將?Flannel 和?Calico 整合了起來。

     

    QNPC 必須用?iptables 實現嗎?在某些情況下,Pod 出向流量并不會由主機協議棧,這樣?iptables 就用不了,這種情況下?NPC 怎么實現呢??

    A:Calico、Weave、Romana 的?NPC 都是通過?iptables 實現的。Pod

    egress 不通過主機協議棧也會通過?netfilter。

    No Comments

    Post a Comment

    Comment
    Name
    Email
    Website