swarm和k8s本質都是容器編排服務。它們都能把底層的宿主機抽象化,然后將應用從以構建好的鏡像開始,最終以docker的方式部署到宿主機上。
應該選擇哪種方案作為我們的容器雲服務呢?
我覺得k8s(kubernetes簡稱)跟swarm的比較好比MySQL和SQL Server的比較,前者輕量級、實施快、以實現核心功能為重,比較適合小規模部署,后者則是企業級、功能全、支撐場景多,適合做企業級docker雲方案。
如下我對兩者做出的一些對比:
- 設計理念有區別
swarm偏重的是容器的部署,而k8s更高一層:應用的部署。k8s對容器的所有操作都滲透着為應用而服務的理念,比如pod是為了讓聯系緊密但又不適合部署在一起的應用分別部署在不同docker里面,但docker之間共享volume和network namespace方式,以便實現緊密地“交流”,在比如service是為了隱藏pod(容器的集合,下文會介紹到)的網絡細節,讓pod提供固定的訪問入口,從而方便地讓其他應用訪問等。
另外,k8s特別擅長大規模docker的管理。為了解決復雜場景下應用的部署,k8s的組件要比swarm多得多,即便似乎功能類似的組件,k8s很多時候都在場景支持上要優化swarm,以調度為例,swarm只有三種調度策略:宿主機負載、宿主機運行容器的多寡、隨機指定宿主機,但K8s除此之外,策略更加豐富,它的策略數量是swarm的2倍以上。比如它還有端口沖突策略(在大規模部署docker時,端口沖突是必須要考慮的場景)、容器掛載的卷沖突策略、指定特定宿主機策略等。
- k8s安裝復雜當適應更多場景
swarm與docker天然集成,安裝和使用很簡單,特別是docker 1.12及以上版本,swarm已經集成到了docker的engine中,因此docker安裝后swarm的 部署已經完成了一半,而且swarm的操作都是通過docker api來實現,掌握了docker的操作命令后上手swarm很簡單,基本上一個星期都可以玩的比較6了。
k8s基於docker,但圍繞着應用的部署開發了很多組件,這些組件很多並不依賴於docker的api,在部署時需要單獨規划和實施,而且因為組件中很多策略適應不同的部署場景,所以在部署前不僅僅要明白場景需求,而且還要對組件的設計邏輯了如指掌。所以安裝和熟悉過程相比swarm而言要曲折很多。
- docker vs pod
在swarm中,被創建、調度和管理的最小單元就是docker。
在k8s中,最小單元則是pod(豌豆莢),pod由一個或者多個為實現某個特定功能而放在一起的容器組成。在pod內的docker共享volume和網絡namespace,彼此之間可以通過localhost通信或者標准進程間通信。
用pod有什么好處呢?
我們試想這樣一個場景:我們有一個web應用的容器,現在我們為了收集web日志需要安裝一個日志插件,如果把插件安裝在web應用容器的里面,則會面臨如下一些問題:
- 如果插件有更新,盡管web應用沒有變化,但因為兩者共享一個鏡像,則必須把整個鏡像構建一遍;
- 如果插件存在內存泄露的問題,整個容器就會有被拖垮的風險
如果把插件安裝在不同的容器,同樣也不合適,因為你要想辦法解決插件所在容器讀取web容器的日志的問題。
有了pod以后,這些問題都可以迎刃而解。在pod里面為日志插件和web應用各自創建一個容器,兩者共享volume,web應用容器只需將日志保存到volume,變可以很方便的讓日志插件讀取。同時,兩個容器擁有各自的鏡像,彼此更新互不影響。
- 容器內的負載均衡
swarm自帶的負載均衡機制應用不廣,大部分還是采用nginx+consul。nginx本身也是單獨的 容器,而consul保存了各個docker中應用的網絡信息(IP和端口),nginx鏡像在compose時,在dockerfile中指定consul的地址,取出consul中保存的應用的網絡信息,作為參數配置到nginx的config file中,從而實現負載均衡。
這種模式的缺點就是:nginx的容器中的配置文件無法跟着應用docker的網絡信息發生變化而更改,也就是說,如果新增加了docker,新增加的docker IP和應用端口則需要手動添加到nginx的config file中,或者重新構建nginx的容器。
kubernetes的負載均衡要完善很多,內部集成了負載均衡。而且,對於dockerIP變更的問題也有很好的處理機制:k8s通過service實現負載均衡,service是pod(pod包含了容器,容器中包含了應用)的訪問入口,它指向一組有相同label的多個pod。每個service創建的時候會在k8s內置的dns服務器中寫入一條記錄:service的名稱和service的IP。當需要訪問pod中的應用時,只需訪問service的名稱即可,pod的IP對訪問者來說是透明的,因此不管怎么變都不會影響負載均衡。
- 誰最適合灰度發布
兩者都支持灰度發布。
但swarm的灰度發布是一次梭哈。當執行swarm update操作時,所有舊的docker逐一全部替換成新的版本。如果在替換過程中我發現新版本存在問題時,我只能強行終止update,然后執行回滾。在這個過程中對線上的應用會有影響。
而k8s有replication controller的機制,可以人為控制灰度發布的過程。在發布的過程中,我可以讓k8s通過replication controller起一小部分新版本的pod並減少對應數量老版本的pod,新的pod可響應用戶的請求,如果新的pod比較順利,則慢慢增加新版本的數量而減少老版本數量,直至新版本全部替換老版本,如果新的pod出現了問題,此時讓新pod立即下線,從而不對線上業務造成影響。
k8s的發布過程可以人為干預,因此在重大發布時,這種方式其實更優。
- 彈性伸縮
彈性伸縮是指根據宿主機硬件資源承載的情況而做出的一種容器部署架構動態變化的過程。
比如某台宿主機的CPU使用率使用偏高,k8s可以根據Pod的使用率自動調整一個部署里面Pod的個數,保障服務可用性,但swarm則不具備這種能力。
- 生態
swarm是docke官方推出的集群方案,k8s是脫胎於google的一款基於容器的應用部署和管理打造一套強大並且易用的管理平台。相比swarm而言,k8s更懂容器的管理。
從github上也可以到看到k8s項目的star和fork 都很高,而且網上找的資料也非常豐富。也正是基於k8s的生態影響力,導致docker不得不在新發布的docker EE(Enterprise Edition)將k8s整合進來。
結論:
綜上所述,K8S作為一款企業級的容器雲方案,更值得我們進行研究。套用業界流行的話:swarm懂容器,但K8S更懂管理。