Docker 容器的创建比较简单,容器解决了应用程序对于运行环境的依赖问题,但是在当前所处的微服务盛行的情况下,手动管理容器是一件比较重复其及其枯燥的工作,这项工作理论上可以通过计算机来完成,因此涌现除了许多的部署容器的工具,本文将简要介绍一下 Docker Compose 和 Docker Swarm 的使用
Docker Compose 是一个用于定义和运行多个容器的 Docker 应用程序,通过 Docker Compose,你可以使用一个 yaml 文件来定义你的应用服务。然后,通过一个单独的命令,可以创建并且运行所有你已经配置好的服务。
使用以下三个步骤来使用 Docker Compose:
-
通过 定义你的应用程序的运行环境,使得你的应用程序可以在任意的环境下都能够运行
-
在 配置文件中定义你应用服务的配置关系,使得这些容器能够在彼此独立的环境下能够协同工作
-
运行 以及一些其它的 Docker Compose 命令启动或者运行你的整个应用程序。直接使用 命令也是可以的,前提是需要安装
以 为例,按照如下的命令来安装
Docker Compose 存在 和 两种版本,开发时建议使用 版本,因为许多 版本的特性在 版本中已经被移除了,当升级时可能会出现问题
一个可能的 文件示例如下所示:
在 文件所在的目录下, 执行 命令即可完成相关容器的部署
具体的语法细节请参考:https://docs.docker.com/compose/compose-file/compose-file-v3/
Docker Compose 解决了在单个主机上部署多个服务带来的问题,除了在单台主机上部署相关的服务之外,在多台主机上部署应用程序也是一个不小的挑战。所幸,Docker 提供了 Docker Swarm 工具来帮助我们完成这一步骤
Docker Swarm 存在以下特点:
-
使用 Docker 引擎整合集群管理
使用 Docker 引擎的即可创建一个集群,而不需要额外的编排软件去创建或管理集群
-
去中心化设计
Docker 引擎不是在部署的时候处理节点角色之间的区别,而是在运行时的任意时刻进行特定的处理。你可以使用 Docker 引擎部署两种类型的节点:manager 和 worker。这意味着你可以从单个的磁盘镜像中构建整个集群
-
声明式服务模型
Docker 引擎使用一种声明式的方式让你能够在你的应用程序栈中定义各种服务的期望状态。例如,你可能会构建一个应用程序,该应用程序由 Web 前端、消息队列服务以及一个数据库后端组成
-
可缩放
对于每个服务,你可以声明你想要运行的的任务的数量。当你扩大或缩小应用时,Docker Swarm 会自动地通过添加或移除任务来自动适应以维持期望的状态
-
期望状态和解
Docker Swarm 的管理节点持续不断地监视着集群的状态并且调节任意在实际状态和你期望的状态之间的不同。例如,如果你设置一个服务来运行 10 个容器的副本,此时一个工作的机器主机中两个运行的副本已经奔溃,那么 Swarm Manager 将会创建两个新的副本来替换已经奔溃的副本,Swarm Manager 会新创建的两个副本放入到已经运行并且可用的工作节点中
-
多主机网络
你可以为你的服务指定一个覆盖网络。Swarm Manager 在初始化或者更新应用程序时会自动为该覆盖网络上的容器分配地址
-
服务发现
Swarm 的 manager 节点为每个在 Swarm 中的节点分配了一个唯一的 名称,并对运行中的容器进行负载均衡。你可以通过在 Swarm 中内嵌的 服务查询每个运行在 Swarm 中的容器
-
负载均衡
你可以开放服务的端口用于外部的负载均衡。在内部,Swarm 允许你指定如何在节点中分发服务容器
-
默认安全
每个在 Swarm 中的节点,Swarm 都强制执行 TLS 的相互身份验证和加密,以保护自身和其它所有节点之间的通信,你可以选择使用自签名根证书或来自自定义根 CA 的证书。
-
滚动更新
在更新时,你可以逐步地将服务更新到各个节点。Swarm Manager 让你可以控制部署服务到不同节点之间的延迟。如果在更新时遇到了问题,你可以回滚到之前的服务版本
-
节点
Manager 节点主要具有以下的几个作用:
- 维护集群的状态
- 调度服务
- 为 Swarm 集群提供外部可调用的 API 接口
- 提供服务注册发现、负载均衡等功能
Manager 节点通过 Raft 算法来维持内部服务的内部状态一致性。为了获得 Docker Swarm 故障容忍的优势,Docker 建议根据具体的高可用需求,尽可能将 Manager 节点数设置为奇数个
Worker 节点用于执行具体的任务,不参与 Raft 的分布式状态,不做调度决策,也不服务于 Swarm 的 Http API,只是单纯地执行 Manager 分发的任务。
由于 Manager 节点在默认情况下也可以作为 Worker 节点参与任务的执行,为了提高系统的稳定性,请将 Manager 节点的可用性设置为 Drain,这样可以将任务分配到实际的工作节点上,使得分工更加明确,具体如下所示:
-
服务
任务(Task)是 Swarm 中最小的调度单位,任务包含了一个 Docker 容器和在容器内运行的命令,如果某一个任务奔溃,那么协调器将会创建一个新的副本任务,将该副本任务放入到其它可用的容器中
Service 是一组任务的集合,Service 定义了任务的属性,如:任务的个数、服务策略、镜像的版本号等
- Overlay Network:用于管理 Swarm 中每台机器的 Docker 的守护进程之间的通信。因此如果直接将一个服务附加到已有的 Overlay Network 中,那么新加入的服务就可以立即和其它的服务进行通信
- Ingress Network:一个特殊的 Overlay Network,用于服务中节点之间的通信。当任何 Swarm 节点在发布的端口上收到请求时,它会将该请求交给一个名为 IPVS 的模块。IPVS 跟踪参与该服务的所有 IP 地址,然后选择其中的一个,并通过 Ingress 网络将请求路由到它。初始化或加入 Swarm 集群时会自动创建 Ingress 网络,大多数情况下,不需要自定义配置
- Docker Gwbridge Network:一种桥接网络,将 Overlay 网络连接到一个单独的 Docker 守护进程的物理网络。默认情况下,每个正在运行的任务的容器都将连接到本地 Docker 守护进程所在的宿主机器的 docker_gwbridge 网络。
流量的分类
Docker Swarm 的流量分为两大类:控制管理流量和应用数据流量
-
控制管理流量(Controller And Management Plane Traffic)
-
应用数据流量(Application Data Plane Traffic)
首先,我在我的计算机上安装了两台虚拟机,二者的操作系统都是 ,现在将它们作为 Worker 节点,两者的 IP 地址(子网地址)分别为:192.168.0.105、192.168.0.107,宿主机的 IP 地址为 192.168.0.106,现在将宿主机作为 Manager 节点
配置 Swarm
首先,在宿主机上初始化 Docker Swarm,构建一个只有一个 Mannager 节点的集群
执行完成之后,可能会得到类似下图的输出:
其中,图中的输出 需要在别的 Worker 节点的机器上执行,现在分别在两台 Worker 节点的机器上执行相应的命令
对于 192.168.0.105、192.168.0.107,都执行添加到 Swarm 的命令:
执行完成之后,会发现此时已经有两个 Worker 节点被添加到 Swarm 中了:
创建 Service
以创建 Nginx 为例,创建一个具有两个副本任务的 Service,如下所示:
正常运行的结果类似下图所示:
[1] https://docs.docker.com/compose/
[2] https://www.cnblogs.com/wtzbk/p/15604370.html