為什么我們拋棄ECS而選擇了Kubernetes
在這篇文章中我們將會探討2個主流的Docker編排框架:AWS的ECS(Elastic Container Service)和Google的Kubernetes。
3個月前,我們在nanit.com希望選擇一個合適的Docker編排框架,ECS成為了我們的首選,畢竟吴趴,我們對AWS的服務較為熟悉,并且我們的基礎設施都是建立在AWS的。經(jīng)過一段時間的測試劲件,我們發(fā)現(xiàn)ECS并不成熟,缺少一些我們需要的關鍵功能约急,因此我們開始嘗試其在這篇文章中我們將會探討2個主流的Docker編排框架:AWS的ECS(Elastic Container Service)和Google的Kubernetes零远。他的框架:Kubernetes。令人意外的是厌蔽,Kubernetes非常成熟牵辣,幾乎支持我們需要的所有功能。對于我們來說奴饮,Kubernetes在ECS的主場完勝了ECS纬向。接下來,就讓我們一起來看看Kubernetes贏在哪些方面戴卜。
注意:ECS一直在更新逾条,我們會盡可能的跟進這些內容,但部分內容可能被忽略了投剥,希望讀者不要介意师脂。
構建集群(Cluster Setup)
ECS:為了啟動一個ECS集群,用戶需要設置一個Auto Scaling Group江锨。用戶可以編輯user-data來將EC2實例添加到指定的ECS集群上吃警。當ASG被設置,實例啟動之后啄育,用戶可以在ECS控制臺看到這部分內容∽眯模現(xiàn)在,用戶可以開始進行task-definition挑豌,方式類似于Docker-compose安券。
Kubernetes:想要在AWS上啟動一個Kubernetes墩崩,用戶需要先啟動一個具有一定權限的EC2實例(通過IAM)。這將會創(chuàng)建多個AWS constructs來支持你的集群:VPC完疫、ASG泰鸡、一些安全組(Security Groups)和一個Kubernetes主實例。集群需要幾分鐘來啟動壳鹤,之后用戶就能夠在上面運行自己的容器盛龄。
比較結果:使用這兩種框架來啟動一個集群都非常的簡單和友好。
啟動基礎服務(Basic Service Setup)
我們的任務是啟動一個Nginx 鏡像芳誓,并且讓其他人能夠訪問這個Web服務余舶。
ECS:首先,我們需要創(chuàng)建一個ELB(Elastic Load Balancer)锹淌,它負責80端口的轉發(fā)匿值。然后,我們需要創(chuàng)建一個task-definition赂摆,它負責在80端口上啟動一個Docker鏡像挟憔。最后,需要創(chuàng)建一個Service烟号,它會顯示出有多少實例會同時運行绊谭。我們需要將它綁定到我們之前創(chuàng)建的ELB上。
Kubernetes:首先需要創(chuàng)建一個Replication Controller汪拥,它會顯示出我們希望運行的Docker鏡像和有多少鏡像會同時運行达传。之后,我們需要創(chuàng)建一個Service object迫筑,這會啟動一個ELB并且將ELB的流量轉發(fā)到對應的容器上宪赶。
比較結果:Kubernetes的方式更舒服一些,更簡潔脯燃。用戶并不需要手工啟動或者管理ELB搂妻。Kubernetes會完全負責管理:當用戶創(chuàng)建了一個service,一個ELB會自動創(chuàng)建辕棚;當用戶刪除了一個service叽讳,它會自動從AWS上刪除。
服務發(fā)現(xiàn)(Service Discovery)
當你使用了微服務架構和Docker坟募,一個好的服務發(fā)現(xiàn)解決方案是至關重要的。Docker容器總是在不同虛擬機中遷移邑狸,用戶必須有一個可靠的方法來發(fā)現(xiàn)在集群內和集群外的服務懈糯。
ECS:ECS并沒有提供任何服務發(fā)現(xiàn)的解決方案。我能想到的最好方法就是構建一個內部加載平衡器(internal load balancer)单雾,并且將每一個service附加到一個平衡器上赚哗。平衡器的host name不會被改變她紫,然后你就能夠利用這個host name來作為服務的端點。其他的方法還有集成一個外部的程序屿储,比如Consul贿讹。
Kubernetes:我認為這是Kubernetes的亮點之一。Kubernetes內置了一個完全的解決方案够掠。它是一個插件民褂,因此用戶可以選擇是否使用,但我強烈建議使用疯潭。它能夠和namespace一起很好的工作赊堪。簡單來說,當你創(chuàng)建了一個Kubernetes服務竖哩,比如說叫做redis哭廉,你就能夠在集群的任何地方引用redis這個名字,即便是跨虛擬機相叁。這就像是讓docker網(wǎng)絡跨越了特定的虛擬機遵绰,連通了整個集群。Namespaces允許你將多個服務歸納到一個具有邏輯的組中≡鲅停現(xiàn)在假設我們有兩個命名空間椿访,分別是production和staging,他們都包含有一個redis的服務埠通。一個在production命名空間下的容器可以通過redis來引用在production命名空間下的redis服務赎离,同樣的,在stagin命名空間下的容器也能通過redis來引用到位于stagine命名空間下的redis服務端辱。這種自動化識別使得用戶不需要花費時間去配置信息就能夠構建一個隔離的環(huán)境梁剔,并且你可以隨意在所有的命名空間中使用redis來引用對應的服務,接下來kunernetes會為你自動解析它們舞蔽。
比較結果:毫無疑問荣病,Kubernetes小勝一局。使用Kubernetes渗柿,用戶完全不用關心服務發(fā)現(xiàn)的事情个盆,全部交給Kubernetes來做就好了:)
部署(Deployments)
當我們升級一個服務的時候,即便還在部署朵栖,我們也想要確保它百分之百能用颊亮。我們的測試包括一個簡單的NginX服務和一些簡單的靜態(tài)網(wǎng)頁。我們啟動了一個并發(fā)為30個請求的負載測試陨溅,并且在負載測試期間终惑,我們會對該服務進行升級。
在部署期間门扇,我們發(fā)現(xiàn)ECS丟失了比Kubernetes更多的請求雹有。其中偿渡,Kubernetes丟失了0-2個請求,而ECS丟失了9-14個霸奕。
比較結果:說實話溜宽,我對ECS非常的失望。同樣质帅,我也對Kubernetes表示失望适揉,但是它至少比ECS好多了。值得注意的是临梗,Kubernetes 1.1.1版本應該會對輪詢升級機制(rollong update mechanism)進行改善涡扼,還有一些其他的系統(tǒng)系能提升,這些改進都會使得這些數(shù)字變得更好看盟庞。
持久卷(Persistent Volumes)
我們經(jīng)常需要掛載一些持久性的文件系統(tǒng)到一個指定的容器上吃沪,MySQL就是一個典型的例子。
ECS:ECS支持Docker原生的解決方案——用戶可以啟動一個數(shù)據(jù)容器什猖,然后使用volumes-from命令來掛載它到其他容器上票彪。就拿MySQL來看,你首先需要設置一個mysql-data容器不狮,這個容器僅僅擁有一個數(shù)據(jù)卷降铸。然后設置另外一個mysql-db容器,這個容器使用volumes-from命令來掛載之前創(chuàng)建的數(shù)據(jù)卷容器摇零。這個方法看起來不錯推掸,但是它是host-sepicific的,這意味著你的mysql-db容器不能夠在主機之間移動驻仅。你必須指定mysql-db容器在哪一個主機上運行谅畅,以此來防止容器被重新分配到其他主機上,最終失去了持久性噪服。
Kubernetes:除了從一個指定的主機上掛載數(shù)據(jù)卷毡泻,Kubernetes還提供了一個選項:掛載一個EBS(Elastic Book Store)數(shù)據(jù)卷。這意味著一個容器的持久性存儲可以在多個不同的虛擬機之間保留粘优。你再也不需要強制你的MySQL容器必須運行在哪一個具體的虛擬機上仇味。
注意:EBS同一時間只能被一個虛擬機掛載,這意味著如果有一個服務雹顺,它有兩個運行在不同虛擬機的容器丹墨,他們將不能夠掛載和共享這個EBS。
比較結果:即便Kubernetes的EBS掛載有一定的限制嬉愧,但它依舊非常的獨特和有用带到。
健康檢查(Health-Checks)
確保擁有足夠的服務容量是高可用性和冗余性的核心思想。健康檢查就是用來確保服務不僅僅是運行的,并且它們還是健康和可操作的揽惹。
ECS:ECS使用ELB(Elastic Load Balancer)健康檢查,這種方式有三個主要的缺點:
ELB健康檢查僅僅限于HTTP/TCP檢查
如果你想要對一個不開放TCP端口的服務進行檢查四康,這是不行的搪搏。僅僅是為了能夠進行健康檢查,你就必須運行一個HTTP/TCP服務器闪金。
即便你擁有一個支持HTTP/TCP的服務疯溺,你還需要創(chuàng)建一個ELB,并將它綁定到這個服務上哎垦,這樣才能進行健康檢查囱嫩。
Kubernetes:除了基于HTTP/TCP的健康檢查,Kubernetes還提供了一種叫做Exec的方式漏设。Exec可以讓用戶在容器中運行命令墨闲。如果命令結束,并且返回0則表示這個服務是健康的郑口,否則這個服務很可能是不健康的鸳碧,它會被其他的實例所替換。
比較結果:Kubernetes的方式更靈活犬性,更簡單配置瞻离。用戶并不需要去啟動一個冗余的HTTP/TCP服務器僅僅為了進行健康檢查,并且即便服務沒有綁定ELB乒裆,你也可以對它們進行健康檢查套利。
端口管理(Port Management)
從我們的上篇文章中可以看出,端口管理在Docker中是比較困難的鹤耍。我們想通過一個簡單的例子來說明Kubernetes如何比ECS更優(yōu)雅的解決了這個問題肉迫。我們擁有一臺虛擬機和兩個監(jiān)聽80端口的網(wǎng)站。我們不能夠在同一個虛擬機上開2個80端口惰蜜,因此我們需要尋找一個方法來解決這個問題昂拂。
ECS:用戶必須手工確定兩個服務沒有使用同一個端口。我們只有一臺虛擬機抛猖,因此只能運行一個開放80端口的容器格侯。當我們想要開啟第二個開放80端口的容器時,這是不行的财著,因為我們沒有多余的虛擬機了税朴。也就是說,能夠開放多少個x端口的服務取決于擁有多少個虛擬機蝙场。在小型集群中偷遗,這是非常容易滿足的條件,但是當你的服務數(shù)量變得越來越多時伟姐,這將成為一個頭疼的問題收苏,因為當你想要擴充容器時亿卤,你必須確認你還有足夠的端口。
Kubernetes:Kubernetes非常優(yōu)雅的解決了這個問題鹿霸。它為每一個虛擬機上的容器都分配了一個隨機的端口排吴。然后它創(chuàng)建了2個ELB,一個將80端口轉發(fā)到容器A的隨機端口上懦鼠,另外一個轉發(fā)到容器B的隨機端口上钻哩。一個內部的路由機制會負責將數(shù)據(jù)包轉發(fā)到對應容器端口。
比較結果:Kubernetes使用虛擬端口的方式代替綁定原始端口的方法肛冶,很好的解決了這個頭疼的問題街氢。
記錄(Logging)
沒有什么系統(tǒng)不需要記錄功能。
我從沒有想過記錄會成為一個大問題睦袖,但能夠為你解決問題令我非常的高興珊肃,即便這個問題非常簡單。我們之前提到Kubernetes提供了一個服務發(fā)現(xiàn)的擴展功能扣泊,在這里近范,我想說的是記錄的擴展功能。它含有兩個不同的記錄和度量收集(metric collection)的機制延蟹。第一種是著名的ELK方法评矩,ELK會收集容器的所有記錄,并且能夠讓用戶通過Kibana接口來查詢和可視化這些記錄阱飘。第二種是InfluxDB斥杜,它使用Grafana作為可視化工具來查詢系統(tǒng)信息,如CPU和內存使用情況沥匈。
比較結果:Kubernetes的擴展功能更勝一籌蔗喂。當然,你會說我并不需要這些擴展高帖,系統(tǒng)也能很好工作缰儿,但是,它們效果如此之好散址,并且能適用于99%的用例乖阵,為什么不使用呢?ECS并沒有提供內置的記錄功能预麸,用戶想要集成一個進去并不是很困難瞪浸,但是這些并不能和Kubernetes提供的功能相提并論。
未知的云平臺(Cloud Agnostic)
其實吏祸,Kubernetes和ECS之間并不存在競爭:)
ECS會專注于AWS平臺对蒲,如果你已經(jīng)在ECS上構建了你的基礎架構,當你想要轉移到其他云平臺時,你將會遇到很多困難蹈矮。
Kubernetes適用于多個云平臺砰逻。你可以在AWS,Google Cloud含滴,微軟的ZURE诱渤,Rackspace等等上運行你的集群,并且運行效果或多或少都是相同的谈况。在這里,或多或少指的是有一些功能只有部分云供應商提供递胧。你必須確認你選擇的新供應商能夠支持Kubernetes中使用的功能碑韵,至少確保遷移是可能的。
開源軟件(OSS)
Kubernetes是開源的項目缎脾,而ECS不是祝闻。這意味著,所有的一切遗菠,從源代碼到未來的發(fā)展路線都是對你開放的联喘。發(fā)現(xiàn)了漏洞?你可以創(chuàng)建一個issue或者直接提交一個pull 請求來修復它辙纬。新的功能會被添加到每一個新版本豁遭,其中的貢獻人數(shù)和pull請求是驚人的。
ECS有著不同的性質贺拣,我不能夠在網(wǎng)上找到關于它未來發(fā)展路線的規(guī)劃蓖谢。你不能夠獲得一個漏洞和issue的列表,你必須深入到論壇上去尋找想要的答案譬涡。并且你尋找的答案往往都是缺乏實際的闪幽,并不能夠提供任何幫助(https://forums.aws.amazon.com/message.jspa?messageID=664865#664865)。也許這僅僅是因為我個人的糟糕經(jīng)歷涡匀,但是不管怎么說盯腌,這都是令人煩躁和失望的。
比較結果:就我個人而言陨瘩,我更喜歡開源軟件腕够。我喜歡Kubernetes的開放性,每個人都能夠參與討論和貢獻代碼拾酝。我相信社區(qū)的力量會給我們帶來一個更好的產(chǎn)品燕少。
多可用區(qū)域(Multi-AZ)
當談論到Kubernetes時,有一件事情困擾著我:它不支持AWS上的多可用區(qū)域集群(multiple availability-zones cluters)蒿囤。這意味著所有EC2實例都集中在一個AZ上客们,這使得你的集群很可能會遭受到中斷問題。
ECS有對Multi-AZ有很好的支持。
比較結果:在Kubernetes的issue上底挫,已經(jīng)有一些工作正在進行恒傻。我十分確定下個版本會很好的得到改善。因此ECS在這一點上的勝利并不會長久建邓。
總結
很多公司都開始使用Doker作為他們的主要基礎設置盈厘,傳遞機制(delivery mechanism)和編排框架(orchestration frameworks)成為了系統(tǒng)的核心,并且影響著我們開發(fā)官边,遷移沸手,運行,升級的方式注簿。當我想要比較ECS和Kubernetes時契吉,我找不到類似的文章。所以我認為把我們的經(jīng)驗公布出來非常的重要诡渴,這樣其他人能夠站在我們的肩膀上看的更遠捐晶。