從目前來看,Kubernetes 和 Docker Swarm 是2個最常用來在集群環境中創建容器的工具。這兩個工具都是被創建來管理容器集群的,而且他們都把集群中的所有服務器當成一個統一的設備來使用。但是,它們在實現方法上有巨大的不同。
Kubernetes
Kubernetes 是基于 google 自身多年使用 linux 容器的經驗創建出來的,所以可以說它是 Google自身多年操作經驗的一個復制,只是 google 把這些操作經驗應用到了 Docker 上。 使用Kubernetes 來管理容器在多個方面都將帶來很大的好處,而其中最重要的就是 Google 把他們多年使用容器的經驗帶入了這個工具。如果你是從 Docker1.0 (或者更早之前的版本)開始使用Kubernetes,你會發現使用 Kubernetes 來管理 docker 容器是非常愉悅的體驗。Kubernetes 解決了許多 Docker 自身的問題。通過 Kubernetes,你可以在容器中使用實際的物理存儲單元,從而我們可以很方便的把容器移動到其他機器上,而不丟失任何數據; Kubernetes 使用 flannel 來創建容器之間的網絡;Kubernetes 集成了 load balancer;Kubernetes 使用 etcd 來實現服務發現,諸如此類的東西還有很多。但是使用 Kubernetes 是要付出一定的代價愛的,比如,Kubernetes 使用了一個完全不同于 Docker 的 CLI (Command Line Interface),不同的 API 以及不同的 YAML 配置定義。換句話說,如果你使用Kubernetes,那么你將完全不能使用 Docker 自帶的CLI,也不能使用 Docker Compose 來定義(創建)容器。使用 Kubernetes,你必須為 Kubernetes 重新創建所有和Docker 容器管理相關的東西,因此我們可以認為 Kubernetes 并不是為了 Docker創建的(從一定意義上說是正確的)。Kubernetes 提升了 Docker 容器集群的管理層次,但同時它的學習曲線也是非常陡峭的。
Docker Swarm
Docker Swarm 就截然不同, 它就是針對 Docker 容器技術創建的集群工具。最關鍵的是 Dcoker Swarm 對外提供的是完全標準的 Docker API,因此任何使用 Docker API 與 Docker 進行通訊的工具(Docker ClI, Docker Compose, Dokku, Krane)都可以完全無縫地和 Docker Swarm協同工作。這一點對 Docker Swarm 來說既是一個優點,也是一個缺點。有點就是你可以使用熟悉的工具集,缺點也顯而易見,就是你只能做 Docker API 規定的事情。如果 Docker API 不支持某個你要的功能,你就不能直接使用 Docker Swarm 來實現,你可能需要使用一些特別的技巧來實現(也可能完全不能實現)。
在下面的章節中,我們將分別介紹如何安裝這2個工具,并且非別介紹它們在管理容器集群上提供的功能。
安裝
安裝 Docker Swarm 非常簡單,直接和靈活。我們需要做的就是安裝服務發現工具,然后在所有的 docker 節點運行 swarm 容器。由于其本身就是一個容器,所以它是以容器的方式來運行的,與操作系統無關。通常我們運行 swarm 后,它會暴露一個端口,我們僅需要通知它服務的地址。沒有比這更簡單的了。我們甚至可以在沒有服務發現工具的情況下也可以運行 swarm,試試是否喜歡,當確實需要服務發現工具時,可以再安裝 etcd,Consul 等其它工具。
而 Kubernetes 的安裝則是復雜難懂的。每個系統和主機供應商的安裝指令都不盡相同。他們各自都有一套指令,用自己的團隊來維護指令和解決問題。比如,你想嘗試一下 Vagrant,卻因為不熟悉 Fedora 的命令作罷。但并不意味你不能運行 Vagrant ,比如可以試試 Ubuntu 或者 CoreOS。你一定可以成功,但是需要在 Kubernetes Getting Started 官方文檔頁面之外搜索相關的命令。不管你需不需要,社區有這些問題解決方案,但是你仍然需要大量的時間去搜索方案的相關問題,并希望在第一次嘗試的時候可以派上用場。更大的問題在于命令是依賴bash腳本,如果配置管理不是必需的,倒也無妨。但我們不想運行一個腳本使 Kubernetes 成為 Puppet,Chef 或者 Ansible 的一部分。當然,這個問題也是可以解決的。你可以找到 Ansible 的文檔或者自己寫文檔來運行 Kubernetes。 這些看似都不是什么大問題,但和 Swarm 相比,顯得令人費心。當我們使用 Docker 時,不應該操作命令行(除了一些 docker run 參數),而是應該運行容器。Swarm 正是這樣做的而 Kubernetes 不是。
然而一些人不關心使用什么發現工具。我喜歡 Swarm 的簡單和邏輯"包含其中的電池但可移除"。所有事情都是開箱即用但是我仍然可以用其他的動氣來替換某個組件。和 Swarm 不同,Kubernetes 是武斷的工具。你必須適應它提供的選擇。如果你想使用 Kubernetes,就得使用 etcd。如果你喜歡的話,我不會嘗試說 etcd 的不好。例如,在非常復雜的環境中使用 Consul 并且需要使用 Kubernetes 和把一個用作 Kubernetes 并且其它剩下的都用作服務發現需要。另外一件事情我不喜歡 Kubernetes 的是在設置之前需要知道高級的事情。需要告訴所有節點的地址,以及它們擁有的角色,他們在集群中擁有多少職責等等。對于 Swarm 來說,我只需要要啟動一個節點并且告訴它加入網絡就行了。不再需要其他高級設置了,因為這些關于集群繁殖的信息是通過 gossip 傳播的。
裝配可能不是這些工具的最大不同。不管你使用哪一種工具,遲早所有的事情都會設置好并運行起來并且你將忘記所有曾經處理過的困難。你可能會說我們不應該只選擇一個工具而不是其他的工具除非它更容易裝配。有道理,讓我繼續談論關于怎樣定義和這些工具一起運行的容器的區別。
運行容器
你如何定義為一大群運行著的 Docker 容器所需要的所有參數?實際上你不需要,這不同于你之前定義它們的方式。如果你是用 Docker CLI 來運行容器,你可以繼續使用一樣(幾乎一樣)的命令。如果你喜歡使用 Docker Compose 去運行容器,你可以繼續使用它去運行他們內部的大量集群。無論哪種方式你都可以運行你的容器,改變的是你可以用同樣的方式運行更大規模的集群。
Kubernetes 需要你學習它的 CLI 和配置。你不能使用 docker-compose.yml 定義你早先創建的容器。你必須創建 Kubernetes 等同的設備。你不能用你以前學的 Docker CLI 命令。還必須學習Kubernetes CLI,并且你要確保整個團隊都學習它。
不管你使用哪個 tool 來部署你的集群,你都應該已經熟悉如何使用 Docker。你可能已經使用 Docker Compose 來替代傳統的 Docker CLI,你使用 Docker Compose 來配置 Dokcer 容器的參數,創建 Docker 容器,來獲取容器的日志等等;你也可能只是在使用傳統的 Docker CLI 來進行所有這些操作, 你甚至還可能寫了自己的專用 script 來運行 Docker CLI。但是不管你使用 Docker CLI 還是 Docker Compose,你所有用的這些技能都將可以和 Docker Swarm 完美地配合。
如果你選擇使用 Kubernetes 來管理你的集群, 請準備好你可能需要做一些重復勞動。即使你選擇了 Kubernetes,你仍然需要使用 Docker Compose 來運行你定義的容器,開發人員將繼續在本地運行 Docker 容器,而 staging 環境的可能只是一個并不太大的集群。換句話說,一旦你決定使用 Docker, Docker Compose 或者 Docker CLI 是不可或缺的工具。一旦你開始使用 Kubernetes,你會發現你需要將所有的 Docker Compose 定義(或者你在使用的 script)翻譯成 Kubernetes 的描述,而且你還必須同時維護兩套版本。在使用 Kubernetes 的時候,你會發現所有的事情都必須雙份(這將帶來超高的維護成本)。這里所說的所有事情,不僅僅包含配置文件,也包含所有運行集群說需要的命令(Kubernetes 說使用的命令和 Docker CLI 完全不同)。
那些創建了 Kubernetes并不是有意讓你在操作Docker的時候充滿了挑戰,之所以 Kubernetes 和Swarm 有如此大的區別,那是因為他們采用了不同的方法來解決面對的問題。Swarm 小組決定使用和 Docker CLI 一樣的 API 接口,如此一來,Swarm 就和 Docker CLI 完全兼容了,當你從 Docker CLI遷移到使用 Swarm 的時候,基本不需要做任何額外的事情(即不需要修改任何配置,也不需要學習新的東西)。Swarm 唯一的問題是,如果你需要 Swarm 做一些不被 API 支持的事情,那 Swarm 就無能為力了。一言以蔽之,如果你想要一個工具,可以使用 Docker API 在集群中部署容器,那么 Swarm 無疑是你的首選。反之,如果你要一個強大的可以自定義的工具,那么你就應該選擇 Kubernetes。
下面讓我們來看一下使用 Swarm 的時候,我們會遇到什么樣的問題。就我所知,其中2個比較大的問題是網絡問題和存儲卷。在 Docker Swarm 1.0 版本發布之前,我們無法讓2個運行在不同服務器上的容易通訊,實際上,就算在 Docker Swram 1.0 版本中,我們還是不能直接連通2個運行在不同服務器上的容器,我們是在一個叫做 multi-host networking 工具的幫助下實現了間接的通訊。從Kubernetes 被創建出來,就已經通過內建的 flannel 實現了不同服務器上的容器之間的互聯。從Docker 1.9開始,容器互聯已經被集成到了 Docker CLI。
另外問題是卷組持久化。Docker 在1.9發布版中把它們引入進來。直到最近,如果你用卷組做持久化,這個容器就被綁定到依賴卷組的服務器上了。容器將不能移動。就需要求助于一些討厭的技巧像卷目錄從一臺服務器復制到另一個服務器。那本身就是一個很慢的操作藐視像 Swarm 等工具的目標。此外即使你有時間去拷貝一個卷組到另外一個服務器上去。但你不知道從哪兒拷貝,因為集群工具趨向于把你的整個數據中心當作一個單一的實體。容器會被部署到最適合它們的位置(最少的容器運行,最多的CPU或者內存可用,等等)。現在我們有了 Dockers 原生態支持的持久卷組。
網絡和卷組持久化問題很長一段時間來都是Kubernetes的支持的容器的特性和為什么很多人選擇它卻不選擇 Swarm。但是這個優勢在Docker1.9發布版就消失了。
選擇
當嘗試在 Docker Swarm 和 Kubernetes 之間做選擇的時候。考慮一下幾點。你是否想依賴Docker 本身解決和集群相關的問題。如果是,選擇 Swarm。如果有些東西 Docker 不支持,很可能 Swarm不會支持,因為它依賴 Docker 的 API。另外,如果你想要一個工具不受 Docker 的局限,Kubernetes 可能是合適的選擇。Kubernetes 不是基于 Docker 構建的,但是它是基于 Google的容器經驗。它是武斷的,并且嘗試用它自己的方式做事情。
在選擇使用 Kubernetes 還是 Swarm 的時候,你需要問自己以下的問題:1) Kubernetes 提供的有點是否會變成一種額外的負擔?2)你是否有信息在將來 Docker Swarm 將越來越好,可以解決目前你在部署過程中遇到的所有問題。強烈建議在你回答這些問題之前,看看 Docker release 1.9 提供的功能。至少在 Docker Release 1.9 中,我們有了卷組持久化,軟件定義網絡,同時 1.9 也提供了 unless-stopped 重啟策略,從而使我們非常容易處理容器的意外故障。 在 Docker 1.9 版本中,Kubernetes 和 Swarm 之間的不同至少又減少了3件,實際上,現在 Kubernetes 能夠提供的好處已經越來越少了。 退一步來講,使用 Swarm 有一個很大的好處,就是它使用 Docker API 意味著你可以重用所有的 Docker 命令和 Docker Compose 配置。從我個人的角度來看,我高度看好 Docker 以及運行在 Docker 之上的 Docker Swarm 未來的發展。Kubernetes 和 Swarm 都是成熟的可以直接運行在生產環境的系統,它們之間的區別已經越來越小了,但是 Swarm 相對來說更加容易安裝和使用,而且我們可以重用我們說創建的所有 script 和配置文件。
我個人建議大家使用 Swarm 來管理 Docker 集群,Kubernetes 實在是太復雜了,而且難于安裝,也難于使用(因為它所使用的API完全和Docker CLI不一樣),而且從 Docker 1.9 開始,和 Swarm 相比,它也并沒有提供太多的優勢功能了。當然這并不意味著 Kubernetes 和 Swarm 的功能完全一樣了,畢竟它們實現的功能還是不太一樣的,Kubernetes 還是有一些 Swarm 所不具備的功能,但是這些差距并不是主要的。從我的經驗來看,隨著 Docker 新版本的發布,就主要功能來說,Kubernetes 和 Swarm 之間的差距越來越小。最后我不得不說的是,因為 Swarm 是如此的容易安裝,學習和使用,在很多情況下,你根本就不會感到有任何的困難來管理你的 Docker 集群。