.Net 大戶的選擇:Windows Container 在攜程的應用

攜程開始了對 Windows container 的調研工作,目前已經有一些成果和實際應用案例,與大家分享一下,主要內容有:

  • 攜程為什麼要使用 Windows container (可能國內大部分的人瞭解 Windows container 少一些,特別是具體的實踐,分享重點會偏 Windows container 細節)
  • 傳統.Net 應用容器化實踐
  • 容器存儲&網絡&編排

攜程為什麼要做 Windows container ?

現狀:

  • 攜程是.Net 應用大戶,由技術棧決定的,早期攜程整個應用架構都放在該平臺上,線上跑了 3000 多個核心應用,覆蓋了 20 多個 BU (業務部門),這讓我們不得不關注這一龐大的系統。
  • 平臺要往 java 方面轉,去分享 java 的紅利,但是.Net 線上應用不可能都重寫;
  • .Net 的應用目前 90%左右的應用都跑在虛擬機上,從虛擬機自身來看,粒度太粗,對資源的使用率還不是很好。
  • 持續發佈,應用上線,從拿到機器環境準備好環境上線生產,虛擬機模式下週期長,擴容慢。

新一代發佈平臺的需求,希望縮短環境準備時間,做到秒級部署, Linux 平臺的應用非常容易做到,但是 Windows .Net 應用在這方面支持比較難,另外,為了確保生產和測試環境高度一致,希望應用發佈是單一應用、單一鏡像的,最好是一個容器儘量少的包含系統進程,這樣可以把資源隔離的粒度控制在小範圍內,儘量榨取宿主機的資源,同時希望 Linux 容器和 Windows 容器的方案儘可能接近,比如網絡、存儲,不需要兩套不一樣的方案或是有大的有變化。

一些 Windows container 的技術細節

最開始的時候攜程用物理機部署應用,為了保證互不衝突,用戶在一個物理機上只部署一個應用。後來認為此舉太浪費,就部署了多個應用,但是為管理帶來了麻煩,應用之間有一定的衝突或者相互影響。之後有了虛擬機,虛擬機上可以部署更多的應用,而且隔離比較好,不過虛擬機資源隔離的粒度太粗了,於是容器走了過來,能做到把一個應用打到包裡,這個包涵蓋了環境配置等, run 起來可以只是一個進程,又具備一定的隔離性,同時把資源使用的粒度控制足夠的細。

.Net 大戶的選擇:Windows Container 在攜程的應用

Windows container 目前支持的系統是 Windows server 2016 ,這個版本是去年 10 月份正式發佈的(攜程是國內比較早的一批拿到了他們的 RTM 版本),支持兩類 server ,一類是 server core ,另一類是 nano server 。 nano server 是微軟比較推薦的一類服務器系統,啟動非常快,可以大幅度縮短計劃內維護宕機時間,通常幾秒鐘就起來了,不包含硬件檢測的時間,幾十秒都能夠起來。這塊攜程還沒有用於生產環境,目前只測試了用 server core 作為容器宿主機的系統的情況。需要著重提一下的是,如果宿主機打了補丁或者升級,容器也要對應的做補丁或者升級。當然不一定說立馬做補丁升級,但一定要比較精確的找到對應的版本做升級。

.Net 大戶的選擇:Windows Container 在攜程的應用

Windows container 有兩種 container 類型,這兩種容器都是跑到 Windows servrer 2016 的,但還有一種容器的玩法是在 Liunx 平臺跑.Net core ,這種方案我們也看過,大家很容易想到它的侷限,其實只能跑到用.Net 技術開發的 Windows 的應用,一些非.Net 的應用不支持,因此這個方案被 Pass 了。直接在 Windows server 跑容器的方案更為靠譜,該方案有兩種類型, Windows server 和 hyper - v container 。

.Net 大戶的選擇:Windows Container 在攜程的應用

