1. 程式人生 > >如何解決容器網路效能及複雜網路部署問題?

如何解決容器網路效能及複雜網路部署問題?

本文作者:青雲QingCloud雲基礎平臺研發總監陳海泉。

近兩年,容器已經隨著 Docker 技術的傳播火遍全球,現在已經有越來越多的企業使用者在開發、測試甚至生產環境中開始採用 Docker 等容器技術。

然而,目前主流的 Docker 管理平臺,比如 K8S,當企業想構建一套網路方案,需要精通 Linux 提供的各種高階網路功能,這個技術門檻太高了。特別是對專注於業務開發的 Docker 使用者而言,這類操作往往顯得過於複雜。

而且,由於在虛機中部署容器,雲平臺和 Docker 平臺都有自己的虛擬化網路實現方案,二者功能重疊,使用時會相互巢狀,導致的其網路效能損耗非常嚴重,甚至達到 80%。

所以,雖然容器技術正在逐步被大家認可與應用,但其網路效能以及配置的複雜程度一直都在被大家所詬病。今天的內容,將會給大家介紹一種容器部署方案,幫助大家解決網路這個難題。

Docker的網路模型架構

首先,我們先看看 Docker 提供了哪些網路功能,Docker 的網路模型是這樣的:

圖片描述

Docker 的網路結構分為 3 個層次:Network、Endpoint 和 Container。對比到物理裝置可以這麼理解:Network 是交換機,Endpoint 是網絡卡,Container 就是伺服器。

決定 Network 這個交換機的工作方式的元件,就是 Network Driver。常用的 Driver 有兩個:

  • Bridge
  • Overlay

Bridge Driver

Bridge Driver 是種比較直接的方式:Bridge 指的是 Linux Kernel 實現的虛機交換機。每個網路在宿主機上有一個 Bridge 例項,預設是 Docker0,有對應的 IP 地址和網段,每個 Docker 例項從網段裡面分配一個地址。結構如下:

圖片描述

在同一個 Bridge 下的 Endpoint 是一個二層網路,要實現跨宿主機的 Endpoint 之間通訊,只能走三層網路,也就是通過路由轉發過去。要對外提供服務,還需要對宿主機的 IP 埠做轉換(Nat)。這種情況下主要網路效能損失發生在埠轉換(Nat)和路由上面。

同時這也和青雲 SDN 1.0 裡面的基礎網路實現方式是完全一樣,優點是結構簡單可靠,缺點也很明顯: 不能把多個宿主機連成一個二層網路。這個問題會導致 Docker 例項的 IP 地址,必須跟當前宿主機定義的網段一致。如果啟動到別的宿主機上,IP 就需要更換。

Overlay Driver

Overlay Driver 的作用是把位於多個宿主機的 Docker 例項連線在一個虛擬的二層網路裡面。相比 Bridge,在功能上有一定進步,本質上是一個分散式的虛擬交換機。

舉個送快遞的例子,方便大家理解:有的公司對員工提供內部郵件的服務,位於不同寫字樓的員工可以用工位號互發郵件。公司的收發室拿到郵件後,會重新再打個包,上面寫著雙方寫字樓的地址,交給真正的快遞公司去投遞。收件方的收發室會拿到郵件後,會拆掉外面的信封,把裡面的郵件按工位號送給收件的員工。

這例子裡面,工位號就是 Underlay 的地址, 寫字樓的地址是 Overlay 的地址。Docker 的這個虛擬二層網路,就是企業內部郵件,但是真正派件的還是快遞公司。跟普通快遞相比,多了個環節:收發室對郵件重新包裝,不僅打包費時間,多的包裝也佔了重量,也就帶來了額外的效能損失。

目前,Overlay 模式的虛擬網路應用已經很普遍,青雲給使用者提供的虛擬二層網路也是相同的工作原理。

容器的部署方式

Docker 目前有兩種方式部署:

  • 私有環境物理機部署
  • 公有云虛擬機器部署

今天和大家分享的就是為什麼要在雲平臺上部署 Docker。

雖然看起來在公有云的虛擬機器部署 Docker 的做法比較奇葩,目前也沒有公有云能讓使用者直接部署 Docker 在物理機上,當然,Softlayer 這種物理機託管的雲除外。

