跳到主要内容

Docker Swarm 和 Docker Stack

Docker Swarm 和 Docker Stack 不仅仅是 Docker 和 Docker Compose 的补充,更是他们的自然延伸。如果你已经习惯于使用 Docker 和 Docker Compose 来创建和管理单个主机上的应用,那么你会发现 Swarm 和 Stack 提供了一个熟悉且一致的界面,用于扩展应用到多个主机上。Swarm 模式和 Stack 命令是嵌入在 Docker CLI 中的,这意味着你可以继续使用你熟悉的 Docker 命令,而不需要学习新的工具。

对于 Docker Compose 用户来说,Docker Stack 提供了一种非常直接的方式来将你的 Compose 项目扩展到 Swarm 中。你可以使用完全相同的 Compose 文件定义你的服务堆栈,然后使用 Docker Stack 命令将其部署到 Swarm 中。这使得你可以无缝地从单个 Docker 主机的部署转变到 Swarm 集群的部署。

简介 #

什么是Docker Swarm #

Docker Swarm 是 Docker 的一种集群和编排解决方案。它允许你将多个 Docker 主机连接在一起,形成一个“群集”(Swarm),并可以在这个 Swarm 上运行和管理你的服务。在 Swarm 模式下,你可以使用 Docker 的标准命令来部署应用,调整服务的规模,以及进行滚动更新。

什么是Docker Stack #

Docker Stack 则是在 Swarm 上管理服务堆栈的工具。一种服务堆栈可以看作是一个包含多个相互关联的服务的集合,这些服务可以一起部署和扩展。这与我们在 Docker Compose 中定义的服务堆栈的概念是相同的。实际上,Docker Stack 使用与 Docker Compose 相同的 YAML 文件格式来定义服务堆栈。

为什么我们会想要使用 Docker Swarm 和 Docker Stack #

个人理解这是Docker提供出来的容器编排解决方案,和其他的容器编排解决方案类似,它可以解决以下的几个问题:

  • 扩展性:通过使用 Swarm,你可以将你的应用分布到多个 Docker 主机上,这可以提供更高的计算资源,并允许你的应用服务在需要时进行扩展。
  • 容错性:如果一个 Swarm 中的节点出现故障,Swarm 可以自动将任务调度到其他健康的节点上,从而保证你的应用服务的正常运行。
  • 易用性:Docker Swarm 和 Docker Stack 的使用和 Docker 及 Docker Compose 的使用方法非常相似,这使得你可以很容易地将你已经知道的 Docker 和 Compose 技术应用到更大规模的部署中。

理解 Docker Swarm #

在 Swarm 模式下,你可以将多个 Docker 主机组织成一个 Swarm 集群,其中一个主机充当管理者节点,其余的主机充当工作节点。

下面是 Docker Swarm 一些关键概念:

  • 节点(Node):一个节点就是一个 Docker 主机,它可以是物理机器,也可以是虚拟机。每个节点都有一个角色,即管理者(Manager)或工作者(Worker)。管理者节点负责维护 Swarm 集群的状态,处理服务的创建、更新和删除,以及进行任务调度。工作者节点则负责运行 Docker 容器。一个 Swarm 集群至少有一个管理者节点。
  • 服务(Service):在 Docker Swarm 中,服务是你要在 Swarm 集群中部署的应用的基本单位。一个服务定义了一个特定的任务,比如运行一个 web 服务器或者一个数据库。每个服务都由一个或多个任务(Task)组成,任务是服务的运行实例。
  • 任务(Task):任务是 Docker Swarm 中的一个原子调度单位。每个任务对应一个 Docker 容器,并且每个容器只能运行一个任务。任务的状态由 Swarm 集群管理,包括任务的创建、更新和删除。
  • 堆栈(Stack):在 Swarm 中,一个堆栈就是一组相关联的服务,这些服务共享相同的 Compose 文件进行定义。堆栈使得在 Swarm 中部署多服务应用变得更加简单和一致。

