使用 Docker Machine 和 Swarm 构建集群
1. Docker Machine 基础操作
Docker Machine 是用于构建和管理基于 Docker 的机器集群的强大工具。在使用 Docker Machine 时,有一些基础操作是我们需要掌握的。
首先是文件复制和查看操作。我们可以使用
docker-machine scp
命令在不同主机之间复制文件,使用
docker-machine ssh
命令查看目标主机上的文件。例如,将
host1
上的
dog.file
文件复制到
host2
上,并查看该文件内容:
docker-machine scp host1:dog.file host2:dog.file
docker-machine ssh host2 "cat dog.file"
这些与 SSH 相关的命令对于自定义配置、检索卷内容以及执行其他与主机相关的维护操作至关重要。
另外,启动、停止(或终止)和移除机器的命令与操作容器的命令类似。
docker-machine
提供了四个子命令:
start
、
stop
、
kill
和
rm
。示例如下:
docker-machine stop host2
docker-machine kill host3
docker-machine start host2
docker-machine rm host1 host2 host3
2. 配置 Docker 客户端以连接远程守护进程
Docker Machine 会记录和跟踪其所管理机器的状态。它可以用于在远程主机上升级 Docker、打开 SSH 连接以及在主机之间安全地复制文件。然而,像
docker
命令行界面或
docker-compose
这样的 Docker 客户端一次只能连接到一个 Docker 主机。因此,Docker Machine 的一个重要功能是为活动的 Docker 主机生成环境配置。
以下是 Docker Machine、Docker 客户端和环境之间的关系:
graph LR
A[Docker Machine 状态文件] --> B[Docker Machine (CLI)]
B --> C[环境变量]
C --> D[Docker (CLI)]
D --> E[从环境变量获取连接信息]
B --> F[设置连接特定机器的环境变量]
A --> G[记录所有管理机器的状态]
要开始管理 Docker 环境,我们可以创建新的机器并激活其中一个。首先使用
create
命令创建机器:
docker-machine create --driver virtualbox machine1
docker-machine create --driver virtualbox machine2
为了激活新机器,我们需要更新环境。Docker Machine 提供了
env
子命令,它会尝试自动检测用户的 shell 并打印配置环境以连接到特定机器的命令。如果无法自动检测,可以使用
--shell
标志指定特定的 shell:
docker-machine env machine1
docker-machine env --shell powershell machine1
docker-machine env --shell cmd machine1
docker-machine env --shell fish machine1
docker-machine env --shell bash machine1
例如,在 POSIX 兼容的 shell 中设置
machine1
为活动机器:
eval "$(docker-machine env machine1)"
在 Windows 的 PowerShell 中,可以使用以下命令:
docker-machine env --shell=powershell machine1 | Invoke-Expression
我们可以使用
active
子命令或查看
ls
子命令输出中的
ACTIVE
列来验证是否成功激活了
machine1
:
docker-machine active
docker-machine ls
3. 使用多台机器工作
创建几个容器,体验使用多台机器的简单性和微妙之处。首先,在活动机器上拉取一个镜像:
docker pull dockerinaction/ch12_painted
需要注意的是,拉取到活动机器上的镜像只会存在于该机器上。如果要在整个集群中使用某个通用镜像,需要在每台机器上分别拉取。
在启动容器之前,我们可以切换活动机器并列出镜像:
eval "$(docker-machine env machine2)"
docker images
由于
machine2
之前没有安装过任何镜像,
images
子命令的输出应该为空。
接下来,在
machine2
上拉取镜像并运行容器:
docker run -t dockerinaction/ch12_painted \
Tiny turtles tenderly touch tough turnips.
比较
machine1
和
machine2
上的容器列表:
docker ps -a
eval "$(docker-machine env machine1)"
docker ps -a
由于
machine1
上还没有创建任何容器,列表应该为空。
这个简单的示例展示了使用多台机器的便捷性,但也说明了手动连接、编排和调度大量机器上的工作可能会很混乱。除非特别查询活动主机,随着使用的机器数量增加,很难跟踪 Docker 客户端的指向。
虽然可以利用 Docker Compose 简化编排,但 Compose 也像其他 Docker 客户端一样,只会使用环境配置所指向的 Docker 守护进程。在继续之前,我们可以清理环境,移除
machine1
和
machine2
:
docker-machine rm machine1 machine2
4. 引入 Docker Swarm
Docker Machine 适合构建和管理机器集群,而 Docker Compose 为基于 Docker 容器的服务提供编排功能。然而,仍然存在两个主要问题:在 Docker 机器集群中调度容器以及发现这些服务的部署位置。Docker Swarm 可以解决这些问题。
4.1 调度和服务发现问题
当人们遇到第一个问题时,可能会问:“应该选择哪台机器来运行给定的容器?” 在机器集群中组织需要运行的容器并非易事。过去,我们会将不同的软件部署到不同的机器上,以机器为部署单元,自动化更容易实现。但现在,使用 Linux 容器进行隔离和 Docker 进行容器工具化,主要关注的是资源使用效率、每台机器的硬件性能特征和网络局部性。基于这些因素选择机器的过程称为调度。
解决调度问题后,又会面临新的问题:“现在我的服务已经部署在网络中的某个地方,其他服务如何找到它?” 当将调度委托给自动化过程时,无法事先知道服务的部署位置。传统上,服务器软件使用 DNS 来解析已知名称到一组网络位置,但写入数据是另一个问题。在特定位置宣传服务的可用性称为注册,解析命名服务的位置称为服务发现。
4.2 使用 Docker Machine 构建 Swarm 集群
Swarm 集群由两种类型的机器组成:运行 Swarm 管理模式的机器称为管理器(manager),运行 Swarm 代理的机器称为节点(node)。
使用 Docker Machine 构建 Swarm 集群与创建独立的 Docker 机器类似,只是在使用
create
子命令时需要添加一些额外的命令行参数:
-
--swarm
:表示创建的机器应运行 Swarm 代理软件并加入集群。
-
--swarm-master
:指示 Docker Machine 将新机器配置为 Swarm 管理器。
-
--swarm-discovery
:指定集群的唯一标识符。
创建 Swarm 集群的步骤如下:
1. 创建集群标识符:
docker-machine create --driver virtualbox local
eval "$(docker-machine env local)"
docker run --rm swarm create
最后一个命令会输出一个十六进制的标识符,将其复制并替换后续命令中的
<TOKEN>
。
- 创建一个三节点的 Swarm 集群:
docker-machine create \
--driver virtualbox \
--swarm \
--swarm-discovery token://<TOKEN> \
--swarm-master \
machine0-manager
docker-machine create \
--driver virtualbox \
--swarm \
--swarm-discovery token://<TOKEN> \
machine1
docker-machine create \
--driver virtualbox \
--swarm \
--swarm-discovery token://<TOKEN> \
machine2
可以使用
docker-machine ls
子命令的输出识别这些机器是否属于 Swarm 集群,集群管理器的名称会显示在
SWARM
列中:
| NAME | URL | SWARM |
|------------------|---------------------------|----------------------------|
| machine0-manager | tcp://192.168.99.106:2376 | machine0-manager (manager) |
| machine1 | tcp://192.168.99.107:2376 | machine0-manager |
| machine2 | tcp://192.168.99.108:2376 | machine0-manager |
一个 Docker 客户端可以单独配置以与这些机器中的任何一个一起工作,但当配置客户端使用管理器上的 Swarm 端点时,就可以将集群视为一个大机器来工作。
4.3 Swarm 扩展 Docker 远程 API
Docker Swarm 管理器端点公开 Swarm API,Swarm 客户端可以使用该 API 控制或检查集群。更重要的是,Swarm API 是 Docker 远程 API 的扩展,这意味着任何 Docker 客户端都可以直接连接到 Swarm 端点,并将集群视为单个机器。
以下是 Swarm 管理器将 Docker 客户端指定的工作委托给集群中节点的过程:
graph LR
A[Docker 客户端] --> B[Swarm 管理器 (端口 3376)]
B --> C[选择目标节点]
C --> D[连接到节点的 Docker 引擎 (端口 2376)]
D --> E[调度工作]
F[Machine 0 - 管理器] --> B
G[Machine 1] --> H[Swarm 代理 (token://12341234)]
H --> D
I[Machine 2] --> J[Swarm 代理 (token://12341234)]
J --> D
配置环境以使用上一节创建的 Swarm 集群。在 POSIX 兼容的 shell 中,运行以下命令:
eval "$(docker-machine env --swarm machine0-manager)"
在 PowerShell 中,运行:
docker-machine env --swarm machine0-master | Invoke-Expression
当环境配置为访问 Swarm 端点时,
docker
命令行界面将使用 Swarm 功能。例如,使用
docker info
命令将报告整个集群的信息,而不是单个守护进程的详细信息:
Containers: 4
Images: 3
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
machine0-manager: 192.168.99.110:2376
? Containers: 2
? Reserved CPUs: 0 / 1
? Reserved Memory: 0 B / 1.022 GiB
? Labels: executiondriver=native-0.2, kernelversion=4.0.9-...
machine1: 192.168.99.111:2376
? Containers: 1
? Reserved CPUs: 0 / 1
? Reserved Memory: 0 B / 1.022 GiB
? Labels: executiondriver=native-0.2, kernelversion=4.0.9-...
machine2: 192.168.99.112:2376
? Containers: 1
? Reserved CPUs: 0 / 1
? Reserved Memory: 0 B / 1.022 GiB
? Labels: executiondriver=native-0.2, kernelversion=4.0.9-...
CPUs: 3
Total Memory: 3.065 GiB
Name: 942f56b2349a
接下来,在集群中创建一个容器:
docker run -t -d --name hello-swarm \
dockerinaction/ch12_painted \
Hello Swarm
可以使用
logs
子命令查看容器的输出:
docker logs hello-swarm
使用
ps
子命令并过滤容器名称,可以发现容器所在的机器:
docker ps -a -f name=hello-swarm
在创建类似的容器时,集群可能会将其调度到不同的主机上。在进行此操作之前,再次检查集群信息:
docker info
注意集群中的容器和镜像数量:
Containers: 5
Images: 4
Containers
和
Images
的数量是集群的非重复总和。由于集群中有三个节点,需要三个代理容器和一个管理器容器,剩下的一个容器就是刚刚创建的
hello-swarm
容器。四个镜像由三个
swarm
镜像副本和一个
dockerinaction/ch12_painted
镜像副本组成。需要注意的是,使用
run
命令创建容器时,所需的镜像只会在调度容器的主机上拉取。
使用 Docker Machine 和 Swarm 构建集群
5. Swarm 调度算法与实践
在使用 Swarm 集群时,调度算法起着关键作用,它决定了容器将被部署到哪个节点上。Swarm 提供了多种调度算法,常见的有
spread
、
binpack
和
random
。
- spread :该算法会尽量将容器均匀地分布到各个节点上,以充分利用集群的资源,避免某个节点负载过高。
- binpack :此算法会尝试将容器集中部署到尽可能少的节点上,以提高资源的利用率,减少空闲资源。
- random :随机选择一个节点来部署容器。
我们可以在创建 Swarm 集群时通过相关参数指定调度算法。例如,在创建 Swarm 管理器时,使用
--swarm-strategy
参数:
docker-machine create \
--driver virtualbox \
--swarm \
--swarm-discovery token://<TOKEN> \
--swarm-master \
--swarm-strategy spread \
machine0-manager
为了更好地理解调度算法的作用,我们可以进行以下实践。首先,确保环境已配置为使用 Swarm 集群:
eval "$(docker-machine env --swarm machine0-manager)"
然后,创建多个容器:
for i in {1..5}; do
docker run -t -d --name container-$i \
dockerinaction/ch12_painted \
"Container $i is running"
done
使用
docker ps -a
命令查看容器的分布情况:
docker ps -a
通过观察容器所在的节点,我们可以直观地看到调度算法的效果。如果使用的是
spread
算法,容器应该会相对均匀地分布在各个节点上。
6. 服务发现与负载均衡
在 Swarm 集群中,服务发现和负载均衡是非常重要的功能。当我们在集群中部署多个服务实例时,其他服务需要能够方便地找到这些实例,并且能够实现负载均衡,以提高系统的性能和可靠性。
Swarm 内置了服务发现和负载均衡机制。当我们创建一个服务时,Swarm 会为该服务分配一个虚拟 IP 地址(VIP),其他服务可以通过这个 VIP 地址来访问该服务。
以下是创建一个服务的示例:
docker service create \
--name my-service \
--replicas 3 \
dockerinaction/ch12_painted \
"My service is running"
在这个示例中,我们创建了一个名为
my-service
的服务,并且指定了 3 个副本。Swarm 会自动将这些副本调度到集群中的不同节点上,并为该服务分配一个 VIP 地址。
其他服务可以通过这个 VIP 地址来访问
my-service
。例如,我们可以创建一个测试容器来访问
my-service
:
docker run -it --rm \
alpine:latest \
wget -qO- http://<my-service-VIP>
Swarm 会自动将请求负载均衡到
my-service
的各个副本上。
7. 集群的监控与维护
为了确保 Swarm 集群的稳定运行,我们需要对集群进行监控和维护。以下是一些常见的监控和维护操作:
7.1 监控集群状态
我们可以使用
docker info
命令来查看集群的基本信息,包括容器数量、镜像数量、节点信息等:
docker info
还可以使用
docker node ls
命令查看集群中各个节点的状态:
docker node ls
该命令会列出所有节点的 ID、主机名、状态等信息。
7.2 节点管理
在集群运行过程中,可能需要对节点进行添加、删除或更新操作。
-
添加节点
:使用
docker-machine create命令创建新的节点,并使用--swarm和--swarm-discovery参数将其加入到集群中。 -
删除节点
:首先将节点从集群中移除,然后使用
docker-machine rm命令删除该节点。例如:
docker node rm <node-ID>
docker-machine rm <machine-name>
-
更新节点
:可以使用
docker-machine ssh命令登录到节点上,然后进行软件更新等操作。
7.3 故障处理
当集群中出现故障时,我们需要及时进行处理。例如,如果某个节点出现故障,可以将其从集群中移除,并添加一个新的节点。
以下是一个简单的故障处理流程图:
graph TD
A[检测到节点故障] --> B[将故障节点从集群中移除]
B --> C[创建新节点]
C --> D[将新节点加入集群]
8. 总结
通过本文的介绍,我们了解了如何使用 Docker Machine 和 Swarm 构建和管理集群。Docker Machine 提供了便捷的机器创建和管理功能,而 Swarm 则解决了容器调度和服务发现的问题。
在实际应用中,我们可以根据具体的需求选择合适的调度算法,利用服务发现和负载均衡机制提高系统的性能和可靠性。同时,要做好集群的监控和维护工作,及时处理故障,确保集群的稳定运行。
希望本文能够帮助你更好地理解和使用 Docker Machine 和 Swarm,构建出高效、稳定的容器集群。
Docker Machine与Swarm构建集群指南
超级会员免费看
127

被折叠的 条评论
为什么被折叠?