有人會問, hyper-v 不就是一個虛擬機的技術嗎?對,其實它有點像虛擬機,但是 hyper - v 的技術略有不同,速度會明顯比虛擬機快很多,只是在申請資源或者獲取資源時,比 Windows server Container 的速度稍稍慢一點點, Windows server container 可能 3 秒,它可能 4 、 5 秒。但是資源的隔離度比較好一些,類似於虛擬機,微軟公有云 Azure 的容器服務也是採取這種容器類型,他們的考慮是公有云上面部署的應用不是受信任的,相互之間有可能“打架”的情況發生,他想隔離好一些。

.Net 大戶的選擇:Windows Container 在攜程的應用

另一個區別, Windows server Container 的內核是共享的,可以在宿主機上看到每個容器裡面的進程,這與 Linux 容器相似,可以直接 kill 掉。 hyper-v container 宿主機是看不見容器內進程的,像一個虛擬機一樣。此外,內存資源隔離不同, Windows server Container 內存可以 share , hyper-v container 不能 share , hyper-v container 一旦分配就不能重新進行修改。對系統應用是信任的,這種比較適合做私有云的一些產品,因為在應用上跑的什麼東西,這個應用能幹什麼壞事或者是相互之間有沒有影響,都可以控制,但是公有云不能這樣做,應用使用率很高,會把別的容器影響到。啟動速度上也會有差別,一個啟動快,一個啟動慢一點,當然並不是特別慢。

.Net 大戶的選擇:Windows Container 在攜程的應用

容器鏡像,這個和 Linux 容器的鏡像類似,可以分層。最下面一層是基礎鏡像,但是基礎鏡像和 Linux 有區別。 Linux 鏡像可以自己搞,弄一個系統把它做成鏡像,但是微軟沒有辦法自己做一個 Windows container base 鏡像。或者說現在只是 Windows server 2016 的鏡像,想跑一個 2012 的系統是不行的。當前系統內核只能支持 win10 ,在上面可以繼續安裝想要的東西,比如接著安裝 Framework ,然後在最上面裝應用。

.Net 大戶的選擇:Windows Container 在攜程的應用

鏡像構建也是一樣, Windows container 容器和 Docker 集成比較好,可以用 Docker 工具的一些命令進行 build ,用 Dockerfile 來 Build 一個鏡像。 registry 是鏡像可以直接 push 到一個平臺或者是私有的 registry 上面去,通過 Docker pull 方式拉下來, Docker run 跑起來。

.Net 大戶的選擇:Windows Container 在攜程的應用

Windows container 的鏡像,可以在 Docker 網站上可以找到關於 Windows container 的一些 base image, pull 下來大概有 8G 左右,在外網上下載可能要兩天。大家可以嘗試一下。也可以建私有的 registry ,攜程採用的 VMware 開源的 Harbor 方案,本身沒有做太多的修改,直接可以用。和攜程的 AD 整合以後基本上能用了, registry 可以把 Linux 和 Windows 的鏡像都放在一起,兩邊都能用,都能管,這部分省掉了很多的內容,不需要做額外的開發,這樣 Windows 和 Linux 的平臺的 image 管理方案是一致的。

傳統.Net 應用遷移

遷移背景:

之前提到攜程有 3000 多個.Net 應用,這些應用每天要不停的發佈、測試、編譯打包,是一項很大的繁瑣工程,有個叫“ build ”的項目負責這個事情。最初這些跑在虛擬機裡,資源使用率很低,白天很忙,晚上使用率很低,有一定的資源浪費,且構建環境也經常不一致。為了積攢容器應用使用的經驗,我們考慮把 build 項目先容器化,也就意味著.Net 應用自己的編譯在容器裡面編譯,看能撞出來什麼樣的火花。

原來寫幾千個應用的編譯腳本,如果改了一些東西,變更維護的代價是非常大的,儘量這個方案不要用到原來以往用的工具和使用方式,不去動它,最好能夠拿過來不怎麼修改,就跑起來。另外,重點看一下像 vs2010 和 vs201 這樣的工具能不能在容器裡跑,實踐證明是可以的。然後看 MSBuild 在容器裡面是否兼容,支持不同的.Net Framework 版本,這些都是比較通用的軟件,結果是這些功能都能夠支持,另外也包括 python 、 MVC 、 GIT 等等。

