硬件虚拟化通过使用 hypervisor 将物理硬件与虚拟机(VM)共享,提供了诸如可扩展性、安全性、隔离等一系列优势。目前,虚拟机并不是唯一的虚拟化形式,容器也变得非常流行。虽然虚拟机共享底层机器的物理硬件,但容器共享底层操作系统的内核。容器不是轻量级虚拟机,而是标准化的可执行包,用于交付应用程序,包括使用基于微服务的软件架构开发的应用程序,并包括运行应用程序所需的所有组件。
Docker 引擎是运行容器的最流行平台。Kubernetes 是您可能在容器化和云计算领域越来越频繁地听到的术语。但哪个更好 – Docker 还是 Kubernetes?这是一个热门的讨论话题,但这样提问在技术上并不正确。例如,您不能问:“哪个更好 – 热还是蓝?”
什么是 Docker?
Docker 是一个开源的独立应用程序,用作运行容器化应用程序的引擎。它安装在您的操作系统(OS)上,最好是在 Linux 上,但也可以安装在 Windows 和 macOS 上,然后运行在物理或虚拟机器上。
容器中运行的应用程序与系统的其余部分和其他容器隔离,但给出了在其自己的操作系统实例中运行的幻觉。多个 Docker 容器可以同时在单个操作系统上运行;您可以使用 Docker 管理这些容器,而 Docker 可以在没有 Kubernetes 的情况下运行。如果您有多个主机用于运行容器,手动管理它们可能会很困难,通常最好选择一个集中管理工具或编排解决方案。
Docker Compose 是一个基本的容器编排工具,用于运行多容器 Docker 应用程序。您可以配置一个 YAML(yml)Docker Compose 配置文件来定义多容器应用程序,而不是为每个容器手动配置单独的 Dockerfiles。配置单个 YAML 文件后,您可以在 Linux 控制台中使用单个命令运行所有所需的容器。使用 Docker Compose 是编排 Docker 容器的一种方式,但是有一种强大的替代方案可用,称为 Kubernetes。
Kubernetes 是什么?
Kubernetes 是一个开源的容器编排解决方案,用于以高度自动化的方式管理容器化的软件和服务。
Kubernetes 是一个旨在自动化部署、扩展和应用程序可用性的 Google 项目,用于在容器中运行的应用程序。您可以将运行容器的主机数量增加到 11 台或更多主机。此外,您可以使用 Kubernetes 创建 Docker 容器集群,以确保高可用性和负载均衡。
集群中使用的主机称为节点。 Kubernetes的架构类型是主从 – 集群由主节点和工作节点组成。 Kubernetes建议的最小节点数量是四个。虽然您可以使用一台机器构建集群,但为了运行所有示例和测试,您至少需要四个节点。处理生产流量的Kubernetes集群应至少具有三个工作节点。使用两个主节点可以保护您的集群免受一个主节点的故障影响。如有需要,您可以使用多个主节点。
- 主节点用于管理集群的状态,包括接受客户端请求、调度容器操作、运行控制循环等。需要在每个主节点上运行存储集群所有数据的etcd 数据库的副本。主节点运行一组三个进程:kube-apiserver、kube-controller-manager和kube-scheduler。
- 工作节点用于通过运行容器执行应用程序工作负载。非主节点上运行两个Kubernetes进程:kubelet(用于与主节点通信)和kube-proxy(用于在每个节点上反映Kubernetes网络服务)。
- 复制控制器 是一种组件,用于确保在任何给定时刻都运行指定数量的 Pod 副本。因此,您可以确保在需要时始终可用 Pod。
如果使用 Kubernetes,则使用不同的 CLI 和 API 来相互通信服务。还有特定的术语用于命名由 Kubernetes 构建的群集的 RESTful API 的对象和资源。
- Pod 是 Kubernetes 中的基本调度单元。这是一组资源,其中可以运行多个容器。属于同一个 Pod 的容器可以在同一主机上运行,并使用相同的资源和相同的本地网络。Pod 中的容器被隔离但可以轻松地相互通信。因此,Pod 通常用于 Kubernetes,但如果您使用独立的 Docker 应用程序,则仅提供容器池。
- Service 是一组共同工作的容器,例如,提供多层应用程序的功能。Kubernetes 支持使用抽象来动态命名和负载均衡 Pod。这种方法通过名称确保服务之间的透明连接,并允许您跟踪它们的当前状态。
- 标签 是绑定到 Pod 和其他对象或服务的键/值对,除了允许轻松对它们进行分组和分配任务。
- 命名空间是一种方法,允许将统一的 Kubernetes 集群逻辑上分割成多个虚拟集群。每个虚拟集群可以存在于由配额限制的虚拟环境中,而不会影响其他虚拟集群。
Kubernetes 可以与 Docker 一起使用,尽管 Docker 不是唯一可以与 Kubernetes 一起使用的容器平台。Kubernetes 也可以与 Windows 容器、Linux 容器、rkt 等配合使用。K8s 是 Kubernetes 的名称,有时可以在技术文档中找到。
Kubernetes 对比 Docker:网络比较
让我们来审视每种解决方案的网络选项。
Docker为容器之间的网络通信提供了三种网络模式。
桥接。此模式默认使用,创建一个虚拟的第三层桥接。该网络在主机上的名称为 docker0。Docker 自动创建一个第三层网络桥接,并为外部网络接口配置伪装规则,使用网络地址转换(NAT)原理,使容器可以相互通信并连接到外部网络。如果您想从其他主机和外部网络连接到容器,可以为主机机器的网络接口配置端口转发。因此,通过连接到主机机器的适当端口,您将被转发到 Docker 容器的必要端口。如果需要,您可以为 Docker 容器创建多个网络接口。
主机。在此模式下,主机网络驱动程序确保容器与Docker主机之间不隔离。容器共享主机网络栈,容器的主机名与主机操作系统的主机名相同。如果在一个监听TCP端口8080的容器上运行,容器应用将在主机机器的IP地址的TCP端口8080上可用。主机网络驱动程序仅适用于Linux机器。
无。给定容器的网络接口未配置任何IP地址,除了回环接口的127.0.0.1地址。如果设置了无网络模式,则无法访问外部网络。
Docker容器的多主机网络。如果容器运行在不同的主机上,可以在配置了覆盖网络后彼此通信。必须配置有效的键值存储服务(Consul、Etcd或ZooKeeper)来创建这样的网络。
Kubernetes。如果使用独立的Docker容器,每个容器可以被视为通过适当的网络接口进行通信的基本单元。如果使用Kubernetes,Pod是容器集群的基本单元。每个Pod都有自己的IP地址,由至少一个容器组成。一个Pod可以由多个用于相关任务的容器组成。同一Pod的容器不能同时打开相同的端口。这种限制是因为由多个容器组成的Pod仍然只有一个IP地址。
此外,Kubernetes 为每个 Pod 创建一个特殊的暂停容器。这个特殊的容器用于为其他容器提供网络接口(用于内部和外部通信),并且通常处于暂停(睡眠)状态。当 Kubernetes 发送“SIGTERM”信号时,这些暂停容器才会醒来。
Flannel 通常被用作 Kubernetes 的网络织物,它使用网络覆盖的原则将容器连接起来。覆盖网络允许您在集群的不同物理主机上运行容器时进行通信,这些主机被称为节点。使用 etcd 这个开源的键值存储来保存宿主机为容器分配的真实 IP 地址和覆核网络 IP 地址之间的映射关系。
可以将 Kubernetes 网络与 VMware NSX-T 集成,使用 NSX 容器插件。这种集成允许您使用多租户网络拓扑,而这种拓扑在 Kubernetes 中是“原封不动”的。
Kubernetes 网络模型提供以下特性:
- 所有容器都可以直接与集群内的其他容器通信,无须进行 NAT。
- 所有集群节点都可以直接与集群内的所有容器通信,反之亦然。
- 容器可以看到自己的 IP 地址,而其他 Kubernetes 组件也可以看到这些 IP 地址。
Ingress是Kubernetes的一个API对象,用于管理集群外部服务的访问(主要是HTTP和HTTPS)。您可以配置Ingress以对容器化服务执行外部访问,用于负载平衡、SSL终止和基于名称的虚拟主机。必须在主节点上部署Ingress控制器才能使Ingress规则生效。
使用案例
将Docker作为独立软件使用对应用程序的开发非常有利,因为开发人员可以在隔离的环境中运行其应用程序。此外,测试人员也可以使用Docker在沙盒环境中运行应用程序。如果您希望在生产环境中使用Docker运行大量容器,则可能会遇到一些复杂情况。例如,一些容器可能会被过载或失败。您可以手动在适当的机器上重新启动容器,但手动管理可能会消耗大量宝贵的时间和精力。
Kubernetes通过提供高可用性、负载平衡、容器编排工具等关键功能来解决这些问题。因此,Kubernetes最适合具有大量Docker容器的高负载生产环境。部署Kubernetes比安装独立的Docker应用程序更加困难,这就是为什么Kubernetes不总是用于开发和测试的原因。
Kubernetes与Docker Swarm的比较
Docker Swarm 是 Docker 的本地集群工具,可以将一组 Docker 主机转换为单个虚拟主机。Docker Swarm 与 Docker Engine 完全集成,允许您使用标准 API 和网络流程;旨在部署、管理和扩展 Docker 容器。
Swarm 是称为节点的 Docker 主机集群。在与 Kubernetes 和 Docker Swarm 比较集群部署之前,请考虑以下主要组件:
管理节点 用于执行控制编排、集群管理和任务分配。
工作节点 用于运行由管理节点分配任务的容器。每个节点可以配置为管理节点、工作节点,或同时执行管理节点和工作节点的功能。请注意,工作节点运行 Swarm 服务。
服务。Docker Swarm 的服务定义了每个容器化服务的所需最佳状态。服务控制诸如副本数量、可用于其的网络资源、必须从外部网络公开的端口等参数。服务配置(如网络配置)可以修改并应用到容器上,而无需手动重新启动容器。
任务。任务是运行单个容器的插槽。任务是 Swarm 服务的组成部分。
因此,Docker Swarm 和 Kubernetes 是用于类似目的的两个不同平台。现在是时候在适当的一组类别中进行比较了。
集群部署
Docker Swarm。标准 Docker API 允许您使用标准 Docker CLI(命令行界面)部署 Swarm 集群,这使得部署变得更加容易,特别是当首次使用时。与 Kubernetes 相比,Swarm 的部署简易性还体现在单个 Docker 主节点可以决定如何分配服务。Docker Swarm 不使用 Pod。
Kubernetes 要求您使用不同于标准 Docker 命令的指定命令。在 Kubernetes 中使用指定的 API,这意味着即使您了解 Docker 管理的命令,您也可能需要学习使用额外的工具来部署 Kubernetes。在 Kubernetes 集群中必须手动定义节点 – 您应该选择主节点,定义控制器、调度器等。
可扩展性
Docker Swarm。由于 Docker 提供了简单的 API,可以更快地部署容器和服务更新,无论是在大型还是小型集群中。命令行界面(CLI)相当简单易懂。因此,与 Kubernetes 相比,Swarm 可以被认为是更具可扩展性的解决方案。
Kubernetes 提供了相对统一的 API,以及许多功能,这些功能经常导致部署过程较慢。必须配置三种类型的组件:Pod、Deploy 和 Service。在自动缩放方面,Kubernetes 更可取,因为它能够分析服务器负载,并根据给定要求自动扩展和缩减。对于大型分布式网络和复杂系统,Kubernetes 是最佳选择。
高可用性
这两种解决方案选项都具有类似的服务复制和冗余机制,在两种情况下,系统都是自我调节的,在失败的节点重新变成集群后,不需要手动重新配置。
Docker Swarm。管理节点处理工作节点和整个集群的资源。Swarm 集群节点负责服务的复制。
Kubernetes。Kubernetes 的负载平衡服务检测到不健康的节点,并将其从集群中删除。所有的 Pod 都分布在节点之间,因此在容器化应用程序运行的节点失败时提供了高可用性。
负载平衡
Docker Swarm。负载平衡是一项内置功能,可以通过使用内部 Swarm 网络自动执行。所有对集群的请求都会分发和重定向到集群节点;任何节点都可以连接到任何容器。Docker Swarm 使用 DNS 元素将传入的请求分发到服务名称。
Kubernetes。在Kubernetes中,定义的策略用于负载均衡。在这种情况下,容器Pod必须定义为服务。您必须手动配置负载均衡设置,而Ingress可以用于负载均衡。
创建和运行容器
Docker Swarm。在使用Docker Swarm时,由于Docker Swarm的标准化API,可以利用大多数可用于Docker CLI的命令。Docker Compose定义了如何使用卷和网络,并定义了必须组合的容器。对于Docker Swarm,可以使用Docker Compose设置精确的副本数量。
Kubernetes。Kubernetes有自己的API、客户端,并且需要配置YAML文件。这是一个关键的区别之一,因为在这种情况下无法使用Docker Compose和Docker CLI部署容器。在Kubernetes中,定义服务的系统遵循与Docker Compose类似的工作原理,但更复杂。使用Pods、Deployments和Services在Kubernetes中执行Docker Compose的功能,每个层都用于其自己指定的目的。Pods负责容器交互,而deployments负责单个节点集群中的高可用性和网络(类似于独立Docker应用程序而不使用Swarm的Docker Compose),而Kubernetes services负责配置集群内部的服务操作、容错等。
网络
Docker Swarm。集群内的容器通信有一个默认的内部网络,如果需要,可以添加更多的网络。网络受生成的TLS证书保护。支持手动生成证书来加密容器数据流量。
Kubernetes。Kubernetes的网络模型相当不同,通过使用插件来实现,其中一个是Flannel,这是最受欢迎的选项。Pods之间相互交互,这种交互可以受到策略的限制。etcd服务管理着一个内部网络。TLS加密也可用,但需要手动配置。Kubernetes网络模型假定配置两个CIDRs,即无类别域间路由,也称为超网划分。
监控
Docker Swarm。虽然没有内置的监控和日志记录工具,但您可以手动设置第三方监控工具。ELK或Reimann可用于此目的。
Kubernetes。Kubernetes提供了内置工具用于日志记录和监控。Elasticsearch和Kibana(ELK)可用于监控整个集群状态,而Heapster、Grafana和Influx可用于监控容器服务。
图形用户界面(GUI)
Docker Swarm。可以使用第三方工具(如Portainer.io)启用GUI,提供用户友好的Web界面。作为替代方案,您可以使用提供了图形界面用于集群管理的Docker企业版。
Kubernetes。Kubernetes提供的图形用户界面是一个可靠的仪表板,可以通过Web界面访问,您可以轻松控制您的集群。对于那些在使用CLI管理Kubernetes方面经验较少的用户来说,GUI可能是一个非常有价值的工具。
结论
Docker Swarm是一个本地的Docker解决方案,主要使用Docker API和CLI。相比之下,Kubernetes是谷歌的项目,用于部署容器运行的集群。
Docker Swarm和Kubernetes都提供高可用性、负载均衡、覆盖网络和可伸缩性功能。Docker Swarm是两者中较易部署的,因为它的大部分功能配置是自动化的,并且消耗较少的硬件资源。然而,由于受限于Docker API,其功能受到限制,而且缺少原生监控工具。
而Kubernetes则是一个模块化的解决方案,具有较高的灵活性,并且得到了大多数大型企业实体的支持多年。Kubernetes提供了用于监控服务和整个集群的内置工具,尽管部署和配置更加困难,使得这个资源更需要投入。Kubernetes与Docker CLI和Docker Compose不兼容。在大型环境中,运行高负载的多容器应用程序时,首选使用Kubernetes。