Docker 集群工具比对:Kubernetes vs Docker Swarm

jopen 9年前

从目前来看,Kubernetes 和 Docker Swarm 是2个最常用来在集群环境中创建容器的工具。这两个工具都是被创建来管理容器集群的,而且他们都把集群中的所有服务器当成一个统一的设备来使用。但是,它们在实现方法上有巨大的不同。

Kubernetes

Docker 集群工具比对:Kubernetes vs Docker Swarm

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 集群工具比对:Kubernetes vs 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,试试是否喜欢,当确实需要服务发现工具时,可以再安装 etcdConsul 等其它工具。

而 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 集群。