因為 Docker 本身的安全性還不夠讓人放心。雖然 Docker 已經有各種安全保護,包括 Namespace 提供的隔離機制、Selinux、Apparmor 等安全機制,以及最近才有的Unprivileged Container 功能來控制 Docker 例項在宿主機上的使用者許可權,但是由於容器的本質是跟宿主機共用同一個 Linux Kernel,一旦 Kernel 本身有安全漏洞,就有可能被 Docker 使用者利用,侵入到雲平臺的物理機。

比如幾個月前發現的 COW 漏洞,就有可能讓 Docker 例項獲得物理機的 Root 許可權,實現容器的“越獄”。這個漏洞存在了十幾年才被人發現,完全有可能還有很多類似漏洞存在,只是沒有被公開而已。

所以,公有云直接讓使用者在多租戶的物理機上執行 Docker,是極不安全的做法。

因此,要在公有云使用 Docker,就只有在虛擬機器裡面執行 Docker 這一個選擇。那麼在公有云上部署 Docker 業務,存在哪些問題呢?其實,主要還是效能和功能兩方面。

網路效能

網路虛擬化的本質是用軟體實現物理網絡卡和交換機的功能,因此虛擬網路中的所有流量都會消耗 CPU 資源。

Linux 在處理網路流量時,有幾個方面會消耗 CPU:

  1. 地址轉換(Nat);
  2. 三層路由轉發;
  3. Vxlan 封裝;
  4. 二層轉發;
  5. 虛擬機器的 Kernel 和宿主機 Kernel 之間的轉發。

其中 1 和 2 佔的 CPU 消耗較高,這是因為地址轉換和路由都會對資料包的包頭做修改,並重新計算 Checksum, 而且地址轉換還需要查詢 Conntrack 的連線表和 IPtables 的地址轉換規則,這些功能都是全靠宿主機的 CPU 完成。

雲平臺提供的 SDN 網路,是第一層網路虛擬化,已造成一定的效能損失。但是可以通過利用物理網絡卡的硬解除安裝功能,比如 Vxlan Offload, 具體包括 Gso、Gro、Rx Checksum 等在這一層減少虛擬化帶來的部分效能損失。

雖然容器本身由於跟宿主機共享 Kernel 的這個特性,相比 VM 網路效能更好,沒有 第 5 條的損失,但是 Docker 搭建的虛擬網路,仍然會帶來顯著的效能損失。

同時,由於第二層虛擬化無法利用硬解除安裝功能,所以效能損失通常會高於第一層。兩層網路虛擬化帶來的效能損耗相疊加,將顯著影響網路效能。

舉個例子:

在上海一區(SH1A),使用 IPerf -C 命令進行的基本效能測試 (關閉雲平臺的網路限速)結果如下:
虛擬主機之間:頻寬 9Gbps;
虛擬主機內:使用 Docker Overlay 外掛的 Docker 例項之間頻寬下降為 2.3 Gbps。

由此可見,這種使用 Docker Overlay 的方案會帶來近 3/4 的效能損耗。而如果算上對外提供服務所需要的地址轉換帶來的效能損失,整體效能損失將更為巨大。

配置複雜

首先,Docker 自身的網路複雜。Bridge 和 Overlay 都需要配合地址轉換功能使用,而地址轉換的規則不僅多,而且複雜。

我最近遇到個私有云客戶,其在雲平臺上面部署基於 K8S 的業務系統。他們遇到一個問題,同一個宿主機的 Docker 例項之間,用 K8S 提供的業務 IP 無法訪問,而不同宿主機之間用相同的 IP 訪問正常。

這個開發團隊,通宵加班好幾天,也沒搞清楚怎麼回事,來找我幫忙解決。這個問題實際上是因為 K8S 少下發了一條 IPtables 規則,沒有對同宿主機的這種情況做源地址轉換。

這個問題對熟悉 Linux 網路功能的人來說,不是什麼難題,但是對專注於業務開發的 Docker 使用者而言,可就很難解決了。

我說這個例子的目地就是要說明,配置 Docker 虛擬網路是件難度很高的事情。