遷移收益

  • 首先環境,編譯的環境高度一致,每個環境沒有太多的區別,容器拉起來直接跑,提高了編譯成功率。
  • 其次資源利用率提高了,我們把虛擬機資源砍掉了一半,就只需要兩臺宿機機搞定整個攜程 3000 多個.Net 應用的編譯。
  • 編譯時長也縮短了,原來用一次構建平均要幾分鐘,現在 90 秒左右基本上能構建完成。
.Net 大戶的選擇:Windows Container 在攜程的應用

待解決的問題:

  • 圖形不支持,這個是某些企業想用 Windows container 的大問題,它本身圖形不支持。後臺程序沒有太大問題,不過有一些依賴圖像工具比較難支持。
  • 舊應用兼容不是很好。比如遇到 MGwin 編譯出來的包,一旦代碼中有調用標準輸出的語句程序直接就掛了,遇到這類問題,需要把源碼拉下來重新編譯,比較有難度。
  • 不支持 RDP ,遠程桌面是不能用的,那怎麼做到遠程訪問呢? 還好 Windows 現在支持 SSHD 安裝了,只需要容器內裝一個 SSHD ,然後遠程 SSH 去,當然可以用 powershell 遠程的登錄方式,兩種方案都可以用, SSH 方案更統一一些, 如果用戶當前正在 Linux 平臺上工作,突然想登一個 Windows 的容器怎麼辦?當然也可以用 linux 平臺的 powershell 工具實現遠程登陸容器。
  • 不支持 D 盤。攜程遷移過來很多老的應用是要裝在 D 盤的,容器拉起來沒有 D 盤,只有一個 C 盤。本身 Docker 有一個 volume 功能,可以掛一個數據的盤,問題是這樣會導致在宿主機上留下一些東西,和宿主機產生耦合,如果容器刪除或者遷移,宿主機上就留下了髒數據。後來我們為 D 盤做一個 link ,相當於 D 盤可以快捷的方式連到 C 盤,映射到 C 盤的某個目錄,這樣數據都是落地到在容器的磁盤上,如果想在別的地方拉起來這個容器,可以直接 push register ,就可以在別的地方部署且環境一樣。

存儲&網絡&編排

接下來 Windows container 容器的存儲,網絡,編排方面的技術與大家分享一下。

Windows container 資源的隔離方式和配置管理 API 是借用 Docker 規範,設計理念和 Linux Container 類似,也支持 CPU share 的這種方式去控制資源的分配。內存可以通過 quota 的方式去分配內存, Disk 也能夠充分應用到 IO 的帶寬,這一塊還沒有做非常多嚴格的測試。關於網絡的支持,攜程做了很多測試,整體來講比較不錯,問題較少。性能也滿足需求,多個容器在一個同一個宿主機上也能儘量用到整個宿主機的帶寬。

容器的存儲

.Net 大戶的選擇:Windows Container 在攜程的應用

存儲有三種:一種是鏡像,鏡像本身是一個存儲,設計之初定義就不是一個永久的存儲,當前容器存儲拉掉那個存儲就沒有了,也不是設計安全的。另外一種存儲是 volume (卷) ,可以掛一個數據盤到某一個容器上,在容器裡擴展存儲空間。同時多個容器也可以掛載宿主機上的一個同一個 volume (卷目錄),這樣大家可以實現 NFS 一樣的效果。最後一類存儲是網絡存儲,比如可以用 SMB 的方式掛網絡盤在容器裡面使用,裡面如果有萬兆的帶寬支持還可以玩一下,如果沒有萬兆帶寬的話就不要玩了,它只能放一些冷數據。

容器的網絡

.Net 大戶的選擇:Windows Container 在攜程的應用

相對來講複雜一些, Windows 支持有四種網絡模型,第一種 NAT 模式大家比較熟悉,起一個本地或者是數據本地的 IP 地址,如果你想外網訪問的話,把 Docker 映射出來,這種方式比較適合做一個 JOB 類型的應用在上面,不需要外邊可以訪問它,但是容器裡面可以去下載東西。之前講的 build 項目就是用這個網絡模型,非常簡單,不需要考慮太多網絡的模型就可以直接用。