部署你的第一个 Docker Swarm #

首先,你需要在一台已经安装了 Docker 的主机上初始化 Swarm。我们称这台主机为管理者节点。你可以使用以下命令来初始化 Swarm:

docker swarm init --advertise-addr <MANAGER-IP>

其中,<MANAGER-IP> 是你的管理者节点的 IP 地址。运行该命令后,Docker 会在你的主机上启动 Swarm 并输出一个加入 Swarm 的命令和令牌。

接下来,你可以在其他主机上运行加入 Swarm 的命令,将它们添加到 Swarm 集群中。

docker swarm join --token <TOKEN> <MANAGER-IP>:2377

现在你已经拥有了一个运行中的 Swarm 集群。接下来,让我们尝试在 Swarm 中部署一个服务。我们将部署一个简单的 HTTP echo 服务,该服务会返回它接收到的所有 HTTP 请求。

docker service create --name echo --publish 8080:80 --replicas 3 jmalloc/echo-server

这个命令告诉 Docker 在 Swarm 集群中创建一个名为 “echo” 的服务,发布 8080 端口,创建 3 个副本,并使用 “jmalloc/echo-server” 镜像。 使用 docker service ls 命令,你可以查看你的 Swarm 中所有的服务。

这就是如何部署你的第一个 Swarm 集群和服务。你会发现,尽管 Swarm 提供了强大的集群管理和服务编排功能,但其使用方式和 Docker 非常相似,你无需学习太多新的概念和命令。

理解和使用 Docker Stack #

在 Docker Swarm 中,堆栈(Stack)是一种管理多个相关联服务的方式。就像我们之前在 Docker Compose 中看到的,堆栈允许你使用一个 YAML 文件来定义多个服务,并使用一个命令将这些服务部署到 Swarm 中。

简单来说,想要在 Docker Swarm 中使用类似 Docker Compose 的能力,那么你需要使用的是 Docker Stack,它的使用方式甚至是定义方式和 Docker Compose 十分类似。

让我们以一个例子来更好地理解堆栈。假设你有一个包含 web 服务和数据库服务的应用,并且你已经使用 Docker Compose 文件来定义了这个应用。在 Swarm 中,你可以使用相同的 Compose 文件来部署这个应用。首先,你需要在 Compose 文件中添加一些 Swarm 特有的配置,比如副本数量和部署模式。

version: '3'
services:
  web:
    image: my-web-app:latest
    ports:
      - "80:80"
    depends_on:
      - db
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure
  db:
    image: postgres:latest
    volumes:
      - db-data:/var/lib/postgresql/data
    deploy:
      placement:
        constraints: [node.role == manager]
volumes:
  db-data:

可以看到deploy标签下是针对堆栈我们在原有 Compose 文件里增加的内容。 然后,你可以使用 docker stack deploy 命令来部署堆栈:

docker stack deploy -c docker-compose.yml myapp

这个命令会创建一个名为 myapp 的堆栈,并根据 Compose 文件中的定义创建服务。

Docker Swarm 和 Docker Stack 的最佳实践 #

下面是一些使用 Docker Swarm 和 Docker Stack 的最佳实践:

  • 保持服务的无状态性: 你的应用可能包含一些需要保存状态的服务,比如数据库。然而,对于无状态的服务,例如 web 服务或 API 服务器,它们不应保存任何状态。所有状态都应该存储在数据库或其他持久化存储服务中。这样做的好处是,你可以随时添加或删除服务的副本,而不用担心丢失状态。
  • 使用健康检查: Docker 允许你为服务定义健康检查。这是一个你定义的命令,Docker 会定期运行它来检查服务的健康状态。如果检查失败,Docker 会自动重启服务。
  • 配置故障转移和备份: 在 Swarm 中,你的服务可以跨多个节点运行。这意味着如果一个节点出现故障,服务仍可以在其他节点上运行。然而,你仍然需要为你的应用配置故障转移和备份策略,以防整个集群出现故障。 理解网络和数据卷: Swarm 中的服务可以使用 Swarm 网络和数据卷。Swarm 网络允许服务之间的通信,而数据卷允许你在服务之间共享数据。理解这些概念,并知道如何在你的应用中使用它们是很重要的。
  • 限制资源使用: Docker 允许你为每个服务设置资源限制和保留。例如,你可以限制一个服务使用的 CPU 和内存的数量。这可以帮助你防止一个服务使用过多的资源,导致其他服务运行缓慢。