另一方面,要在雲平臺上面,使用 Docker 對外提供服務,還需要跟雲平臺的網路做整合。

通常是在雲平臺的 IP 和 Docker 的 IP 之間做地址轉換。本身 Docker 實現這些功能就比較複雜,而在此基礎上,再做一層地址轉換,會帶來額外的複雜度。

使用 Docker 管理平臺的初衷是簡化產品部署,而通過這樣的方式跟雲平臺整合,卻與這一方向背道而馳。

如何解決容器網路效能及複雜網路部署的問題

效能問題的根源在於雲平臺和 Docker 平臺都有自己的虛擬化網路,二者功能重疊,使用時相互巢狀。而配置複雜的難度一個是 Docker 自身網路複雜,另一個方面是跟雲平臺的網路整合也複雜。

目前青雲的 SDN 直通方案通過讓 Docker 例項掛載雲平臺提供的虛擬網絡卡的方式,讓 Docker 例項直接使用雲平臺的 SDN 功能,代替 Docker 的虛擬網路。

一方面減少了第二層虛擬網路的效能損失;另一方面,雲平臺的 SDN 是通過 API 和控制檯封裝好的服務,Docker 直接使用就可以了,不需要自己再配置 Docker 的網路,所以大幅降低了使用難度。

SDN 網路直通方案包含兩個方面:

  • 雲平臺網絡卡管理:通過提供網絡卡介面,讓虛擬主機能夠掛載多個網絡卡。這些網絡卡可以屬於相同或者不同的網路,同時每個網絡卡能夠管理自己的私網 IP、公網 IP、負載均衡器和防火牆等功能。
  • 外掛:這是青雲Qingcloud 自主開發的一款 Docker 網路外掛。在啟動 Docker 例項的時候,通過該外掛,可以將虛擬主機上的繫結的多個網絡卡一一掛載到 Docker 例項上, 並可以配置 IP 地址和路由。啟動之後,Docker 例項就加入了雲平臺 SDN 提供的網路,能夠使用雲平臺所有的網路功能。

這是青雲Qingcloud 自主開發的一款 Docker 網路外掛。在啟動 Docker 例項的時候,通過該外掛,可以將虛擬主機上的繫結的多個網絡卡一一掛載到 Docker 例項上, 並可以配置 IP 地址和路由。

啟動之後,Docker 例項就加入了雲平臺 SDN 提供的網路,能夠使用雲平臺所有的網路功能。雲平臺網絡卡管理,就是能夠讓虛擬主機掛載多個網絡卡。網絡卡對應到 Docker 的網路元件,就是Endpoint,這個裝置受雲平臺管理,底層由 SDN 內部的控制器下發規則,可以使用 DHCP 管理 IP 地址,並接入所有云平臺的網路模組。

相比 Docker 的網路功能,青雲的網絡卡可以提供更多的功能:

VPC

前面說過,Docker 的 Overlay 網路實際上是虛擬的二層網,而 VPC 提供的是一個虛擬的三層網。可以理解為一個分散式的核心交換機。青雲的 VPC 最多可以建立 252 個虛擬網路,容納超過 6 萬臺虛擬主機。

就技術上來看,虛擬二層網使用 Vxlan 實現,是現在較成熟的技術。而虛擬的三層網,是 SDN 技術的一個關鍵點,因為它背後需要有個分散式閘道器才能做到虛擬機器數量增加時,VPC 整體網路效能不變。

目前 SDN 廠商和技術好的雲端計算公司都有各自的實現,還沒有看到靠譜的開源產品能夠做到。

當 Docker 掛載上青雲的網絡卡時,就加入了對應的 VPC,跟其他例項連在了一起。使用者可以根據網絡卡對應的網路來定義例項間是二層還是三層聯通。

公網 IP

每個網絡卡可以繫結自己獨享的公網 IP,也可以使用 VPC 共享的公網 IP 對外提供服務。公網和私網地址的轉換,由雲平臺的分散式閘道器來做,不需要 Docker 配置任何 IPtables 規則。

負載均衡器

