Docker从入门到实战(下):一张网讲透网络、存储、监控与Compose编排
⏱ 预计阅读时长 :约 30 分钟 | 📁 实验环境 :CentOS Stream 8 + Docker 26.x | 难度:入门 → 进阶
文章目录
- Docker从入门到实战(下):一张网讲透网络、存储、监控与Compose编排
-
- 摘要
- 前言
- [第5章 Docker网络](#第5章 Docker网络)
-
- [031 none 和 host 网络:什么时候该用它们?](#031 none 和 host 网络:什么时候该用它们?)
-
- [none 网络:完全隔离,只有自己](#none 网络:完全隔离,只有自己)
- [host 网络:直接共享宿主机网络栈](#host 网络:直接共享宿主机网络栈)
- [032 学容器必懂 bridge 网络:veth-pair + docker0 原理讲透](#032 学容器必懂 bridge 网络:veth-pair + docker0 原理讲透)
- [033 自定义容器网络:子网、网关、静态 IP 一次讲清](#033 自定义容器网络:子网、网关、静态 IP 一次讲清)
-
- [1)自动分配网段创建自定义 bridge 网络](#1)自动分配网段创建自定义 bridge 网络)
- 2)手动指定子网与网关创建网络
- [034 容器之间到底通不通?看懂网络隔离与互通](#034 容器之间到底通不通?看懂网络隔离与互通)
- [035 容器通信的三种方式:IP、DNS、joined 该用哪种?](#035 容器通信的三种方式:IP、DNS、joined 该用哪种?)
-
- [方式1:IP 通信](#方式1:IP 通信)
- [方式2:Docker DNS Server(容器名域名解析)](#方式2:Docker DNS Server(容器名域名解析))
- [方式3:joined 容器(共享 network namespace)](#方式3:joined 容器(共享 network namespace))
- [036 容器如何访问外网?iptables NAT 原理与抓包验证](#036 容器如何访问外网?iptables NAT 原理与抓包验证)
- [037 外网如何访问容器?端口映射 + Tomcat 实战](#037 外网如何访问容器?端口映射 + Tomcat 实战)
-
- [实战:安装 Tomcat](#实战:安装 Tomcat)
- 本章小结
- [第6章 Docker存储](#第6章 Docker存储)
-
- [038 Docker 的两类存储资源,别再混为一谈](#038 Docker 的两类存储资源,别再混为一谈)
- [039 bind mount:把宿主机目录直接挂进容器](#039 bind mount:把宿主机目录直接挂进容器)
- [040 docker managed volume:不写路径也能持久化](#040 docker managed volume:不写路径也能持久化)
- [041 容器数据共享的 N 种姿势](#041 容器数据共享的 N 种姿势)
- [042 volume container:用「卷容器」统一管理数据](#042 volume container:用「卷容器」统一管理数据)
- [043 data-packed volume container:把数据打包进镜像](#043 data-packed volume container:把数据打包进镜像)
- [044 数据卷生命周期:备份、恢复、迁移、清理](#044 数据卷生命周期:备份、恢复、迁移、清理)
-
- [实战:安装 MySQL 容器](#实战:安装 MySQL 容器)
- 本章小结
- [第7章 容器监控](#第7章 容器监控)
-
- [Docker 自带监控子命令:ps / top / stats](#Docker 自带监控子命令:ps / top / stats)
-
- [docker ps:查看容器运行状态](#docker ps:查看容器运行状态)
- [docker top:查看容器内部进程](#docker top:查看容器内部进程)
- [docker stats:实时查看资源占用](#docker stats:实时查看资源占用)
- [cAdvisor:Google 开源监控采集组件](#cAdvisor:Google 开源监控采集组件)
- [第8章 容器日志](#第8章 容器日志)
- [第9章 Docker Compose:一条命令编排整套业务](#第9章 Docker Compose:一条命令编排整套业务)
-
- [Compose 模板文件](#Compose 模板文件)
- [实战:WordPress 博客(web + mysql)](#实战:WordPress 博客(web + mysql))
- [第10章 Docker 图形界面管理](#第10章 Docker 图形界面管理)
-
- [DockerUI:国人开发的轻量 Web 管理界面](#DockerUI:国人开发的轻量 Web 管理界面)
- [Portainer CE(社区免费版):最流行的 Docker 图形管理工具](#Portainer CE(社区免费版):最流行的 Docker 图形管理工具)
- 综合实验
-
- [实验1:手动部署 WordPress](#实验1:手动部署 WordPress)
- [实验2:部署 Ghost 博客 CMS](#实验2:部署 Ghost 博客 CMS)
- 全文总结
摘要
本文是 Docker 系列教程的下篇,聚焦生产环境真正会用到的高频能力:
- 网络:讲透 none / host / bridge 三种原生网络模式,自定义网络、容器互通与隔离、内外网通信原理、端口映射,并用 Tomcat 做实战;
- 存储:分清 storage driver 与 Data Volume 两大存储体系,掌握 bind mount、docker managed volume、volume container、data-packed 四种数据卷用法,并用 MySQL 做持久化实战;
- 监控与日志:docker ps / top / stats 自带监控、cAdvisor 采集组件、docker logs 查看日志;
- 编排:Docker Compose 多容器编排,一个 YAML 启动整套业务;
- 图形化管理:DockerUI 与 Portainer 可视化管理;
- 综合实战:WordPress、Ghost 两套博客系统完整部署。
所有命令均可在 CentOS 环境直接复制执行,适合运维工程师、云计算学习者学习与做课程笔记。
前言
前面章节我们已经掌握了 Docker 镜像、容器基础操作、Dockerfile 构建镜像、私有仓库 Harbor 部署。
但到了真实生产环境,光会这些远远不够,还要解决三大核心问题:
📌 核心痛点
- 网络:容器怎么互通?容器怎么访问外网?外网如何访问容器?多种网络模式该如何选型?
- 存储:容器一删数据就没了,怎么实现持久化?数据如何在多容器间共享?
- 编排:一个业务往往要多个容器协同,如何统一启停管理?如何可视化管理整个 Docker 环境?
本篇就围绕网络、存储、监控日志、Compose 编排、图形化管理工具和综合实战完整展开,手把手带你把这些生产级能力一次性补齐。
第5章 Docker网络
⏱ 本章阅读约 10 分钟 | 本章你将掌握:三种网络模式选型、veth-pair 与 docker0 原理、容器互通/隔离、内外网通信、端口映射。
031 none 和 host 网络:什么时候该用它们?
本章重点学习 Docker 原生网络、自定义网络,以及容器之间、容器与外部的通信方式。Docker 网络分为单机 host 内网络、跨多 host 网络,本章聚焦单机容器网络,跨主机网络留待进阶章节讲解。
执行 docker network ls 可以看到 Docker 安装后自动创建的 3 个网络:
bash
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a1b809382f0d bridge bridge local
6ad21ed9ea1f host host local
4e31521b27c6 none null local
none 网络:完全隔离,只有自己
none 网络 driver 为 null,IPAM 配置为空。使用 none 网络的容器只有 lo 回环网卡,没有其他网卡,无法访问外部网络。

使用 --network=none 指定容器使用 none 网络:
bash
[root@docker ~]# docker run -it --network=none busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # hostname
4027da12afaf
✅ 适用场景:高安全隔离、完全不需要联网的业务。例如容器只用来生成随机密码,避免网络泄露。
host 网络:直接共享宿主机网络栈
host 网络模式下,容器共享宿主机的 network namespace,容器网络配置与宿主机完全一致。

--network=host 启用 host 网络:
bash
[root@docker ~]# docker run -it --network=host busybox
/ # ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
link/ether 00:0c:29:33:15:f6 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether 02:42:02:fd:82:b3 brd ff:ff:ff:ff:ff:ff
/ # hostname
docker
host 网络优缺点
- ✅ 优点:性能最好,没有网桥转发损耗;
- ❌ 缺点:端口直接占用宿主机端口,容易端口冲突,灵活性降低。
✅ 适用场景:对网络性能要求极高的业务;需要直接操作宿主机网络栈的容器化网络组件。
032 学容器必懂 bridge 网络:veth-pair + docker0 原理讲透

bridge 是 Docker 的默认网络模式 。Docker 安装后自动创建 docker0 网桥,可以把它理解成一台软件交换机 。不指定 --network 时,容器默认挂载到 docker0。
容器启动时会生成一对 veth-pair 虚拟网卡:
- 一端在容器内部:eth0;
- 另一端在宿主机上,挂载到 docker0 网桥,命名以 veth 开头。
正是这对虚拟网卡,实现了宿主机与容器互通、容器之间互相通信。
安装网桥管理工具 bridge-utils:
bash
[root@docker ~]# cd /etc/yum.repos.d/
[root@docker yum.repos.d]# vim cloud.repo
[centos-openstack-victoria]
name=CentOS 8 - OpenStack victoria
baseurl=https://mirrors.aliyun.com/centos-vault/8-stream/cloud/x86_64/openstack-victoria/
enabled=1
gpgcheck=0
[root@docker yum.repos.d]# yum install -y bridge-utils
查看网桥:
bash
[root@docker ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02420be905a5 no
创建容器,观察网桥变化:
bash
[root@docker ~]# docker run -itd --name busybox1 busybox
[root@docker ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02420be905a5 no vethddb2744
进入容器查看网卡:
bash
[root@docker ~]# docker exec -it busybox1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

容器内的 eth0@if25 和宿主机的 vethddb2744 就是一对 veth-pair。
查看 bridge 网络配置信息:
bash
[root@docker ~]# docker network inspect bridge

bridge 默认网段 172.17.0.0/16,网关就是 docker0 网桥 172.17.0.1:
bash
[root@docker ~]# ip a | grep docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
💡 一句话记忆 :bridge 网络 = veth-pair 成对虚拟网卡 + docker0 网桥,实现单机容器互通。
033 自定义容器网络:子网、网关、静态 IP 一次讲清
Docker 支持三种自定义网络驱动:bridge、overlay、macvlan。其中 overlay / macvlan 用于跨主机网络。
1)自动分配网段创建自定义 bridge 网络
bash
[root@docker ~]# docker network create --driver bridge my_net
[root@docker ~]# brctl show
[root@docker ~]# docker network inspect my_net
2)手动指定子网与网关创建网络
bash
[root@docker ~]# docker network create --driver bridge \
--subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
查看网桥,会生成 br- 开头的网桥 id:
bash
[root@docker ~]# brctl show
[root@docker ~]# docker network inspect my_net2
启动容器,指定使用自定义网络:
bash
[root@docker ~]# docker run -it --network=my_net2 --name busybox2 busybox
给容器指定静态 IP:
⚠️ 注意 :只有创建网络时手动指定了
--subnet,容器启动才能用--ip设置静态 IP。
bash
[root@docker ~]# docker run -it --network=my_net2 --ip 172.22.16.8 --name busybox3 busybox
如果网络没有手动指定 subnet,直接使用 --ip 会报错。

034 容器之间到底通不通?看懂网络隔离与互通

✅ 同一自定义网络内的容器默认互通
busybox2、busybox3 都挂载 my_net2 网络,可以直接 ping 通。
❌ 不同网桥网络默认隔离,互相 ping 不通
my_net2 和默认 bridge(docker0)属于不同网桥,即便宿主机开启 ip_forward、存在路由,Docker 的 iptables 规则 DOCKER-ISOLATION 也会丢弃跨网桥流量,实现网络隔离。
解决方案:给容器多网卡,加入多个网络
使用 docker network connect,给已运行容器追加一块网卡接入其他网络:
bash
[root@docker ~]# docker network connect my_net2 busybox1

📌 核心要点
- 同一网络内容器互通;
- 不同网桥默认隔离,由 docker iptables 实现;
- 一个容器可以有多块网卡,接入多个网络。
035 容器通信的三种方式:IP、DNS、joined 该用哪种?
方式1:IP 通信
容器要互通,必须至少有一块网卡属于同一个网络。
创建容器时用 --network 指定网络,或者运行中用 docker network connect 接入网络,就可以直接通过 IP 访问。
方式2:Docker DNS Server(容器名域名解析)
⚠️ 注意 :只支持 user-defined 自定义网络,默认 bridge 网络不支持 DNS 解析容器名。
自定义网络中,容器使用 --name 命名后,可以直接 ping 容器名字通信:
bash
# 自定义网络 bbox1、bbox2
[root@docker ~]# docker run -it --network my_net2 --name bbox1 busybox
# ctrl+p ctrl+q 后台退出
[root@docker ~]# docker run -it --network my_net2 --name bbox2 busybox
[root@docker ~]# docker exec -it bbox2 sh
/ # ping -c 3 bbox1
方式3:joined 容器(共享 network namespace)
--network=container:容器名,新容器完全复用已有容器的网络栈,网卡、IP 完全一样,可以用 127.0.0.1 互相访问服务。
bash
# 启动 web1 httpd
[root@docker ~]# docker run -d -it --name web1 httpd
# busybox 复用 web1 网络栈
[root@docker ~]# docker run -it --network container:web1 busybox
/ # wget 127.0.0.1
✅ joined 容器适用场景
- 同一个业务的多个程序,希望用 loopback 高效通信;
- 独立容器做网络抓包,监控其他容器的流量。
036 容器如何访问外网?iptables NAT 原理与抓包验证
容器访问外网的本质是 iptables MASQUERADE 源地址 NAT。
容器内部数据包的源 IP 是容器私有网段,经过宿主机 NAT 转换后,源 IP 被替换成宿主机的网卡 IP 访问互联网。
bash
# 查看 nat 表规则
[root@docker ~]# iptables -t nat -S
抓包验证 NAT 过程:
bash
[root@docker ~]# yum install -y tcpdump
# 监听 docker0
tcpdump -i docker0 -n icmp
# 监听物理网卡 ens160
tcpdump -i ens160 -n icmp
# 新开窗口,容器 ping 外网
[root@docker ~]# docker run -it busybox ping -c3 www.baidu.com

037 外网如何访问容器?端口映射 + Tomcat 实战
外部访问容器使用端口映射 ,格式:-p 宿主机端口:容器端口。

bash
# 指定端口映射
[root@docker ~]# docker run -d -p 8080:80 httpd
[root@docker ~]# curl 192.168.108.30:8080

docker-proxy 进程监听宿主机端口,把流量转发到容器内部。


实战:安装 Tomcat
bash
# 搜索镜像
[root@docker ~]# docker search tomcat
# 拉取镜像
[root@docker ~]# docker pull tomcat
# 运行容器并端口映射
[root@docker ~]# docker run -itd -p 8080:8080 tomcat

⚠️ 易踩坑:新版 tomcat 容器 webapps 为空,需要复制 webapps.dist 内容:
bash
[root@docker ~]# docker exec -it 92d bash
root@92d78922526b:/usr/local/tomcat# mv webapps.dist/* webapps

💡 思考题:如何基于 tomcat 构建镜像,让容器启动后直接就能访问页面?
本章小结
- none:无网卡,完全隔离;host:复用宿主机网络;bridge:默认网桥网络;
- veth-pair + docker0 网桥实现 bridge 网络;
- 自定义 bridge 网络,可以指定子网、静态 IP;不同网桥默认隔离;
- 容器通信三种方式:IP、Docker DNS(自定义网络)、joined 共享网络 namespace;
- 容器访问外网靠 iptables NAT;外部访问容器依靠
-p端口映射。
第6章 Docker存储
⏱ 本章阅读约 8 分钟 | 本章你将掌握:两类存储体系、四种数据卷用法、MySQL 持久化实战。
038 Docker 的两类存储资源,别再混为一谈
Docker 提供两种数据存储:
- storage driver 管理:镜像层 + 可写容器层;
- Data Volume 数据卷:做持久化存储。

storage driver:写时复制 Copy-on-Write
- 新增数据直接写入顶层可写容器层;
- 修改旧文件,先从只读镜像层复制文件到容器层再修改,镜像层保持不变;
- 多层同名文件,上层覆盖下层。
查看 storage driver:
bash
[root@docker ~]# docker info
CentOS Stream 8 默认使用 overlay2 驱动。
⚠️ 关键区别 :容器删除,storage driver 管理的容器层数据会全部丢失 ,适合无状态应用;有状态业务必须使用 Data Volume。
039 bind mount:把宿主机目录直接挂进容器
bind mount:直接挂载宿主机已经存在的目录/文件到容器。

格式:-v 宿主机路径:容器内路径[:ro]
bash
# 准备宿主机目录
[root@docker ~]# mkdir htdocs
[root@docker ~]# echo "<h1>host file</h1>" > htdocs/index.html
# bind mount 挂载
[root@docker ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
[root@docker ~]# curl 127.0.0.1
- 容器销毁,宿主机文件不会删除;
- 增加
:ro设置只读权限,容器内不能修改挂载内容; - 支持挂载单个文件;
- ❌ 缺点:强绑定宿主机路径,可移植性差。
040 docker managed volume:不写路径也能持久化
docker managed volume:只写容器内挂载点,不需要指定宿主机路径,Docker 自动在 /var/lib/docker/volumes/ 生成目录。
bash
# 只写容器挂载点,docker 自动创建宿主机卷目录
[root@docker ~]# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
使用 docker inspect 找到宿主机真实挂载目录。
💡 注意 :如果容器内挂载目录原本就有文件,Docker 会把原有内容复制到 volume 里面。
相关 volume 命令:
bash
docker volume ls
docker volume inspect 卷名
bind mount 与 docker managed volume 对比
| 对比项 | bind mount | docker managed volume |
|---|---|---|
| 宿主机位置 | 任意自定义路径 | /var/lib/docker/volumes/xxx/_data |
| 挂载目录原有内容 | 直接覆盖隐藏 | 复制原有数据到卷内 |
| 支持单个文件 | ✅ 支持 | ❌ 仅目录 |
| 读写权限 | 可加 ro 只读 | 全部读写 |
| 可移植性 | 差,绑定宿主机路径 | 好,无需写宿主机路径 |
041 容器数据共享的 N 种姿势
1. 容器与宿主机共享
- bind mount 直接挂载目录;
- docker managed volume,可以用
docker cp在宿主机与容器间拷贝文件:
bash
docker cp 宿主机文件 容器id:容器路径
docker cp 容器id:容器路径 宿主机路径
2. 多个容器之间共享数据
把同一个 bind mount 目录挂载到多个容器,实现多容器读写同一份数据。
042 volume container:用「卷容器」统一管理数据
volume container:专门用来提供数据卷的容器,容器不需要运行,只需 docker create 创建。
其他容器通过 --volumes-from 卷容器名 继承它所有 volume 配置。
bash
# 创建 volume container,不用 run,用 create
[root@docker ~]# docker create --name vc_data \
-v ~/htdocs/:/usr/local/apache2/htdocs \
-v /other/userful/tools \
busybox
# 其他容器继承卷配置
[root@docker ~]# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
[root@docker ~]# docker run --name web2 -d -p 80 --volumes-from vc_data httpd
✅ 优点:容器与宿主机路径解耦,统一管理卷配置。
043 data-packed volume container:把数据打包进镜像
把静态数据打包进镜像,容器启动自动复制到 volume,完全不依赖宿主机预先准备文件,移植性极强,适合静态资源(html、配置文件)。
Dockerfile 示例:
dockerfile
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs
bash
# 构建镜像
docker build -t datapacked .
# 创建卷容器
docker create --name vc_data datapacked
# 业务容器继承 volume
docker run -d -p 80:80 --volumes-from vc_data httpd
044 数据卷生命周期:备份、恢复、迁移、清理
- 备份:volume 本质是宿主机目录,直接备份对应目录文件;
- 恢复:备份文件覆盖 volume 对应目录;
- 迁移:新版本容器直接挂载旧 volume 目录;
- 删除 :
- bind mount:docker 不会删宿主机文件,需要手动 rm;
- docker managed volume:
docker rm -v 容器id,容器删除同时清理 volume;不加-v会遗留孤儿卷。
清理孤儿 volume:
bash
# 清理所有未被容器使用的 volume
docker volume prune
# 查看所有卷
docker volume ls
# 手动删除指定卷
docker volume rm 卷名
实战:安装 MySQL 容器
简单版(无持久化,删容器数据丢失)
bash
docker pull mysql:5.7
# -e 设置环境变量,初始化 root 密码
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

⚠️ 两个坑:容器删除数据库全部丢失;默认字符集 latin1,中文插入会报错。
实战版(数据卷持久化 + 修改字符集 utf8)
bash
docker run -d -p 3306:3306 --privileged=true \
-v /gqd/mysql/log:/var/log/mysql \
-v /gqd/mysql/data:/var/lib/mysql \
-v /gqd/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
宿主机 /gqd/mysql/conf/my.cnf:
ini
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
重启容器后字符集生效。

💡 动手实验:删除 mysql 容器,再重新启动挂载同样 volume 目录,数据依然存在。
本章小结
- storage driver:镜像层 + 容器可写层,容器销毁数据丢失,适合无状态;
- Data Volume 分为 bind mount、docker managed volume;
- volume container、data-packed 容器实现多容器数据共享;
- volume 备份恢复本质是操作宿主机目录;prune 清理孤儿数据卷;
- MySQL 实战:通过
-v挂载日志、数据、配置目录,实现持久化和字符集修改。
第7章 容器监控
⏱ 本章阅读约 3 分钟 | 本章你将掌握:docker 自带三件套监控 + cAdvisor 采集组件。
Docker 自带监控子命令:ps / top / stats
docker ps:查看容器运行状态
bash
docker ps
docker ps -a
docker top:查看容器内部进程
bash
docker top 容器名/ID
docker top sshtest -au
docker stats:实时查看资源占用
实时查看容器的 CPU、内存、网络 IO、块 IO 资源占用:
bash
docker stats
# 只输出一次,不持续刷新
docker stats --no-stream
cAdvisor:Google 开源监控采集组件
cAdvisor 是 Google 开源的容器监控采集工具,收集容器的各项指标,可输出给 Prometheus 等监控系统。

bash
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
浏览器访问 http://宿主机IP:8080。
⚠️ 注意:cAdvisor 只支持单机;UI 简陋;定位是数据采集器,一般配合 Prometheus + Grafana 做可视化大盘。
第8章 容器日志
⏱ 本章阅读约 2 分钟
容器应用日志输出到 stdout 标准输出、stderr 标准错误。
bash
# 后台运行 httpd
docker run -d -p 80:80 httpd
# 查看容器全部日志
docker logs 容器ID
# 持续跟踪日志,类似 tail -f
docker logs -f 容器ID
💡 建议 :
docker attach可以附着到容器终端,但退出操作容易误杀容器;生产环境优先用docker logs。
第9章 Docker Compose:一条命令编排整套业务
⏱ 本章阅读约 5 分钟 | 本章你将掌握:Compose 核心概念、YAML 编写、WordPress 多容器实战。
当业务由多个容器协同(web + mysql + redis)时,一条条 docker run 命令维护起来非常繁琐。
Docker Compose 是多容器编排工具,使用 docker-compose.yml YAML 文件定义一组服务,一条命令即可完成整套业务的批量创建、启动、停止、删除。
📌 两个核心概念
- service(服务):一个应用服务,可以有多个容器实例;
- project(项目):完整的业务项目,是一组关联服务的集合。

查看帮助:
bash
docker compose -h
docker compose version
Compose 模板文件
默认文件名 docker-compose.yml,关键字大部分等价于 docker run 参数。
简单示例:
yaml
services:
webapp:
image: httpd
实战:WordPress 博客(web + mysql)
传统方式要用多条 docker run 分别启动两套容器,还要手动处理网络、环境变量;Compose 一行搞定。
docker-compose.yml:
yaml
services:
blog:
image: wordpress:latest
restart: always
links:
- db
ports:
- "80:80"
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=huawei
- WORDPRESS_DB_NAME=wordpress
db:
image: mysql:latest
restart: always
environment:
- MYSQL_ROOT_PASSWORD=huawei
- MYSQL_DATABASE=wordpress
bash
# 校验 yml 语法
docker compose config -q
# 后台启动整套项目
docker compose up -d
# 查看容器
docker compose ps
# 停止并删除整套服务(网络、容器),卷默认保留
docker compose down

浏览器访问宿主机 80 端口,完成 wordpress 初始化。
第10章 Docker 图形界面管理
⏱ 本章阅读约 3 分钟 | 本章你将掌握:DockerUI 与 Portainer 部署与访问。
DockerUI:国人开发的轻量 Web 管理界面
bash
docker run -d --name docker.ui --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8999:8999 joinsunsoft/docker.ui
访问:http://ip:8999,默认账号 ginghan / 123456。
Portainer CE(社区免费版):最流行的 Docker 图形管理工具
功能强大,是目前最主流的 Docker 可视化管理工具:
bash
docker volume create portainer_data
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
访问 https://ip:9443,首次登录创建管理员账号。
综合实验
⏱ 本章阅读约 6 分钟 | 动手时间:把前面所有知识点串起来。
实验1:手动部署 WordPress
bash
docker pull mysql
docker pull wordpress
# 启动 mysql
docker run -d -p 3306:3306 \
-v /mysql:/var/lib/mysql:z \
--name mysql \
-e MYSQL_ROOT_PASSWORD=huawei \
-e MYSQL_DATABASE=wordpress mysql
# 获取 mysql 容器 IP
docker inspect mysql | grep IPAddress
# 启动 wordpress,指定数据库 IP 地址
docker run -d -p 80:80 -v /www:/var/www/html:z \
--name wordpress \
-e WORDPRESS_DB_HOST=172.17.0.2 \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=huawei \
-e WORDPRESS_DB_NAME=wordpress wordpress
浏览器访问宿主机 IP,完成博客初始化。
实验2:部署 Ghost 博客 CMS
Ghost 是基于 Node.js 的开源博客系统。
bash
docker pull ghost
mkdir -p /data/ghost
docker run -d \
--restart always \
--name ghost \
-p 2368:2368 \
-v /data/ghost:/var/lib/ghost/content \
-e NODE_ENV=development \
-e url=http://localhost:2368 ghost
chmod -R 777 /data/ghost/
docker restart ghost
# 查看运行日志
docker logs ghost
- 前台访问:
http://ip:2368 - 后台管理:
http://ip:2368/ghost
⚠️ 注意:云服务器记得在安全组放行 2368 端口,并开放防火墙端口。
全文总结
本篇是 Docker 教程的下半部分,覆盖了生产环境的高频核心知识点:
- 网络模块:none、host、bridge 三种原生网络模式;自定义网络;veth-pair 原理;容器之间、内外网通信;端口映射;Tomcat 实战。
- 存储模块:storage driver 写时复制;bind mount、docker managed volume 两种数据卷;volume container 共享数据;mysql 持久化实战。
- 监控日志:docker ps / top / stats;cAdvisor 监控采集;docker logs 查看容器标准输出日志。
- 编排:Docker Compose,用 YAML 定义多容器业务,WordPress 完整示例。
- 图形化管理:DockerUI、Portainer 可视化管理 Docker。
- 综合实战:WordPress、Ghost 两套博客系统完整部署案例。
📌 进阶方向:到此 Docker 整套学习闭环已完成。后续可以继续学习:Docker 安全、Swarm / K8s 容器编排等。