Docker Swarm vs K3S vs K8S #

Docker Swarm: #

优点:Swarm模式内置于Docker引擎中,使用起来相对简单直接。配置明了,部署容易。其内置的负载均衡和服务发现机制也非常易于使用。对于中小型项目来说,Docker Swarm是一个非常好的选择。 缺点:相比Kubernetes,Docker Swarm的功能更为基础,且社区相对较小,这意味着可能缺少一些高级特性和广泛的第三方支持。

K3S: #

优点:K3S是Kubernetes的一个轻量级版本,它去掉了一些在边缘计算、IoT、CI和ARM设备等场景中不必要的组件,使其安装包更小,安装和运行更快。因此,如果你在资源受限或者需要快速部署的环境中运行Kubernetes,K3S可能是最好的选择。 缺点:由于K3S精简了一些组件,所以在一些高级的用例中可能无法满足需求。

Kubernetes(K8S): #

优点:Kubernetes是最流行的容器编排工具,它的功能非常丰富,包括自动扩缩容、滚动更新、服务发现、负载均衡等等。Kubernetes有着庞大的社区和丰富的生态系统,几乎所有的云服务提供商都提供Kubernetes的支持。 缺点:相比Docker Swarm和K3S,Kubernetes的学习曲线较陡峭,配置和管理也相对复杂。它的资源消耗也相对较大。

FAQ #

官方例子 #

Voting App

虽然 Docker Swarm 和 Stack 的学习和使用相对直观,但是在实际应用中可能会遇到一些问题。以下是一些常见的问题和可能的解决方案:

  • 服务不能相互通信: 在 Swarm 中,服务默认可以通过服务名相互通信。如果你的服务不能相互通信,可能是网络配置有问题。你应该检查你的服务是否都连接到了正确的 Swarm 网络。
  • 服务不能访问 Internet: Swarm 中的服务默认可以访问 Internet。如果你的服务不能访问 Internet,可能是防火墙或网络配置的问题。你应该检查你的防火墙规则和网络配置。
  • 服务启动失败: 如果你的服务无法启动,可能是镜像问题、资源限制问题或健康检查失败。你应该查看服务的日志和 Docker 的错误消息,以确定问题的原因。
  • 服务无法扩展: 如果你不能增加服务的副本数量,可能是资源不足。你应该检查你的节点是否有足够的资源来运行更多的副本。
  • 数据丢失: 如果你的服务丢失了数据,可能是你没有正确地使用数据卷。你应该检查你的数据卷配置,以确保数据正确地持久化。

总结 #

我们详细讨论了 Docker Swarm 和 Stack,这两者都是 Docker 生态系统中的重要组成部分。Docker Swarm 是 Docker 的原生集群技术,允许你在多个 Docker 主机上部署和管理服务。而 Docker Stack 则是一个管理在 Swarm 集群上运行的服务栈的工具。

虽然 Swarm 和 Stack 可能无法满足所有的用例,例如需要更复杂的调度、网络和安全功能的大规模集群,但对于许多用例,特别是中小规模的项目,Swarm 和 Stack 提供了一种简单、直观的解决方案。

感谢你花时间阅读这篇文章,希望你已经获得了关于 Docker Swarm 和 Stack 的深入理解,并准备好在你的项目中使用它们。祝你使用 Docker 的旅程顺利!

参考文章 #