網絡卡可以作為負載均衡器的後端,以叢集的方式,對外提供高可用和高效能的服務。相比 Docker 的負載均衡器,青雲的負載均衡器有許多優點:

  • 4層/7層全透明,後端伺服器能直接拿到客戶端的源 IP 地址。這個功能是我在青雲做的第一個專案,到目前,在雲端計算的負載均衡器服務中仍然是獨有的功能,世界上別的公有云都沒有做到。
  • 水平擴充套件能力,使用者可以通過修改叢集節點數量,擴充套件網路頻寬和 HTTPS 解除安裝能力。
  • HTTPS 轉發策略等等很多配置選項,要比 Docker 或者 K8S 實現的負載均衡器的選項豐富很多。
  • 防火牆。每個網絡卡都可以獨立配置自己的防火牆過濾規則,這個功能在 Docker 上還沒見到。

給虛擬主機掛載網絡卡之後,需要使用到 Hostnic 外掛,有 3 步:

  1. Docker-Plugin-Hostnic 是個 Docker 像,把它啟動成 Docker 例項,效果就是載入了一個叫 Hostnic 的 Docker 網路外掛;
  2. 建立 Docker 網路。比如:Docker Network Create -D Hostnic –Subnet=192.168.1.0/24 –Gateway 192.168.1.1 Hostnic,其中網段和閘道器是網絡卡在 VPC 對應的網路的屬性;
  3. 啟動 Docker 例項,傳入網絡卡對應的 Mac 和 IP 地址。比如: Docker Run -It –Ip 192.168.1.5 –Mac-Address 52:54:0E:E5:00:F7 –Network Hostnic Ubuntu:14.04 Bash。

這樣就完成了對 Docker 例項網路的所有功能配置。

前面說的公網 IP、負載均衡器和防火牆,都可以通過青雲控制檯、SDK、 CLI 或者 API 的方式去單獨配置。對這些功能使用上有疑問的話,可以通過工單跟我們的工程師溝通,不必在死磕 Docker 那些複雜的網路配置。

除了青雲自己研發的 Hostnic,現在已經有另外一款 Docker 外掛支援青雲 SDN 直通。是希雲Csphere 開發的 Qingcloud-Docker-Network,同樣也已經開源: Https://Github.Com/Nicescale/Qingcloud-Docker-Network

跟 Hostnic 相比,這款外掛整合了青雲 API,能夠在啟動 Docker 例項時,自動建立,並繫結網絡卡,使用起來更方便一些。

對於公有云,目前只能選擇在虛擬主機裡面使用 Docker,但是對於私有云,可以在青雲提供的容器主機裡面部署 Docker。

容器主機的工作原理跟 Docker 一樣,都是用到了 Linux Kernel 的容器技術,但是用起來更接近虛擬主機,有著幾乎相同的功能,比如:掛載 SSH 金鑰、Web Terminal、映象製作、備份等功能,跟虛擬主機映象全相容,還能做到線上擴容 CPU、記憶體、系統硬碟。

也就是說,對於私有云使用者,可以使用跟公有云虛擬主機完全一樣的操作方式,在容器主機裡面部署 Docker,從而減少 KVM 虛擬化這一層在效能上的損失,能達到接近物理機的效能。

跟直接在物理機上部署 Docker 相比,使用容器主機可以有云平臺便捷的功能,比如秒級建立或者消毀一個容器主機。雲平臺的副本可以保證物理機宕機後,通過離線遷移,迅速恢復業務。再加上前面說的這些雲平臺的網路功能,為構建使用者業務叢集,節省大量時間。同時青雲的 SDN 網路在 Linux Kernel 上有深度優化,相比直接在物理機上使用 Docker 的 Overlay 網路效能還會好不少。

由CSDN主辦的中國雲端計算技術大會(CCTC 2017)將於5月18-19日在北京召開,Spark、Container、區塊鏈、大資料四大主題峰會震撼襲來,包括Mesosphere CTO Tobi Knaup,Rancher labs 創始人樑勝、Databricks 工程師 Spark commiter 範文臣等近60位技術大牛齊聚京城,為雲端計算、大資料以及人工智慧領域開發者帶來一場技術的盛大Party。現在報名,只需399元就可以聆聽近60場的頂級技術專家分享,還等什麼,登陸官網,趕快報名吧!

圖片描述