.Net大户的选择:Windows Container在携程的应用
羅勇,攜程云平臺開發經理
主要負責攜程云平臺建設和維護,熟悉OpenStack,Docker ,Linux/Windows Container 等技術領域
今天的主題是Windows容器。今年下半年攜程開始了對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起來可以只是一個進程,又具備一定的隔離性,同時把資源使用的粒度控制足夠的細。
Windows container目前支持的系統是Windows server 2016,這個版本是去年10月份正式發布的(攜程是國內比較早的一批拿到了他們的RTM版本),支持兩類server ,一類是server core,另一類是nano server 。 nano server是微軟比較推薦的一類服務器系統,啟動非常快,可以大幅度縮短計劃內維護宕機時間,通常幾秒鐘就起來了,不包含硬件檢測的時間,幾十秒都能夠起來。這塊攜程還沒有用于生產環境,目前只測試了用server core作為容器宿主機的系統的情況。需要著重提一下的是,如果宿主機打了補丁或者升級,容器也要對應的做補丁或者升級。當然不一定說立馬做補丁升級,但一定要比較精確的找到對應的版本做升級。
Windows container有兩種container類型,這兩種容器都是跑到Windows servrer 2016的,但還有一種容器的玩法是在Liunx平臺跑.Net core,這種方案我們也看過,大家很容易想到它的局限,其實只能跑到用.Net 技術開發的Windows的應用,一些非.Net的應用不支持,因此這個方案被Pass了。直接在Windows server跑容器的方案更為靠譜,該方案有兩種類型,Windows server和hyper-v container 。
有人會問,hyper-v不就是一個虛擬機的技術嗎?對,其實它有點像虛擬機,但是hyper-v的技術略有不同,速度會明顯比虛擬機快很多,只是在申請資源或者獲取資源時,比Windows server Container的速度稍稍慢一點點,Windows server container可能3秒,它可能4、5秒。但是資源的隔離度比較好一些,類似于虛擬機,微軟公有云 Azure的容器服務也是采取這種容器類型,他們的考慮是公有云上面部署的應用不是受信任的,相互之間有可能“打架”的情況發生,他想隔離好一些。
另一個區別,Windows server Container的內核是共享的,可以在宿主機上看到每個容器里面的進程,這與Linux容器相似,可以直接kill掉。hyper-v container宿主機是看不見容器內進程的,像一個虛擬機一樣。此外,內存資源隔離不同,Windows server Container內存可以share,hyper-v container不能share,hyper-v container一旦分配就不能重新進行修改。對系統應用是信任的,這種比較適合做私有云的一些產品,因為在應用上跑的什么東西,這個應用能干什么壞事或者是相互之間有沒有影響,都可以控制,但是公有云不能這樣做,應用使用率很高,會把別的容器影響到。啟動速度上也會有差別,一個啟動快,一個啟動慢一點,當然并不是特別慢。
容器鏡像,這個和Linux容器的鏡像類似,可以分層。最下面一層是基礎鏡像,但是基礎鏡像和Linux有區別。Linux鏡像可以自己搞,弄一個系統把它做成鏡像,但是微軟沒有辦法自己做一個Windows container base鏡像。或者說現在只是Windows server 2016的鏡像,想跑一個2012的系統是不行的。當前系統內核只能支持win10,在上面可以繼續安裝想要的東西,比如接著安裝Framework,然后在最上面裝應用。
鏡像構建也是一樣,Windows container容器和Docker集成比較好,可以用Docker工具的一些命令進行build,用Dockerfile來Build一個鏡像。registry是鏡像可以直接push到一個平臺或者是私有的registry上面去,通過Docker pull方式拉下來,Docker run跑起來。
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秒左右基本上能構建完成。
待解決的問題:
?圖形不支持,這個是某些企業想用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的帶寬,這一塊還沒有做非常多嚴格的測試。關于網絡的支持,攜程做了很多測試,整體來講比較不錯,問題較少。性能也滿足需求,多個容器在一個同一個宿主機上也能盡量用到整個宿主機的帶寬。?
容器的存儲
存儲有三種:一種是鏡像,鏡像本身是一個存儲,設計之初定義就不是一個永久的存儲,當前容器存儲拉掉那個存儲就沒有了,也不是設計安全的。另外一種存儲是volume(卷) ,可以掛一個數據盤到某一個容器上,在容器里擴展存儲空間。同時多個容器也可以掛載宿主機上的一個同一個volume(卷目錄),這樣大家可以實現NFS一樣的效果。最后一類存儲是網絡存儲,比如可以用SMB的方式掛網絡盤在容器里面使用,里面如果有萬兆的帶寬支持還可以玩一下,如果沒有萬兆帶寬的話就不要玩了,它只能放一些冷數據。
容器的網絡
相對來講復雜一些,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容器,對它進行統一的調度,最大限度的優化這種調度策略,提升使用率,這是最終整體的設計理念。
有一些急迫解決的問題,與大家交流一下。首先Windows container的鏡像比較大,在生產環境,如果批量pull base image,網絡的帶寬會很快被打滿,會對業務帶寬造成影響。我們需要有一套方案來解決這個問題, 如何能夠比較“經濟”的方式把Based image或者變更的Layer文件下發下去,是后續要解決的問題。
Windows container的監控日志,沒有現成的方案,我也有與微軟團隊交流過,這部分文檔非常少,攜程之后也會重點解決監控問題。
推行單容器、單應用的發布方式,希望后面能夠把各種FAT/UAT/Prod環境之間打通,都可以通過Windows容器方式,秒級發布。
攜程有3000多個應用,一旦容器跑起來了,宿主機的規模還是比較可觀的,這種情況下,大規模容器如何管理好?這也是后面需要解決的問題。
這是我今天給大家分享的主要的內容,謝謝大家!
活動相關閱讀:
構建與定制:唯品會PaaS基于Kubernetes的實踐
廣發銀行運維實踐分享:Docker適配傳統運維那些事
Docker在Bilibili的實戰:由痛點推動的容器化
——點擊閱讀原文下載活動PPT——
內容轉載自公眾號
數人云 了解更多總結
以上是生活随笔為你收集整理的.Net大户的选择:Windows Container在携程的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .Net Core 之 MSBuild
- 下一篇: Docker4Dev #6 使用 Win