第二種是 transparent 網絡模型,這種模型是現在主要用於生產的模型,首先它是通過 mac 地址偽裝實現數據透傳,對網絡的性能本身折損也比較少,它也支持把多個工作網卡綁到一個交換機上,然後把這個交換機給容器用。網絡模型在容器宿主機以外的機器上看到 Windows 容器和一臺物理機沒有什麼區別。

還有一種是 L2 bridge 這種採用 openstack 網絡的 Flat 模式,所用的網絡跟宿主機的網絡是一樣的,和宿主機在同一個網段,這樣有很大的侷限性,網絡和宿主機混在一起沒有辦法做到多租戶隔離,然後網段用光了就完了,適用於比較小的集群。

最後一種是 Tunnel mode ,沒有太多研究這一種,但是微軟 Azure 用的這一種網絡模型。本身攜程為了和虛擬機的很多的品牌網絡模型一致,所以這一種沒有那麼快的推進。

hyper-v 的網絡模型

Hyper-v 宿主機是 2012 上面 hyper-v 的網絡模型,之前要求一臺宿主機儘量要 4 塊網卡,為什麼要用 4 塊網卡?兩塊給虛擬機用,另外兩塊做一些管理,比如對存儲用,虛擬機遷移等,可以做宿主機的管理。另一種方式, 2016 建議的一種網絡方式,這裡面有一個叫做 embed team ,內嵌交換機,它的好處是把下面無論是兩塊還是 N 塊網卡都可以綁在一個 bound ,然後把這個 bound 放在一個交換機裡面,每個容器 port 全部放在交換機裡面,然後容器給 port 打相應的 vlan tag ,這樣容器的網就通了。

embed team 的好處是不需要要求宿主機一定要有這麼多的網卡才可以用,另一個好處是對這些不同的 vlan 之間做一些流量的控制,攜程的 container 的網絡模型也是基於嵌入式交換機上實現的。把宿主機至少兩塊網卡做了 bound ,放在一個 embed team 裡面去,另外加一個 port 給宿主機做管理網卡。容器宿主機相比虛擬機宿主機簡單,沒有存儲和遷移的需求,就不要以額外的劃分網絡了,如果需要為容器的存儲單獨掛一個網絡的話可以加一個 Port 做這個事情。不同的網段的這種容器在上面可以再創建不同的 Docker ,加不同的 port ,然後容器在裡面可以互通,這樣的好處就是既實現了多租戶、實現了網絡隔離,同時和虛擬機包括 Linux 上面的網絡模型是一致的。

容器編排

編排這塊通常一個容器部署到多個宿主機上,同時一套應用下來有數據層、業務層、也有 web 層,這些應用要分開放,它們中間放在哪裡需要有一個地方,把整個管起來,也希望這個東西能自動化,本身做編排這些,無論是 Swarm 、 K8S 、 Mesos 都是需要解決的問題。一種方案是用 Docker compose 這種方式,適合於單宿主機管理。想編排一下容器,看如何跑,這種方式用 Docker compose 就能解決。當然,微軟現在對 Docker Swarm 支持好一些,實現成本比較低,基本上能管,但是性能方面沒有做太多的測試,目前一些基本的調度、主機分類等等都能用。

為什麼攜程選擇使用 Mesos ?

因為攜程的 Linux 平臺用的也是這套方案做的編排相關的管理,希望有一套方案能夠儘量兩種容器一致,於是我們的方案採用 Mesos 加上 Marathon 對它進行管理,本身它也有一些現成的工具,比如 UI 等現成的工具都可以用,這部分還在進行測試和研究中。官方下來的包不能直接跑到 Windows server 上面,要拿下來重新編譯才能用。最終攜程是想做到這麼簡單的一個容器的管理的架構,就是說希望 Mesos 在裡面能夠同時管 Linux 容器和 Windows 容器,對它進行統一的調度,最大限度的優化這種調度策略,提升使用率,這是最終整體的設計理念。

https://www.v2ex.com/t/335653

相關推薦

推薦中...