实验五----Docker编排与部署
本实验按 1 个 manager 节点 + 2 个 worker 节点 的标准流程进行。Docker Swarm 模式是 Docker Engine 内置的集群编排能力,不需要额外安装单独的编排器
**先把一台 Ubuntu 虚拟机装好 Docker,再关机,用 VMware 做两次完整克隆 **
先关机,在 VMware Workstation 里,对这台原始虚拟机执行:
- 右键虚拟机
- 选择 Manage / 管理
- 选择 Clone / 克隆
- 选择按当前状态克隆
- 选择 Full Clone / 完整克隆
- 第一次命名为
worker1 - 再重复一次,第二次命名为
worker2




VMware 官方文档说明,克隆向导会帮你完成克隆流程;克隆后的虚拟机会成为独立虚拟机,并且拥有不同的 MAC 地址和 UUID。分别启动三台机器并改主机名
把原机当作 manager,两台克隆机分别做 worker1、worker2。进入每台 Ubuntu 后执行:
原机:
plain
sudo hostnamectl set-hostname manager
重命名需重启终端即可看到
第一台克隆机:
plain
sudo hostnamectl set-hostname worker1


第二台克隆机:
plain
sudo hostnamectl set-hostname worker2


然后都执行:
plain
exec bash
hostname



这样三台机器的终端提示名就会区分开,后面做 Swarm 不会乱
1. 配置主机映射
在三台虚拟机上分别编辑 /etc/hosts,保证节点之间可以通过主机名互相访问。建议三台主机名分别设置为 manager、worker1、worker2
查看机器ip:
bash
ip a
在三台机器上执行:
bash
sudo vim /etc/hosts
添加如下内容:
bash
# Docker Swarm 节点映射
192.168.255.149 manager
192.168.255.150 worker1
192.168.255.151 worker2

保存后分别测试连通性:
bash
ping -c 3 manager
ping -c 3 worker1
ping -c 3 worker2

若能够正常解析并连通,说明主机映射配置成功。Swarm 多节点实验要求各节点之间网络可达;另外,Swarm/overlay 网络涉及的关键端口至少包括 2377/tcp、7946/tcp+udp 和 4789/udp,需要在实验环境中放通。(Docker Documentation)
2. 配置 Docker API(三台机器都做)
- 创建 systemd override
bash
sudo mkdir -p /etc/systemd/system/docker.service.d/
sudo vim /etc/systemd/system/docker.service.d/override.conf
打开后写入这段:
bash
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock -H fd:// -H tcp://0.0.0.0:2375

- 重载并重启
bash
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl status docker

- 看 dockerd 启动参数
bash
ps -ef | grep dockerd
应该出现:
plain
-H tcp://0.0.0.0:2375

- 验证 2375
bash
ss -lntp | grep 2375

3. 拉取实验所需镜像
Swarm 模式本身已经集成在 Docker Engine 中,因此不需要单独拉取"Swarm 镜像";这里按实验内容,实际需要拉取的是 service 运行镜像 和 Portainer 镜像 。(Docker Documentation)
在 manager 节点(docker1)执行:
bash
docker pull nginx:latest
docker pull portainer/portainer-ce:lts
docker pull portainer/agent:lts
docker images

4. 初始化集群
在 manager 节点执行 Swarm 初始化命令。官方文档说明,docker swarm init 会把当前节点切换到 Swarm 模式,将其设置为 manager,并默认监听 2377 端口,同时生成 worker 和 manager 的加入令牌。(Docker Documentation)
在 manager 节点(docker1)执行:
bash
# 这里的ip是你docker1的IP
docker swarm init --advertise-addr 192.168.255.149
执行成功后,终端会输出类似如下提示:
bash
Swarm initialized: current node (...) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-xxxxx 192.168.100.10:2377

!!注意看这一步结果给的token是什么,下一步要用
5. node 节点加入集群
Swarm 初始化完成后,在 worker1 和 worker2 上分别执行 manager 输出的 docker swarm join 命令。Docker 官方说明,节点会根据你使用的 token 加入为 worker 或 manager。(Docker Documentation)
在两个 worker 节点执行:
bash
docker swarm join --token SWMTKN-1-5sxzm7v9odf15jvfxbos0gq5u9lx325ee2lu51zuzavyf99rgh-0uloxandcdm0r78pp7ioxyrku 192.168.255.149:2377


