如何在 Ubuntu 16.04 上使用 Docker Swarm 创建 Docker 容器集群
介绍
Docker Swarm 是用于部署 Docker 主机集群的 Docker 原生解决方案。您可以使用它来快速部署在本地计算机或支持的云平台上运行的 Docker 主机集群。
在 Docker 1.12 之前,设置和部署 Docker 主机集群需要您使用外部键值存储(如 Consul)来进行服务发现。然而,对于 Docker 1.12,不再需要外部发现服务,因为 Docker 带有开箱即用的内存中键值存储。
在本教程中,您将学习如何在 DigitalOcean 上使用 Docker 1.12 的 Swarm 功能部署 Docker 机器集群。集群中的每个 Docker 节点都将运行 Ubuntu 16.04。虽然您可以运行由数十个、数百个或数千个 Docker 主机组成的集群,但我们将在本教程中设置的集群将由一个管理器节点和两个工作节点组成,总共三个集群成员.完成本教程后,您将能够轻松地向集群添加更多节点。
先决条件
对于本教程,您需要:
- 一台安装了 Docker 的本地机器。您的本地机器可以运行任何 Linux 发行版,甚至是 Windows 或 macOS。对于 Windows 和 macOS,请使用如何在 Ubuntu 16.04 上安装和使用 Docker 安装 Docker 以获取说明。
- 一个 DigitalOcean API 令牌。如果您没有,请使用本指南生成它。生成令牌时,请确保它具有读写范围。这是默认设置,因此如果您在生成它时不更改任何选项,它将具有读写功能。为了更易于在命令行上使用,请务必将令牌分配给该文章中给出的变量。
- 在您的本地计算机上安装 Docker Machine,您将使用它来创建三台主机。在 Windows 和 macOS 上,Docker 安装包括 Docker Machine。如果您在本地运行 Ubuntu 16.04,请参阅如何在 Ubuntu 16.04 上使用 Docker Machine 配置和管理远程 Docker 主机以获取安装说明。
第 1 步 - 配置集群节点
我们需要为集群创建多个 Docker 主机。作为复习,以下命令提供了一个 Dockerized 主机,其中 $DOTOKEN
是一个评估您的 DigitalOcean API 令牌的环境变量:
- docker-machine create --driver digitalocean --digitalocean-image ubuntu-16-04-x64 --digitalocean-access-token $DOTOKEN machine-name
想象一下,必须这样做才能建立一个由至少三个节点组成的集群,一次配置一台主机。
我们可以使用此命令并结合一些简单的 Bash 脚本来自动化配置任意数量的 Docker 主机的过程。在本地机器上执行此命令以创建三个 Docker 主机,分别命名为 node-1
、node-2
和 node-3
:
- for i in 1 2 3; do docker-machine create --driver digitalocean \
- --digitalocean-image ubuntu-16-04-x64 \
- --digitalocean-access-token $DOTOKEN node-$i; done
命令成功完成后,您可以通过访问 DigitalOcean 仪表板或键入以下命令来验证是否已创建所有机器:
- docker-machine ls
输出应类似于以下内容,它应作为查找节点 IP 地址的快速参考:
OutputNAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-1 - digitalocean Running tcp://111.111.111.111:2376 v1.12.2
node-2 - digitalocean Running tcp://111.111.111.112:2376 v1.12.2
node-3 - digitalocean Running tcp://111.111.222.222:2376 v1.12.2
此时,所有三个 Dockerized 主机都已创建,并且您拥有每个主机的 IP 地址。它们也都在运行 Docker 1.12.x,但还不是 Docker 集群的一部分。在接下来的步骤中,我们将配置防火墙规则,使节点作为集群的成员运行,选择一个节点并将其设为 Docker Swarm 管理器,并将其余节点配置为 Docker Swarm worker。
第 2 步 — 配置防火墙规则以允许 Docker Swarm 流量
一个集群必须至少有一个节点充当管理器,但对于生产设置,建议使用三个管理器。对于此设置,让我们选择第一个节点并将其设为 Swarm 管理器。另外两个节点将是工作节点。
必须在将成为集群一部分的节点上打开某些网络端口,集群才能正常运行。这需要配置防火墙以允许流量通过这些端口。因为可以使用三种不同的防火墙应用程序来完成该任务,所以您需要在节点上为每个防火墙应用程序执行的命令已记录在单独的文章中。按照本指南为每台主机配置防火墙。在管理器上打开适当的端口,然后重复打开两个客户端节点上的端口。
完成此步骤后,您可以初始化集群管理器。
第 3 步 — 初始化集群管理器
我们已经决定 node-1
将成为我们的集群管理器,因此从您的本地机器登录到该节点:
- docker-machine ssh node-1
命令提示符将更改以反映您现在已登录到该特定节点的事实。要将节点配置为 Swarm 管理器,请键入以下命令:
- docker swarm init --advertise-addr node_ip_address
node_ip_address
是节点的 IP 地址。您可以从 docker-machine ls
的输出或您的 DigitalOcean 仪表板中获取它。
您会看到如下所示的输出:
OutputSwarm initialized: current node (a35hhzdzf4g95w0op85tqlow1) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-3k7ighcfs9352hmdfzh31t297fd8tdskg6x6oi8kpzzszznffx-6kovxm3akca2qe3uaxtu07fj3 \
111.111.111.111:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
输出中是节点的 ID,在此示例中为 a35hhzdzf4g95w0op85tqlow1,以及有关如何将其他节点添加到集群的说明。
所以现在你有一个配置了管理器的 Docker Swarm。让我们将剩余的节点添加为工人。
第 4 步 — 将节点添加到集群
要完成此步骤,您可能需要打开另一个终端并暂时保留您用于登录 Swarm 管理器的终端选项卡或窗口。
首先,从本地计算机连接到 node-2
:
- docker-machine ssh node-2
然后执行这条命令,其中your_swarm_token
是你在上一步创建集群时收到的token,manager_node_ip_address
是Swarm manager的IP:
- docker swarm join \
- --token your_swarm_token \
- manager_node_ip_address:2377
命令成功执行后,您将看到以下响应:
OutputThis node joined a swarm as a worker.
注销 node-2
,然后使用 node-3
重复此过程以将其添加到您的集群.
您现在已将两个工作节点添加到集群中。如果防火墙规则配置正确,您现在拥有一个正常运行的 Docker Swarm,所有节点都已同步。
第 5 步 — 管理集群
管理节点和工作节点分配到集群后,所有 Docker Swarm 管理命令都必须在管理节点上执行。因此,返回到您用于添加管理器的终端并输入此命令以查看集群的所有成员:
- docker node ls
输出应与此类似:
OutputID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
2qhg0krj00i4d3as2gpb0iqer node-2 Ready Active
6yqh4bjki46p5uvxdw6d53gc0 node-3 Ready Active
a35hhzdzf4g95w0op85tqlow1 * node-1 Ready Active Leader
此输出显示我们正在处理一个 3 节点 Docker Swarm 及其节点——一个管理器和两个工人。要查看可以在管理器节点上运行的其他管理命令,请键入:
- docker node --help
有关集群的详细信息,您可以在管理器或工作器上使用以下命令(这是一个通用的 Docker 命令):
- docker info
输出应该是这种类型的,并且应该指示集群的状态(活动的或挂起的)、集群中的节点数以及特定节点是管理器还是工作器。
Output...
Network: bridge host null overlay
Swarm: active
NodeID: a35hhzdzf4g95w0op85tqlow1
Is Manager: true
ClusterID: f45u0lh7ag4qsl4o56yfbls31
Managers: 1
Nodes: 3
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Node Address: 104.236.239.4
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-38-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
...
如果您在工作节点上重复相同的命令,则 Is Manager 行应显示 false
。
提示:您可以随时在集群中添加或删除节点。此外,工作节点可以提升为管理器,管理器可以转换为工作器。
现在让我们在集群上运行一个服务。
第 6 步 — 在 Docker Swarm 中运行服务
现在您已经启动并运行了 Docker Swarm,让我们运行一个测试容器并查看管理器如何处理它。在运行 Docker Engine 1.12 或更新版本的机器上,使用 docker service
命令将容器部署为服务。和docker node
命令一样,docker service
命令只能在manager节点上执行。
那么让我们使用官方的 Nginx 容器镜像部署一个 Web 服务器服务:
- docker service create -p 80:80 --name webserver nginx
在此命令中,我们将 Nginx 容器中的端口 80
映射到集群上的端口 80
,以便我们可以从任何地方访问默认的 Nginx 页面。
要查看集群上正在运行哪些服务,请键入:
- docker service ls
输出应采用这种形式。 REPLICAS 列显示有多少服务实例正在运行:
OutputID NAME REPLICAS IMAGE COMMAND
0ymctkanhtc1 webserver 1/1 nginx
您可以使用 docker service ps
后跟服务名称来确定服务在哪些节点上运行。
- docker service ps webserver
输出应类似于以下内容:
OutputID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
39yprxsaaekuif951cl0o4wau webserver.1 nginx node-1 Running Running 7 hours ago
在此示例中,webserver
服务在 node-1
上运行。由于这是在默认端口上运行的 Web 服务器,您可以通过将浏览器指向 http://node-1_ip_address
来访问它。试一试。你会看到 Nginx 的默认页面。
借助网状网络的魔力,可以在集群的任何其他节点上访问在一个节点上运行的服务。例如,还可以通过将浏览器指向集群中任何节点的 IP 地址来访问此 Nginx 服务,而不仅仅是运行它的节点。试一试。
Docker Swarm 的另一个特性是扩展服务的能力,即启动服务的额外实例。假设我们想要将之前启动的 webserver
服务扩展到五个实例。为此,我们只需键入以下命令,系统将再创建四个实例:
- docker service scale webserver=5
docker service ps
的输出将显示新实例在哪些节点上启动:
OutputID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
39yprxsaaekuif951cl0o4wau webserver.1 nginx node-1 Running Running 8 hours ago
1er2rbrnj6ltanoe47mb653wf webserver.2 nginx node-3 Running Running 14 seconds ago
evassgyvruh256ebv5pj3bqcz webserver.3 nginx node-3 Running Running 14 seconds ago
d453agrdpgng47klbl6yfjnka webserver.4 nginx node-1 Running Running 18 seconds ago
2hsdevx178rg15gqxhzrsnmg6 webserver.5 nginx node-2 Running Running 14 seconds ago
这表明四个新实例中的两个在 node-3
上启动,一个在 node-1
上启动,另一个在 node-2
上启动。
最后,如果服务出现故障,它会自动在同一节点或不同节点上重新启动(如果原始节点不再可用)。
结论
您已经看到使用 Docker Engine 1.12 和新的 Swarm 模式设置 Docker Swarm 是多么容易。您还看到了如何在集群上执行一些管理任务。但还有更多。要查看可用的 Docker Swarm 命令,请在您的 Swarm 管理器上执行以下命令。
- docker swarm --help
有关 Docker Swarm 的更多信息,请访问 DigitalOcean 上与 Docker 相关的文章。