.Net大户的选择:Windows Container在携程的应用
羅勇,攜程云平臺(tái)開發(fā)經(jīng)理
主要負(fù)責(zé)攜程云平臺(tái)建設(shè)和維護(hù),熟悉OpenStack,Docker ,Linux/Windows Container 等技術(shù)領(lǐng)域
今天的主題是Windows容器。今年下半年攜程開始了對(duì)Windows container的調(diào)研工作,目前已經(jīng)有一些成果和實(shí)際應(yīng)用案例,與大家分享一下,主要內(nèi)容有:
攜程為什么要使用Windows container?
可能國(guó)內(nèi)大部分的人了解Windows container少一些,特別是具體的實(shí)踐,分享重點(diǎn)會(huì)偏Windows container細(xì)節(jié)
傳統(tǒng).Net應(yīng)用容器化實(shí)踐
?容器存儲(chǔ)&網(wǎng)絡(luò)&編排
攜程為什么要做Windows container?
現(xiàn)狀:
攜程是.Net應(yīng)用大戶,由技術(shù)棧決定的,早期攜程整個(gè)應(yīng)用架構(gòu)都放在該平臺(tái)上,線上跑了3000多個(gè)核心應(yīng)用,覆蓋了20多個(gè)BU(業(yè)務(wù)部門),這讓我們不得不關(guān)注這一龐大的系統(tǒng)。
平臺(tái)要往java方面轉(zhuǎn),去分享java的紅利,但是.Net 線上應(yīng)用不可能都重寫;
.Net 的應(yīng)用目前90%左右的應(yīng)用都跑在虛擬機(jī)上,從虛擬機(jī)自身來看,粒度太粗,對(duì)資源的使用率還不是很好。
持續(xù)發(fā)布,應(yīng)用上線,從拿到機(jī)器環(huán)境準(zhǔn)備好環(huán)境上線生產(chǎn),虛擬機(jī)模式下周期長(zhǎng),擴(kuò)容慢。
新一代發(fā)布平臺(tái)的需求,希望縮短環(huán)境準(zhǔn)備時(shí)間,做到秒級(jí)部署, Linux平臺(tái)的應(yīng)用非常容易做到,但是Windows .Net 應(yīng)用在這方面支持比較難,另外,為了確保生產(chǎn)和測(cè)試環(huán)境高度一致,希望應(yīng)用發(fā)布是單一應(yīng)用、單一鏡像的,最好是一個(gè)容器盡量少的包含系統(tǒng)進(jìn)程,這樣可以把資源隔離的粒度控制在小范圍內(nèi),盡量榨取宿主機(jī)的資源,同時(shí)希望Linux容器和Windows容器的方案盡可能接近,比如網(wǎng)絡(luò)、存儲(chǔ),不需要兩套不一樣的方案或是有大的有變化。
一些Windows container的技術(shù)細(xì)節(jié)
最開始的時(shí)候攜程用物理機(jī)部署應(yīng)用,為了保證互不沖突,用戶在一個(gè)物理機(jī)上只部署一個(gè)應(yīng)用。后來認(rèn)為此舉太浪費(fèi),就部署了多個(gè)應(yīng)用,但是為管理帶來了麻煩,應(yīng)用之間有一定的沖突或者相互影響。之后有了虛擬機(jī),虛擬機(jī)上可以部署更多的應(yīng)用,而且隔離比較好,不過虛擬機(jī)資源隔離的粒度太粗了,于是容器走了過來,能做到把一個(gè)應(yīng)用打到包里,這個(gè)包涵蓋了環(huán)境配置等,run起來可以只是一個(gè)進(jìn)程,又具備一定的隔離性,同時(shí)把資源使用的粒度控制足夠的細(xì)。
Windows container目前支持的系統(tǒng)是Windows server 2016,這個(gè)版本是去年10月份正式發(fā)布的(攜程是國(guó)內(nèi)比較早的一批拿到了他們的RTM版本),支持兩類server ,一類是server core,另一類是nano server 。 nano server是微軟比較推薦的一類服務(wù)器系統(tǒng),啟動(dòng)非常快,可以大幅度縮短計(jì)劃內(nèi)維護(hù)宕機(jī)時(shí)間,通常幾秒鐘就起來了,不包含硬件檢測(cè)的時(shí)間,幾十秒都能夠起來。這塊攜程還沒有用于生產(chǎn)環(huán)境,目前只測(cè)試了用server core作為容器宿主機(jī)的系統(tǒng)的情況。需要著重提一下的是,如果宿主機(jī)打了補(bǔ)丁或者升級(jí),容器也要對(duì)應(yīng)的做補(bǔ)丁或者升級(jí)。當(dāng)然不一定說立馬做補(bǔ)丁升級(jí),但一定要比較精確的找到對(duì)應(yīng)的版本做升級(jí)。
Windows container有兩種container類型,這兩種容器都是跑到Windows servrer 2016的,但還有一種容器的玩法是在Liunx平臺(tái)跑.Net core,這種方案我們也看過,大家很容易想到它的局限,其實(shí)只能跑到用.Net 技術(shù)開發(fā)的Windows的應(yīng)用,一些非.Net的應(yīng)用不支持,因此這個(gè)方案被Pass了。直接在Windows server跑容器的方案更為靠譜,該方案有兩種類型,Windows server和hyper-v container 。
有人會(huì)問,hyper-v不就是一個(gè)虛擬機(jī)的技術(shù)嗎?對(duì),其實(shí)它有點(diǎn)像虛擬機(jī),但是hyper-v的技術(shù)略有不同,速度會(huì)明顯比虛擬機(jī)快很多,只是在申請(qǐng)資源或者獲取資源時(shí),比Windows server Container的速度稍稍慢一點(diǎn)點(diǎn),Windows server container可能3秒,它可能4、5秒。但是資源的隔離度比較好一些,類似于虛擬機(jī),微軟公有云 Azure的容器服務(wù)也是采取這種容器類型,他們的考慮是公有云上面部署的應(yīng)用不是受信任的,相互之間有可能“打架”的情況發(fā)生,他想隔離好一些。
另一個(gè)區(qū)別,Windows server Container的內(nèi)核是共享的,可以在宿主機(jī)上看到每個(gè)容器里面的進(jìn)程,這與Linux容器相似,可以直接kill掉。hyper-v container宿主機(jī)是看不見容器內(nèi)進(jìn)程的,像一個(gè)虛擬機(jī)一樣。此外,內(nèi)存資源隔離不同,Windows server Container內(nèi)存可以share,hyper-v container不能share,hyper-v container一旦分配就不能重新進(jìn)行修改。對(duì)系統(tǒng)應(yīng)用是信任的,這種比較適合做私有云的一些產(chǎn)品,因?yàn)樵趹?yīng)用上跑的什么東西,這個(gè)應(yīng)用能干什么壞事或者是相互之間有沒有影響,都可以控制,但是公有云不能這樣做,應(yīng)用使用率很高,會(huì)把別的容器影響到。啟動(dòng)速度上也會(huì)有差別,一個(gè)啟動(dòng)快,一個(gè)啟動(dòng)慢一點(diǎn),當(dāng)然并不是特別慢。
容器鏡像,這個(gè)和Linux容器的鏡像類似,可以分層。最下面一層是基礎(chǔ)鏡像,但是基礎(chǔ)鏡像和Linux有區(qū)別。Linux鏡像可以自己搞,弄一個(gè)系統(tǒng)把它做成鏡像,但是微軟沒有辦法自己做一個(gè)Windows container base鏡像。或者說現(xiàn)在只是Windows server 2016的鏡像,想跑一個(gè)2012的系統(tǒng)是不行的。當(dāng)前系統(tǒng)內(nèi)核只能支持win10,在上面可以繼續(xù)安裝想要的東西,比如接著安裝Framework,然后在最上面裝應(yīng)用。
鏡像構(gòu)建也是一樣,Windows container容器和Docker集成比較好,可以用Docker工具的一些命令進(jìn)行build,用Dockerfile來Build一個(gè)鏡像。registry是鏡像可以直接push到一個(gè)平臺(tái)或者是私有的registry上面去,通過Docker pull方式拉下來,Docker run跑起來。
Windows container的鏡像,可以在Docker網(wǎng)站上可以找到關(guān)于Windows container的一些base image, pull下來大概有8G左右,在外網(wǎng)上下載可能要兩天。大家可以嘗試一下。也可以建私有的registry ,攜程采用的VMware開源的Harbor方案,本身沒有做太多的修改,直接可以用。和攜程的AD整合以后基本上能用了, registry可以把Linux和Windows的鏡像都放在一起,兩邊都能用,都能管,這部分省掉了很多的內(nèi)容,不需要做額外的開發(fā),這樣Windows和Linux的平臺(tái)的image管理方案是一致的。
傳統(tǒng).Net應(yīng)用遷移
遷移背景:
之前提到攜程有3000多個(gè).Net應(yīng)用,這些應(yīng)用每天要不停的發(fā)布、測(cè)試、編譯打包,是一項(xiàng)很大的繁瑣工程,有個(gè)叫“build”的項(xiàng)目負(fù)責(zé)這個(gè)事情。最初這些跑在虛擬機(jī)里,資源使用率很低,白天很忙,晚上使用率很低,有一定的資源浪費(fèi),且構(gòu)建環(huán)境也經(jīng)常不一致。為了積攢容器應(yīng)用使用的經(jīng)驗(yàn),我們考慮把build項(xiàng)目先容器化,也就意味著.Net應(yīng)用自己的編譯在容器里面編譯,看能撞出來什么樣的火花。
原來寫幾千個(gè)應(yīng)用的編譯腳本,如果改了一些東西,變更維護(hù)的代價(jià)是非常大的,盡量這個(gè)方案不要用到原來以往用的工具和使用方式,不去動(dòng)它,最好能夠拿過來不怎么修改,就跑起來。另外,重點(diǎn)看一下像vs2010和vs201這樣的工具能不能在容器里跑,實(shí)踐證明是可以的。然后看MSBuild 在容器里面是否兼容,支持不同的.Net Framework版本,這些都是比較通用的軟件,結(jié)果是這些功能都能夠支持,另外也包括python 、MVC、GIT等等。
遷移收益
首先環(huán)境,編譯的環(huán)境高度一致,每個(gè)環(huán)境沒有太多的區(qū)別,容器拉起來直接跑,提高了編譯成功率。
其次資源利用率提高了,我們把虛擬機(jī)資源砍掉了一半,就只需要兩臺(tái)宿機(jī)機(jī)搞定整個(gè)攜程3000多個(gè).Net應(yīng)用的編譯。
編譯時(shí)長(zhǎng)也縮短了,原來用一次構(gòu)建平均要幾分鐘,現(xiàn)在90秒左右基本上能構(gòu)建完成。
待解決的問題:
?圖形不支持,這個(gè)是某些企業(yè)想用Windows container的大問題,它本身圖形不支持。后臺(tái)程序沒有太大問題,不過有一些依賴圖像工具比較難支持。
舊應(yīng)用兼容不是很好。比如遇到MGwin編譯出來的包,一旦代碼中有調(diào)用標(biāo)準(zhǔn)輸出的語(yǔ)句程序直接就掛了,遇到這類問題,需要把源碼拉下來重新編譯,比較有難度。
不支持RDP,遠(yuǎn)程桌面是不能用的,那怎么做到遠(yuǎn)程訪問呢? 還好Windows 現(xiàn)在支持SSHD安裝了,只需要容器內(nèi)裝一個(gè)SSHD,然后遠(yuǎn)程SSH去,當(dāng)然可以用powershell遠(yuǎn)程的登錄方式,兩種方案都可以用,SSH方案更統(tǒng)一一些, 如果用戶當(dāng)前正在Linux平臺(tái)上工作,突然想登一個(gè)Windows的容器怎么辦?當(dāng)然也可以用linux 平臺(tái)的powershell工具實(shí)現(xiàn)遠(yuǎn)程登陸容器。
不支持D盤。攜程遷移過來很多老的應(yīng)用是要裝在D盤的,容器拉起來沒有D盤,只有一個(gè)C盤。本身Docker有一個(gè)volume功能,可以掛一個(gè)數(shù)據(jù)的盤,問題是這樣會(huì)導(dǎo)致在宿主機(jī)上留下一些東西,和宿主機(jī)產(chǎn)生耦合,如果容器刪除或者遷移,宿主機(jī)上就留下了臟數(shù)據(jù)。后來我們?yōu)镈盤做一個(gè)link,相當(dāng)于D盤可以快捷的方式連到C盤,映射到C盤的某個(gè)目錄,這樣數(shù)據(jù)都是落地到在容器的磁盤上,如果想在別的地方拉起來這個(gè)容器,可以直接push register,就可以在別的地方部署且環(huán)境一樣。
存儲(chǔ)&網(wǎng)絡(luò)&編排
接下來Windows container容器的存儲(chǔ),網(wǎng)絡(luò),編排方面的技術(shù)與大家分享一下。
Windows container資源的隔離方式和配置管理API 是借用Docker規(guī)范,設(shè)計(jì)理念和Linux Container類似,也支持CPU share的這種方式去控制資源的分配。內(nèi)存可以通過quota的方式去分配內(nèi)存,Disk也能夠充分應(yīng)用到IO的帶寬,這一塊還沒有做非常多嚴(yán)格的測(cè)試。關(guān)于網(wǎng)絡(luò)的支持,攜程做了很多測(cè)試,整體來講比較不錯(cuò),問題較少。性能也滿足需求,多個(gè)容器在一個(gè)同一個(gè)宿主機(jī)上也能盡量用到整個(gè)宿主機(jī)的帶寬。?
容器的存儲(chǔ)
存儲(chǔ)有三種:一種是鏡像,鏡像本身是一個(gè)存儲(chǔ),設(shè)計(jì)之初定義就不是一個(gè)永久的存儲(chǔ),當(dāng)前容器存儲(chǔ)拉掉那個(gè)存儲(chǔ)就沒有了,也不是設(shè)計(jì)安全的。另外一種存儲(chǔ)是volume(卷) ,可以掛一個(gè)數(shù)據(jù)盤到某一個(gè)容器上,在容器里擴(kuò)展存儲(chǔ)空間。同時(shí)多個(gè)容器也可以掛載宿主機(jī)上的一個(gè)同一個(gè)volume(卷目錄),這樣大家可以實(shí)現(xiàn)NFS一樣的效果。最后一類存儲(chǔ)是網(wǎng)絡(luò)存儲(chǔ),比如可以用SMB的方式掛網(wǎng)絡(luò)盤在容器里面使用,里面如果有萬兆的帶寬支持還可以玩一下,如果沒有萬兆帶寬的話就不要玩了,它只能放一些冷數(shù)據(jù)。
容器的網(wǎng)絡(luò)
相對(duì)來講復(fù)雜一些,Windows 支持有四種網(wǎng)絡(luò)模型,第一種NAT模式大家比較熟悉,起一個(gè)本地或者是數(shù)據(jù)本地的IP地址,如果你想外網(wǎng)訪問的話,把Docker映射出來,這種方式比較適合做一個(gè)JOB類型的應(yīng)用在上面,不需要外邊可以訪問它,但是容器里面可以去下載東西。之前講的build項(xiàng)目就是用這個(gè)網(wǎng)絡(luò)模型,非常簡(jiǎn)單,不需要考慮太多網(wǎng)絡(luò)的模型就可以直接用。
第二種是transparent網(wǎng)絡(luò)模型,這種模型是現(xiàn)在主要用于生產(chǎn)的模型,首先它是通過mac 地址偽裝實(shí)現(xiàn)數(shù)據(jù)透?jìng)?#xff0c;對(duì)網(wǎng)絡(luò)的性能本身折損也比較少,它也支持把多個(gè)工作網(wǎng)卡綁到一個(gè)交換機(jī)上,然后把這個(gè)交換機(jī)給容器用。網(wǎng)絡(luò)模型在容器宿主機(jī)以外的機(jī)器上看到Windows容器和一臺(tái)物理機(jī)沒有什么區(qū)別。
還有一種是L2 bridge這種采用openstack網(wǎng)絡(luò)的Flat模式,所用的網(wǎng)絡(luò)跟宿主機(jī)的網(wǎng)絡(luò)是一樣的,和宿主機(jī)在同一個(gè)網(wǎng)段,這樣有很大的局限性,網(wǎng)絡(luò)和宿主機(jī)混在一起沒有辦法做到多租戶隔離,然后網(wǎng)段用光了就完了,適用于比較小的集群。
最后一種是Tunnel mode,沒有太多研究這一種,但是微軟Azure用的這一種網(wǎng)絡(luò)模型。本身攜程為了和虛擬機(jī)的很多的品牌網(wǎng)絡(luò)模型一致,所以這一種沒有那么快的推進(jìn)。
hyper-v的網(wǎng)絡(luò)模型
Hyper-v宿主機(jī)是2012上面hyper-v的網(wǎng)絡(luò)模型,之前要求一臺(tái)宿主機(jī)盡量要4塊網(wǎng)卡,為什么要用4塊網(wǎng)卡?兩塊給虛擬機(jī)用,另外兩塊做一些管理,比如對(duì)存儲(chǔ)用,虛擬機(jī)遷移等,可以做宿主機(jī)的管理。另一種方式,2016建議的一種網(wǎng)絡(luò)方式,這里面有一個(gè)叫做embed team,內(nèi)嵌交換機(jī),它的好處是把下面無論是兩塊還是N塊網(wǎng)卡都可以綁在一個(gè)bound,然后把這個(gè)bound放在一個(gè)交換機(jī)里面,每個(gè)容器port全部放在交換機(jī)里面,然后容器給port打相應(yīng)的vlan tag,這樣容器的網(wǎng)就通了。
embed team的好處是不需要要求宿主機(jī)一定要有這么多的網(wǎng)卡才可以用,另一個(gè)好處是對(duì)這些不同的vlan之間做一些流量的控制,攜程的container 的網(wǎng)絡(luò)模型也是基于嵌入式交換機(jī)上實(shí)現(xiàn)的。把宿主機(jī)至少兩塊網(wǎng)卡做了bound,放在一個(gè)embed team里面去,另外加一個(gè)port給宿主機(jī)做管理網(wǎng)卡。容器宿主機(jī)相比虛擬機(jī)宿主機(jī)簡(jiǎn)單,沒有存儲(chǔ)和遷移的需求,就不要以額外的劃分網(wǎng)絡(luò)了,如果需要為容器的存儲(chǔ)單獨(dú)掛一個(gè)網(wǎng)絡(luò)的話可以加一個(gè)Port做這個(gè)事情。不同的網(wǎng)段的這種容器在上面可以再創(chuàng)建不同的Docker,加不同的port,然后容器在里面可以互通,這樣的好處就是既實(shí)現(xiàn)了多租戶、實(shí)現(xiàn)了網(wǎng)絡(luò)隔離,同時(shí)和虛擬機(jī)包括Linux上面的網(wǎng)絡(luò)模型是一致的。
容器編排
編排這塊通常一個(gè)容器部署到多個(gè)宿主機(jī)上,同時(shí)一套應(yīng)用下來有數(shù)據(jù)層、業(yè)務(wù)層、也有web層,這些應(yīng)用要分開放,它們中間放在哪里需要有一個(gè)地方,把整個(gè)管起來,也希望這個(gè)東西能自動(dòng)化,本身做編排這些,無論是Swarm、K8S、Mesos都是需要解決的問題。一種方案是用Docker compose這種方式,適合于單宿主機(jī)管理。想編排一下容器,看如何跑,這種方式用Docker compose就能解決。當(dāng)然,微軟現(xiàn)在對(duì)Docker Swarm支持好一些,實(shí)現(xiàn)成本比較低,基本上能管,但是性能方面沒有做太多的測(cè)試,目前一些基本的調(diào)度、主機(jī)分類等等都能用。
為什么攜程選擇使用Mesos?
因?yàn)閿y程的Linux平臺(tái)用的也是這套方案做的編排相關(guān)的管理,希望有一套方案能夠盡量?jī)煞N容器一致,于是我們的方案采用Mesos 加上Marathon對(duì)它進(jìn)行管理,本身它也有一些現(xiàn)成的工具,比如UI等現(xiàn)成的工具都可以用,這部分還在進(jìn)行測(cè)試和研究中。官方下來的包不能直接跑到Windows server上面,要拿下來重新編譯才能用。最終攜程是想做到這么簡(jiǎn)單的一個(gè)容器的管理的架構(gòu),就是說希望Mesos在里面能夠同時(shí)管Linux容器和Windows容器,對(duì)它進(jìn)行統(tǒng)一的調(diào)度,最大限度的優(yōu)化這種調(diào)度策略,提升使用率,這是最終整體的設(shè)計(jì)理念。
有一些急迫解決的問題,與大家交流一下。首先Windows container的鏡像比較大,在生產(chǎn)環(huán)境,如果批量pull base image,網(wǎng)絡(luò)的帶寬會(huì)很快被打滿,會(huì)對(duì)業(yè)務(wù)帶寬造成影響。我們需要有一套方案來解決這個(gè)問題, 如何能夠比較“經(jīng)濟(jì)”的方式把Based image或者變更的Layer文件下發(fā)下去,是后續(xù)要解決的問題。
Windows container的監(jiān)控日志,沒有現(xiàn)成的方案,我也有與微軟團(tuán)隊(duì)交流過,這部分文檔非常少,攜程之后也會(huì)重點(diǎn)解決監(jiān)控問題。
推行單容器、單應(yīng)用的發(fā)布方式,希望后面能夠把各種FAT/UAT/Prod環(huán)境之間打通,都可以通過Windows容器方式,秒級(jí)發(fā)布。
攜程有3000多個(gè)應(yīng)用,一旦容器跑起來了,宿主機(jī)的規(guī)模還是比較可觀的,這種情況下,大規(guī)模容器如何管理好?這也是后面需要解決的問題。
這是我今天給大家分享的主要的內(nèi)容,謝謝大家!
活動(dòng)相關(guān)閱讀:
構(gòu)建與定制:唯品會(huì)PaaS基于Kubernetes的實(shí)踐
廣發(fā)銀行運(yùn)維實(shí)踐分享:Docker適配傳統(tǒng)運(yùn)維那些事
Docker在Bilibili的實(shí)戰(zhàn):由痛點(diǎn)推動(dòng)的容器化
——點(diǎn)擊閱讀原文下載活動(dòng)PPT——
內(nèi)容轉(zhuǎn)載自公眾號(hào)
數(shù)人云 了解更多總結(jié)
以上是生活随笔為你收集整理的.Net大户的选择:Windows Container在携程的应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .Net Core 之 MSBuild
- 下一篇: Docker4Dev #6 使用 Win