Docker 学习笔记(六):多容器管理与集群部署实践
Docker
Docker-compose
单个 Dockerfile 可定义单容器应用,但日常工作中,Web 项目等常需 Web 服务、数据库、负载均衡等多容器配合,手动按序启停容器会导致维护量大、效率低。
Docker Compose 是高效的多容器管理工具,通过单个 docker-compose.yml
(YAML 格式)文件定义关联资源集,轻松管理容器。
其有两个核心概念:
- 服务(Service):一个应用的容器,可包含多个运行相同镜像的容器实例。
- 项目(Project):由一组关联服务容器组成的完整业务单元,定义于
docker-compose.yml
中。
Compose 默认管理对象为项目,通过子命令对项目内容器进行生命周期管理。它最初由 Python 编写,后用 Go 重写,调用 Docker API 管理容器,支持所有兼容 Docker API 的平台。
命令说明
[root@docker ~]# docker compose -h
Flag shorthand -h has been deprecated, please use --helpUsage: docker compose [OPTIONS] COMMANDDefine and run multi-container applications with DockerOptions:--all-resources Include all resources, even those not used by services--ansi string Control when to print ANSI control characters("never"|"always"|"auto") (default "auto")--compatibility Run compose in backward compatibility mode--dry-run Execute command in dry run mode--env-file stringArray Specify an alternate environment file-f, --file stringArray Compose configuration files--parallel int Control max parallelism, -1 for unlimited (default -1)--profile stringArray Specify a profile to enable--progress string Set type of progress output (auto, tty, plain,quiet) (default "auto")--project-directory string Specify an alternate working directory(default: the path of the, first specified, Composefile)-p, --project-name string Project nameCommands:attach Attach local standard input, output, and error streams to a service's running containerbuild Build or rebuild servicesconfig Parse, resolve and render compose file in canonical formatcp Copy files/folders between a service container and the local filesystemcreate Creates containers for a servicedown Stop and remove containers, networksevents Receive real time events from containersexec Execute a command in a running containerimages List images used by the created containerskill Force stop service containerslogs View output from containersls List running compose projectspause Pause servicesport Print the public port for a port bindingps List containerspull Pull service imagespush Push service imagesrestart Restart service containersrm Removes stopped service containersrun Run a one-off command on a servicescale Scale servicesstart Start servicesstats Display a live stream of container(s) resource usage statisticsstop Stop servicestop Display the running processesunpause Unpause servicesup Create and start containersversion Show the Docker Compose version informationwait Block until the first service container stopswatch Watch build context for service and rebuild/refresh containers when files are updatedRun 'docker compose COMMAND --help' for more information on a command.
[root@docker ~]# docker compose version
Docker Compose version v2.27.0
Compose 模板
模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令 跟 docker run 相关参数的含义都是类似的。
默认的模板文件名称为 docker-compose.yml ,格式为 YAML 格式。
模板文件结构
- version:用来定义模板文件的版本,不同版本的模板,格式也不一样。
- 资源列表:用来定义资源清单,包括service、secret、network、volume等。
- 注释行: # 开头的注释行。
示例:使用版本3模板,定义一个使用httpd镜像的services。
version: "3"
services:webapp:image: httpd
实战-Wordpress
方法一:
用docker run
[root@docker ~]# docker pull mysql[root@docker ~]# docker pull wordpress[root@docker ~]# docker run -tid --name db --restart always -v /db:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 -e MYSQL_DATABASE=wordpress mysql
8da76295432326d26a11844fef60042756234194b562d10a9edc5346d78e9da2
[root@docker ~]# docker run -tid --name blog -v /web:/var/www/html -p 80:80 --link db -e WORDPRESS_DB_HOST=db -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=123 -e WORDPRESS_DB_NAME=wordpress wordpress
fcaa6809d5c6d860db16c2fe845bf1b27979e003ce652b27d9f637a67dadf79e[root@docker ~]# docker ps
测试
方法二:
用docker compose
# 先删除之前的环境
[root@docker ~]# docker rm -f $(docker ps -aq)
fcaa6809d5c6
8da762954323# 通过docker compose实现多个容器一起启动
[root@docker wordpress]# vim docker-compose.yml
[root@docker wordpress]# cat docker-compose.yml
services:blog: #服务名字,相当于docker run的时候指定的一个名称image: wordpress:latest #必选,镜像的名字restart: alwayslinks:- dbports: #可选,等价于 docker container run 里的 -p 选项指定端口映射- "80:80"environment: #可选,等价于 docker run 里的 --env 选项设置环境变量- WORDPRESS_DB_HOST=db- WORDPRESS_DB_USER=root- WORDPRESS_DB_PASSWORD=123- WORDPRESS_DB_NAME=wordpressdb:image: mysql:latestrestart: alwaysenvironment:- MYSQL_ROOT_PASSWORD=123- MYSQL_DATABASE=wordpress# 写完检查下语法
[root@docker wordpress]# docker compose config -q# 后端运行
[root@docker wordpress]# docker compose up -d
[+] Running 3/3✔ Network wordpress_default Created 0.3s✔ Container wordpress-db-1 Started 0.5s✔ Container wordpress-blog-1 Started
# 查看
[root@docker wordpress]# docker ps
测试
docker图形界面管理
DockerUI 容器管理器的安装与使用
简介:
DockerUI是一个易用且轻量化的 Docker 管理工具,通过 Web 界面的操作,更方便对于 Docker 指令不 熟悉的用户更容易操作 Docker。
功能:
-
Docker主机管理:数据卷管理,镜像管理,容器管理,构建管理,仓库配置管理,网络配置管理
-
Docker Swarm集群管理:集群概要信息,节点管理,Service管理,任务管理,密码管理,配置管 理
镜像:
使用的镜像来自于@joinsunsoft ,他发布在Docker Hub的镜像地址为:http s://hub.docker.com/r/joinsunsoft/docker.ui
安装
[root@docker ~]# docker pull joinsunsoft/docker.ui# 启动容器并映射8999端口:
[root@docker ~]# docker run -d --name docker.ui --restart always -v /var/run/docker.sock:/var/run/docker.sock -p 8999:8999 joinsunsoft/docker.ui
14357a64e8df7b96764e6aa23d4fd094056c9421eef8a642d5c322c9411a0177
测试
浏览器访问192.168.108.30:8999
默认用户名密码:ginghan/123456
可以管理镜像容器
# 拉取httpd和busybox
[root@docker ~]# docker pull httpd[root@docker ~]# docker pull busybox# 回到ui界面
[root@docker ~]# docker run -itd busybox
81080c93ff6619e4c1c16d6c66b934b5a1dda2a1ff6ed3a1d85de62650de2e49
Docker 图形化界面管理工具 Portainer
安装
# 创建存储卷
[root@docker ~]# docker volume create portainer_data
portainer_data
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local 12d86d6267f1848241d91473cbace4209d3fb5c7098a183114400b7c9924471f
local 558dac1cf2e863b38f0d6c81f1ef451eef72bfe615d5150b89601ab02f20509e
local portainer_data# 通过docker安装Portainer
[root@docker ~]# docker pull portainer/portainer-ce:latest[root@docker ~]# docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
f11d6bd62d48d632a9596f493911c7297b19663280fe1ac0c01747d326bc7d4c
访问
浏览器 https://192.168.108.30:9443访问 Portainer,首次访问需要创建管理员账号
设置密码
访问
使用
Docker swarm
概念
集群化:从 “单主机” 到 “整体资源池”
Docker Swarm 的核心是管理 Docker Host 集群,先理解 “集群化(Clustering)” 的价值:
- 集群定义:由网络互联的多台服务器组成,协同工作时像 “单个系统”,同时具备高可用、负载均衡、并行处理能力(这是与 “一堆独立服务器” 的核心区别)。
- 为什么需要集群:
- 避免资源浪费:独立服务器无法动态适配应用资源波动(如早高峰内存需求高、下午低),提前分配主机易导致利用率低;
- 减少人工干预:独立服务器宕机时,需手动迁移受影响应用;集群可自动处理故障,保障业务弹性;
- 简化管理思维:无需关注 “应用跑在某台主机”,只需定义 “应用需多少 CPU / 内存”,集群管理工具(如 Swarm)会自动调度资源。
- 集群扩容 / 缩容:通过添加 / 删除主机节点实现,操作后集群仍保持 “整体” 属性,不改变使用逻辑。
Docker Swarm Mode:内置的集群能力
- 版本里程碑:Docker v1.12 后,Swarm 功能完全集成到 Docker Engine 中,无需额外安装软件(如之前依赖的 Consul/etcd/Zookeeper 等外部数据库),启动 “Swarm Mode” 即可使用集群能力。
- 优势:对比 Kubernetes,Swarm 集群创建更简单(无额外配置),适合作为容器编排的入门学习工具。
- 兼容性:同一 Docker 主机可同时运行 “Swarm 服务(service)” 和 “独立容器”,不冲突。
Swarm 核心概念拆解
Swarm(集群实例)
- 定义:由多个运行 Docker Engine 的主机组成的 “集群单元”,当某台主机初始化 Swarm 或加入现有 Swarm 时,即启动 “Swarm Mode”。
- 能力边界:未启动 Swarm Mode 时,Docker 仅能执行单容器命令;启动后,新增 “编排 service” 的能力(如管理多副本容器、故障自愈)。
Node(节点)
-
定义:Swarm 中的每台 Docker Engine 主机都是一个 Node,分两种角色,且一台主机仅占一种角色:
角色 核心职责 关键特性 Manager Node(管理节点) 1. 接收部署命令,拆解任务并分配给 Worker; 2. 维护集群状态(如 service 期望副本数); 3. 多管理节点时自动选举 Leader(执行编排) - 生产环境需 3/5/7 个(奇数,防脑裂); - 默认同时是 Worker,可配置为 “仅管理节点”(专职集群管理) Worker Node(工作节点) 1. 接收并执行 Manager 派发的任务; 2. 定期向 Manager 汇报自身资源(CPU / 内存)和任务状态 仅负责运行容器,不参与集群管理
Service(服务)
- 定义:对 “应用部署需求” 的抽象描述(如 “用 httpd:latest 镜像,启动 3 个副本,提供 HTTP 服务”),是 Swarm 编排的最小单元。
- 核心逻辑:Manager 确保 Service 始终处于 “期望状态”,举例:
- 部署 httpd 服务(3 副本),Manager 分析节点资源后,分配 2 个副本到 Worker1、1 个到 Worker2;
- 若 Worker2 宕机,Manager 监控到故障,立即在 Worker3 上新建 1 个 httpd 副本,维持 “3 副本” 的期望状态(故障自愈)。
部署swarm集群
创建三节点集群
swarm-manager 是 manager node,swarm-worker1 和 swarm-worker2 是 worker node。
# 在 swarm-manager 上执行如下命令创建 swarm
[root@swarm-manager ~]# docker swarm init --advertise-addr 192.168.108.30
Swarm initialized: current node (t2wuubtvlwx0qngw3qi6kp6zc) is now a manager.To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-24dky4f5899mt9hvc4i2h27xqf1ep0sd88b3i1gv7v9izx7xrb-cd03s0sgd0i1l7y3sav2k79da 192.168.108.30:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instruct ions.# 执行 docker node ls 查看当前 swarm 的 node,目前只有一个 manager。
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
t2wuubtvlwx0qngw3qi6kp6zc * swarm-manager Ready Active Leader 26.1.3
防火墙设置,三个节点都要执行
[root@swarm-manager ~]# firewall-cmd --set-default-zone=trusted
success
[root@swarm-worker1 ~]# firewall-cmd --set-default-zone=trusted
success
[root@swarm-worker2 ~]# firewall-cmd --set-default-zone=trusted
success
复制前面的 docker swarm join 命令,在 swarm-worker1 和 swarm-worker2 上执行,将它们添 加到 swarm 中。
[root@swarm-worker1 ~]# docker swarm join --token SWMTKN-1-24dky4f5899mt9hvc4i2h27xqf1ep0sd88b3i1gv7v9izx7xrb-cd03s0sgd0i1l7y3sav2k79da 192.168.108.30:2377
This node joined a swarm as a worker.[root@swarm-worker2 ~]# docker swarm join --token SWMTKN-1-24dky4f5899mt9hvc4i2h27xqf1ep0sd88b3i1gv7v9izx7xrb-cd03s0sgd0i1l7y3sav2k79da 192.168.108.30:2377
This node joined a swarm as a worker.# 两个 worker node 已经添加进来了
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
t2wuubtvlwx0qngw3qi6kp6zc * swarm-manager Ready Active Leader 26.1.3
m8w1ijonr4jrp006rg5o7fgft swarm-worker1 Ready Active 26.1.3
qiw3ydp7o20a65rlfare0g0a8 swarm-worker2 Ready Active 26.1.3
可以通过 docker swarm join-token worker 再次查看docker swarm init 提示的添加 worker 的完整命令。
[root@swarm-manager ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-24dky4f5899mt9hvc4i2h27xqf1ep0sd88b3i1gv7v9izx7xrb-cd03s0sgd0i1l7y3sav2k79da 192.168.108.30:2377
运行第一个 Service
部署一个运行 httpd 镜像的 service
[root@swarm-manager ~]# docker service create --name web_server httpdxzlkc6a9md74ca23xg4khsh85
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service xzlkc6a9md74ca23xg4khsh85 converged# --name : service 命名
# httpd :镜像的名字# 查看当前 swarm 中的 service
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
xzlkc6a9md74 web_server replicated 1/1 httpd:latest# 查看service 每个副本的状态
[root@swarm-manager ~]# docker service ps web_server
# 下图可以看到容器web_server在swarm-worker2上运行# 验证httpd 容器已经运行
# 去swarm-worker2上验证
[root@swarm-worker2 ~]# docker ps
如何实现 Service 伸缩
增加 service 的副本数就可以
[root@swarm-manager ~]# docker service scale web_server=5
web_server scaled to 5
overall progress: 5 out of 5 tasks
1/5: running
2/5: running
3/5: running
4/5: running
5/5: running
verify: Service web_server converged
副本数增加到 5,通过 docker service ls 和 docker service ps 查看副本的详细信息。
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
xzlkc6a9md74 web_server replicated 5/5 httpd:latest
[root@swarm-manager ~]# docker service ps web_server
5 个副本已经分布在 swarm 的所有三个节点上。
数增加到 5,通过 docker service ls 和 docker service ps 查看副本的详细信息。
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
xzlkc6a9md74 web_server replicated 5/5 httpd:latest
[root@swarm-manager ~]# docker service ps web_server
[外链图片转存中…(img-XERJfLCW-1757517387121)]
5 个副本已经分布在 swarm 的所有三个节点上。