《Rancher技術特性全解及容器網絡解決方案》要點:
本文介紹了Rancher技術特性全解及容器網絡解決方案,希望對您有用。如果有疑問,可以聯系我們。
作者簡介:
劉力
Rancher 資深架構師
主負責容器云平臺產品架構及設計,10年以上的企業級 IT 解決方案和服務經驗,在多個行業如運營商、政府、金融、大中型企業網絡及應用交付解決方案上有著豐富經驗.管理過國內對容器技術在實際生產環境中的大型項目.
本文目的在于和大家一起了解一下容器網絡以及如何在容器云管理平臺上實現扁平網絡.
內容包括:
- 什么是 CNI 接口;
- 容器網絡基于 CNI 的實現—-IPsec 及 VXLAN;
- 容器網絡基于 CNI 的實現—-直接路由訪問容器;
自2013年 Docker 出現以來,全球已經有越來越多的企業用戶在開發測試或生產環境中采用 Docker 容器技術.
然而,如下圖所示,在企業內部將容器技術真正用于生產時,很多用戶發現面臨的最大的問題仍然是在 VM 虛擬化時代曾經面臨并已經解決的問題.
例如,如何將容器中的數據進行持久化存儲,如何選擇合適的網絡方案,跨云和跨數據中心的部署和管理如何解決?
業內有款開源的容器云管理平臺—— Rancher,短短1年里,已經供全球 4000 多個用戶部署及試用、超過 1800 萬次的下載量(注:統計來自 DockerHub 官方鏡像下載數量).
使用場景覆蓋金融、互聯網、運營商、教育等各個領域.在本次交流中我們將基于該開源容器云平臺進行探討,同時針對容器面臨的網絡問題的解決方案進行分享.
最早的容器網絡模型,利用的是容器宿主機內部的網絡,同時其 IPAM 管理也是基于容器宿主機的,所有容器宿主機上的容器都會連接到容器宿主機內的 Linux Bridge,叫 Docker0,它默認會分配 172.17 網段中的一個 IP,因為有 Docker0 這個網橋,所以在一個容器宿主機上的容器可以實現互聯互通.
但是因為 IPAM 范圍是基于單容器宿主機的,所以在其他容器宿主機上,也會出現完全相同的IP地址.這樣一來這兩個地址肯定沒辦法直接通信.
為了解決這個問題一般采用的就是 NAT 的方法.比如說我有一個應用,它有 Web 和 Mysql,分別在不同的容器宿主機上,Web 需要去訪問 Mysql,我們會把這個 Mysql 的3306端口映射到容器宿主機上的3306這個端口,然后這個服務實際上是去訪問容器宿主機 IP 10.10.10.3 的3306端口 .同時如果想要把服務暴露出去需要做端口映射.
下面就是主要的三種容器原始網絡模式,這些模式在企業環境基本無法采用:
隨著用戶對容器的網絡要求的不斷提高,容器界涌現了很多新的網絡規范,其目的也都是幫助大家解決在使用容器時的網絡問題,現在最主流就是下面這兩個:
需要注意的是 CNM 和 CNI 并不是網絡實現而是網絡規范和網絡體系,CNM 和 CNI 關心的是網絡管理的問題.
這兩個模型全都是插件化的,用戶可以以插件的形式去插入具體的網絡實現.其中 CNM 由 Docker 公司自己提出,而 CNI 則是 Google ?的 Kubernetes 主導.
總體上說 CNM 比較不靈活,也不難么開放,但是確是 Docker 的原生網絡實現.而 CNI 則更具通用性,而且也十分的靈活.
目前主流的插件如:Calico、Weave、Mesos 基本上是對 CNI 和 CNM 兩種規范都提供支持.
CNM 是一個被 Docker 提出的規范.現在已經被 Cisco Contiv, Kuryr, Open Virtual Networking (OVN), Project Calico, VMware 和 Weave 這些公司和項目所采納.
其中 Libnetwork 是 CNM 的原生實現.它為 Docker daemon和網絡驅動程序之間提供了接口.網絡控制器負責將驅動和一個網絡進行對接.
每個驅動程序負責管理它所擁有的網絡以及為該網絡提供的各種服務,例如 IPAM 等等.由多個驅動支撐的多個網絡可以同時并存.
網絡驅動可以按提供方被劃分為原生驅動(libnetwork內置的或Docker支持的)或者遠程驅動 (第三方插件).
原生驅動包括 none, bridge, overlay 以及 MACvlan.驅動也可以被按照適用范圍被劃分為本地(單主機)的和全局的 (多主機).
Network Sandbox:容器內部的網絡棧,包含interface、路由表以及DNS等配置,可以看做基于容器網絡配置的一個隔離環境(其概念類似“network namespace”)
Endpoint:網絡接口,一端在網絡容器內,另一端在網絡內.一個 Endpoints 可以加入一個網絡.一個容器可以有多個 endpoints.
Network:一個 endpoints 的集合.該集合內的所有endpoints可以互聯互通.(其概念類似:Linux bridge、VLAN)
最后,CNM 還支持標簽(labels).Lable 是以 key-value 對定義的元數據.用戶可以通過定義 Label 這樣的元數據來自定義 libnetwork 和驅動的行為.
CNI 是由 Google 提出的一個容器網絡規范.已采納改規范的包括 Apache Mesos, Cloud Foundry, Kubernetes, Kurma 和 rkt.另外 Contiv Networking, Project Calico 和 Weave 這些項目也為 CNI 提供插件.
CNI 的規范比較小巧.它規定了一個容器runtime和網絡插件之間簡單的契約.這個契約通過JSON的語法定義了CNI插件所需要提供的輸入和輸出.
一個容器可以被加入到被不同插件所驅動的多個網絡之中.一個網絡有自己對應的插件和唯一的名稱.
CNI 插件需要提供兩個命令:一個用來將網絡接口加入到指定網絡,另一個用來將其移除.這兩個接口分別在容器被創建和銷毀的時候被調用.
在使用 CNI 接口時容器 runtime 首先需要分配一個網絡命名空間以及一個容器ID.然后連同一些 CNI 配置參數傳給網絡驅動.接著網絡驅動會將該容器連接到網絡并將分配的 IP 地址以 JSON 的格式返回給容器 runtime.
Mesos 是最新的加入 CNI 支持的項目.Cloud Foundry 的支持也正在開發中.當前的 Mesos 網絡使用宿主機模式,也就是說容器共享了宿主機的 IP 地址.
Mesos 正在嘗試為每個容器提供一個自己的 IP 地址.這樣做的目的是使得IT人員可以自行選擇適合自己的組網方式.
目前,CNI 的功能涵蓋了 IPAM, L2 和 L3.端口映射(L4)則由容器 runtime 自己負責.CNI 也沒有規定端口映射的規則.這樣比較簡化的設計對于 Mesos 來講有些問題.端口映射是其中之一.
另外一個問題是:當 CNI 的配置被改變時,容器的行為在規范中是沒有定義的.為此,Mesos在 CNI agent 重啟的時候,會使用該容器與 CNI 關聯的配置.
說完了網絡規范,我們下面談一下 Rancher 是怎么利用 CNI 規范完成容器環境下的 overlay 網絡實現.眾所周知,網絡是容器云平臺中很重要的一環,對于不同的規模、不同的安全要求,會有不同的選型.
Rancher 的默認網絡目前完成了代碼重構,完全支持 CNI 標準,同時也會支持其他第三方 CNI 插件,結合Rancher獨有的 Environment Template 功能,用戶可以在一個大集群中的每個隔離環境內,創建不同的網絡模式,以滿足各種業務場景需求,這種管理的靈活性是其他平臺沒有的.
至于 Rancher 為什么會選擇 CNI 標準,最開始 Rancher 也是基于 CNM 進行了開發,但隨著開發的深入,我們不得不轉向了 CNI,個中原因在本次交流中我們就不做詳細說(tu)明(cao)了,
大家如果有興趣可以參閱:http://blog.kubernetes.io/2016/01/why-Kubernetes-doesnt-use-libnetwork.html
在之前的 Rancher 版本上,用戶時常抱怨 Rancher 的網絡只有 IPsec,沒有其他選擇.而容器社區的發展是十分迅猛的,各種容器網絡插件風起云涌.
在 Rancher v1.2 之后 Rancher ?全面支持了 CNI 標準,除在容器網絡中實現 IPsec 之外又實現了呼聲比較高的 VXLAN 網絡,同時增加了 CNI 插件管理機制,讓用戶可以 hacking 接入其他第三方 CNI 插件.隨后將和大家一起解讀一下 Rancher 網絡的實現.
以最簡單最快速方式部署 Rancher 并添加 Host,以默認的 IPsec 網絡部署一個簡單的應用后,進入應用容器內部看一看網絡情況,對比一下之前的 Rancher 版本:
最直觀的感受便是,網卡名從 eth0 到 eth0@if8 有了變化,原先網卡多 IP 的實現也去掉了,變成了單純的 IPsec 網絡 IP.
這其實就引來了我們要探討的內容,雖然網絡實現還是 IPsec,但是 rancher-net 組件實際上是已經基于 CNI 標準了.最直接的證明就是看一下,rancher-net 鏡像的 Dockerfile:
熟悉 CNI 規范的伙伴都知道 /opt/cni/bin 目錄是CNI的插件目錄,bridge 和 loopback 也是 CNI 的默認插件,這里的 rancher-bridge 實際上和 CNI 原生的 bridge 沒有太大差別,只是在冪等性健壯性上做了增強.
而在 IPAM 也就是 IP 地址管理上,Rancher 實現了一個自己的 rancher-cni-ipam,它的實現非常簡單,就是通過訪問 rancher-metadata 來獲取系統給容器分配的 IP.
Rancher 實際上Fork了CNI的代碼并做了這些修改,https://github.com/rancher/cni.?這樣看來實際上,rancher-net?的 IPsec 和 Vxlan 網絡其實就是基于 CNI 的 bridge 基礎上實現的.
在解釋 rancher-net 怎么和 CNI 融合之前,我們需要了解一下 CNI bridge 模式是怎么工作的.
舉個例子,假設有兩個容器 nginx 和 mysql,每個容器都有自己的 eth0,由于每個容器都是在各自的 namespace 里面.
所以互相之間是無法通信的,這就需要在外部構建一個 bridge 來做二層轉發,容器內的 eth0 和外部連接在容器上的虛擬網卡構建成對的veth設備,這樣容器之間就可以通信了.
其實無論是 docker 的 bridge 還是 cni 的 bridge,這部分工作原理是差不多的,如圖所示:
那么我們都知道 CNI 網絡在創建時需要有一個配置,這個配置用來定義CNI網絡模式,讀取哪個 CNI 插件.
在這個場景下也就是 cni bridge 的信息,這個信息 rancher 是通過 rancher-compose 傳入 metadata 來控制的.
查看 ipsec 服務的 rancher-compose.yml 可以看到,type 使用 rancher-bridge,ipam 使用 rancher-cni-ipam,bridge 網橋則復用了 docker0,有了這個配置我們甚至可以隨意定義 ipsec 網絡的 CIDR,如下圖所示:
ipsec 服務實際上有兩個容器:一個是 ipsec 主容器,內部包含rancher-net服務和ipsec需要的charon服務;
另一個 sidekick 容器是 cni-driver,它來控制 cni bridge 的構建.
兩端主機通過 IPsec 隧道網絡通信時,數據包到達物理網卡時,需要通過 Host 內的 Iptables 規則轉發到 ipsec 容器內,這個 Iptables 規則管理則是由 network-manager 組件來完成的,https://github.com/rancher/plugin-manager.其原理如下圖所示(以?IPsec 為例):
整體上看 cni ipsec 的實現比之前的 ipsec 精進了不少,而且也做了大量的解耦工作,不單純是走向社區的標準,之前大量的 Iptables 規則也有了很大的減少,性能上其實也有了很大提升.
那么 rancher-net 的另外一個 backend vxlan 又是如何實現的呢?我們需要創建一套VXLAN網絡環境來一探究竟,默認的 Cattle 引擎網絡是 IPsec,如果修改成 VXLAN 有很多種方式,可以參考我下面使用的方式.
首先,創建一個新的 Environment Template,把 Rancher IPsec 禁用,同時開啟 Rancher VXLAN,如下圖所示:
然后,我們創建一個新的 ENV,并使用剛才創建的模版 Cattle-VXLAN,創建完成后,添加 Host 即可使用.如下圖所示:
以分析 IPsec 網絡實現方式來分析 VXLAN,基本上會發現其原理大致相同.同樣是基于 CNI bridge,使用 rancher 提供的 rancher-cni-bridge 、rancher-cni-ipam,網絡配置信息以 metadata 方式注入.
區別就在于 rancher-net 容器內部,rancher-net 激活的是 vxlan driver,它會生成一個 vtep1042 設備,并開啟 udp 4789 端口,這個設備基于 udp 4789 構建 vxlan overlay 的兩端通信,對于本機的容器通過 eth0 走 bridge 通信,對于其他Host的容器,則是通過路由規則轉發到 vtep1042 設備上,再通過 overlay 到對端主機,由對端主機的 bridge 轉發到相應的容器上.整個過程如圖所示:
為什么需要扁平網絡,因為容器目前主流的提供的都是 Overlay 網絡,這個模式的好處是,靈活、容易部署、可以屏蔽網絡對應用部署的阻礙.
但是對很多用戶而言,這樣也帶來了額外的網絡開銷,網絡管理不可以控制,以及無法與現有 SDN 網絡進行對接.
在實現扁平網絡后,容器可以直接分配業務 IP,這樣訪問容器上的應用就類似訪問 VM 里的應用一樣,可以直接通過路由直達,不需要進行 NAT 映射.但扁平網絡帶來的問題是,會消耗大量的業務段 IP 地址,同時網絡廣播也會增多.
在 Rancher 環境中實現扁平網絡需要使用自定義的 bridge,同時這個 bridge 與 docker0 并沒有直接關系.
我們可以給容器添加新的網橋 mybridge,并把容器通過 veth 對連接到網橋上 mybridge 上,如果要實現容器訪問宿主機的 VM 上的服務可以將虛擬機配置的IP也配置到網橋上.
進行如上配置后,容器就可以實現 IP 之間路由直接訪問.此圖中的 vboxnet bridge 可以看做是用戶環境的上聯交互機.
在VM和物理機的混合場景,所采用的方法也很類型,這邊就不再多做解釋了.
Rancher CNI 網絡環境實現扁平網絡的工作流如下:
在實現容器扁平網絡的基本配置后,就需要考慮和 Rancher 的集成,Rancher 的 Network-plugin 的啟動依賴于 Metadata,而 Metadata 和 DNS server 均使用 docker0 的 bridge 網絡(IP為169.254.169.250).
即用戶配置的扁平網絡要能夠訪問到 docker0 網絡,否則 Rancher 提供的服務發現與注冊以及其它為業務層提供的服務將不可用.目前主要方法如下圖所示:
具體轉發規則對應的 ebtables 規則如下所示:
Drop?All?traffic?from?veth-cni?except: IP?response?from?169.254.169.250 ARP?response?from?10.43.0.2 ebtables?-t?broute?-A?BROUTING?-i?veth-cni?-j?DROP ebtables?-t?broute?-I?BROUTING?-i?veth-cni?-p?ipv4?--ip-source?169.254.169.250?-j?ACCEPT ebtables?-t?broute?-I?BROUTING?-i?veth-cni?-p?arp?--arp-opcode?2?--arp-ip-src?10.43.0.2?-j?ACCEPT Drop?ARP?request?for?10.43.0.2?on?eth1 ebtables?-t?nat?-D?POSTROUTING?-p?arp?--arp-opcode?1?--arp-ip-dst?10.43.0.2??-o?eth1?-j?DROP
另外也可以在容器所在的主機上將 Docker0 的 bridge 和 CNI 的 bridge 做三層打通,并使用 iptables 來進行控制,目前這個方式還在測試中.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4337.html