两台 worker 都执行完成后,说明节点已经成功加入集群。
6. 验证集群
回到 manager 节点,使用以下命令查看集群状态:
bash
docker node ls
docker info | grep -i swarm
如果配置正确,应看到:
- manager 节点角色为
Leader - worker 节点状态为
Ready Swarm: active

7. 安装 Portainer(Docker 的图形化管理工具)
Portainer 官方在 Swarm 环境下推荐通过 Portainer Server + Agent 的 stack 方式部署。官方安装文档直接提供了 portainer-agent-stack.yml,使用 docker stack deploy 即可完成部署。(Portainer 文档)
在 manager 节点执行:
bash
sudo apt install -y curl
cd ~
curl -L https://downloads.portainer.io/ce-lts/portainer-agent-stack.yml -o portainer-agent-stack.yml
ls -l portainer-agent-stack.yml # 检查文件
docker stack deploy -c portainer-agent-stack.yml portainer
docker service ls

如果要检查部署更细节,还可以执行:
bash
docker stack ls
docker stack services portainer
docker stack ps portainer

当看到 portainer_portainer 和 portainer_agent 相关服务正常运行时,说明 Portainer 已部署成功
8. 浏览器登录 Portainer
Portainer 官方在 Swarm 安装说明中默认通过 9443 提供 Web 界面。部署成功后,在宿主机浏览器或物理机浏览器访问 manager 节点:(Portainer 文档)
plain
https://192.168.255.149:9443
首次访问会要求创建管理员账号,设置用户名与密码后进入 Portainer 控制台。
设置速度要快!不然超时系统会自锁。如果自锁在manager强制重启就行,输入:
docker service update --force portainer_portainer
我设置的密码是123456789zxy


9. 运行 service
Swarm 中最核心的对象是 service 。Docker 官方说明,service 用来描述"希望运行多少个任务副本、使用什么镜像、开放哪些端口"等期望状态。(Docker Documentation)
在 manager 节点运行一个 nginx service:
bash
docker service create --name web --replicas 3 -p 8080:80 nginx:latest
然后查看 service 和任务分布情况:
bash
docker service ls
docker service ps web
可以看到:
web服务已经创建- 副本数为
3/3 - 多个 task 被分配到不同节点运行

10. service 的弹性伸缩
Docker 官方提供 docker service scale 命令,用于修改 service 的副本数;Swarm 会自动把实际状态调整到你设定的期望状态。(Docker Documentation)
将副本数从 3 扩展到 5:
在 manager 上执行:
bash
docker service scale web=5
docker service ls
docker service ps web
若成功,可看到:
- service 副本数变为
5/5 - 新任务自动分布到集群节点上

如果要缩容,也可以执行:
bash
docker service scale web=2
docker service ls
docker service ps web

11. 调度节点
Swarm 支持使用节点标签和约束条件进行调度。Docker 官方说明,可以先用 docker node update --label-add 给节点打标签,再在 docker service create 或 docker service update 中使用 --constraint 限制 service 只能运行在满足条件的节点上。(Docker Documentation)
全部 manager 节点执行:
为两个 worker 添加标签:
bash
docker node update --label-add role=web worker1
docker node update --label-add role=web worker2

查看节点标签:
bash
docker node inspect worker1 --pretty
docker node inspect worker2 --pretty


然后更新 service,只允许它运行在 role=web 的节点上:
bash
docker service update --constraint-add 'node.labels.role==web' web
docker service ps web

额外补充:如果你还想让 manager 不再承载业务任务,可以把 manager 设置为 drain:
bash
docker node update --availability drain manager
docker node ls
官方说明,drain 状态的节点不再接收新的任务调度。(Docker Documentation)
12. 外部网络访问 service
Swarm 的 routing mesh 允许所有节点接受对 service 已发布端口的访问请求,即使该节点本地没有运行该 service 的 task,也可以把流量转发给可用副本。Docker 官方文档明确说明,Swarm 中所有节点都会参与 ingress routing mesh。(Docker Documentation)
在浏览器中访问以下地址:
plain
http://192.168.255.149:8080
http://192.168.255.150:8080
http://192.168.255.151:8080
如果 service 正常运行,就能打开 nginx 默认页面。
这一步可以证明:
- service 已成功发布端口
- routing mesh 已生效
- 外部客户端可以通过任意节点访问 Swarm 服务 (Docker Documentation)
