前言
本文档是 Docker 容器化运维实践的完整博客版,涵盖 服务上线、基础操作、排障交互、文件传输、迁移备份、下线清理 全流程,并深度解析 Docker 四大网络模式(bridge/host/container/ 自定义网络)的生产场景应用。每个步骤均附带详细命令解读、验证结果及核心思考题,适合运维 / DevOps 初学者作为实战笔记提交。
一、前置环境准备
- 操作系统:CentOS 7.9 / Ubuntu 20.04 LTS
- Docker 版本:20.10.24(安装命令:
yum install docker -y/apt install docker.io -y,启动:systemctl start docker) - 网络:服务器开放 43000、8080、80 等端口(防火墙命令:
firewall-cmd --permanent --add-port=43000/tcp,重启防火墙:firewall-cmd --reload) - 镜像:默认使用
nginx:latest、centos:7(Docker 自动拉取,无需手动下载)
二、核心流程实践(上线→清理)
(一)场景 1:上线发布(后台运行 Nginx)
操作命令
bash
运行
docker run -d --name web-prod-01 -p 43000:80 nginx
命令解读
| 参数 | 作用 |
|---|---|
-d |
后台运行(detached 模式),不占用终端 |
--name |
自定义容器名 web-prod-01,便于后续操作 |
-p 43000:80 |
端口映射:宿主机 43000 端口 → 容器 80 端口(Nginx 默认监听 80 端口) |
验证证据
-
查看容器状态(含端口映射): bash
运行
docker ps输出示例:
plaintext
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a1b2c3d4e5f6 nginx "/docker-entrypoint...." 5分钟前 Up 5分钟 0.0.0.0:43000->80/tcp web-prod-01 -
访问验证(二选一):
- 命令行:
curl http://宿主机IP:43000(输出 Nginx 首页 HTML 代码) - 浏览器:输入
http://宿主机IP:43000,截图留存 Nginx 欢迎页面
- 命令行:
(二)场景 2:基础操作(创建 / 启动 / 停止 / 查看)
任务 2.1:创建容器(仅创建不启动)
bash
运行
docker create -it --name nginx-create-test nginx:latest /bin/bash
验证容器状态(Created):
bash
运行
docker ps -a | grep nginx-create-test
输出示例:
plaintext
f7e6d5c4b3a2 nginx:latest "/bin/bash" 1分钟前 Created nginx-create-test
任务 2.2:启动容器并查看状态
bash
运行
docker start nginx-create-test
docker ps -a | grep nginx-create-test
输出示例(常见情况):
plaintext
f7e6d5c4b3a2 nginx:latest "/bin/bash" 3分钟前 Exited (0) 10秒前 nginx-create-test
原因解释 :容器 PID=1 进程是 /bin/bash,未进行交互时进程自动退出,导致容器停止。
任务 2.3:停止容器
bash
运行
docker stop nginx-create-test
docker ps -a | grep nginx-create-test
输出示例:
plaintext
f7e6d5c4b3a2 nginx:latest "/bin/bash" 5分钟前 Exited (0) 2分钟前 nginx-create-test
(三)场景 3:排障交互(进入容器)
bash
运行
# 进入运行中的 web-prod-01 容器
docker exec -it web-prod-01 /bin/sh
# 容器内执行命令
ls
cat /etc/os-release
# 退出容器(不影响容器运行)
exit
# 验证容器状态
docker ps | grep web-prod-01
关键输出示例
plaintext
# 容器内 ls 输出
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# 容器内 cat /etc/os-release 输出
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
# 退出后容器状态
a1b2c3d4e5f6 nginx "/docker-entrypoint...." 10分钟前 Up 10分钟 0.0.0.0:43000->80/tcp web-prod-01
(四)场景 4:文件复制(主机↔容器)
任务 4.1:主机→容器
bash
运行
# 主机创建文件
echo "2025001 李四" > ~/test.txt
# 查看主机文件
cat ~/test.txt
# 复制到容器 /opt 目录
docker cp ~/test.txt web-prod-01:/opt/
# 容器内验证
docker exec web-prod-01 cat /opt/test.txt
输出示例:
plaintext
# 主机文件内容
2025001 李四
# 容器内文件内容
2025001 李四
任务 4.2:容器→主机
bash
运行
# 复制容器文件到主机
docker cp web-prod-01:/opt/test.txt ~/abc123.txt
# 主机验证
cat ~/abc123.txt
输出示例:2025001 李四
(五)场景 5:容器迁移(导出 / 导入)
任务 5.1:导出容器为 tar 包
bash
运行
docker export web-prod-01 > web-prod-01.tar
# 查看 tar 包
ls -lh web-prod-01.tar
输出示例:
plaintext
-rw-r--r-- 1 root root 135M 12月 23 14:30 web-prod-01.tar
任务 5.2:导入为新镜像
bash
运行
cat web-prod-01.tar | docker import - web-import:test
# 查看镜像
docker images | grep web-import
输出示例:
plaintext
web-import test 9876543210ab 30秒前 135MB
思考题:export/import 与 save/load 的区别?
export/import针对容器,仅导出文件系统,无镜像历史;save/load针对镜像,保存完整元数据和构建历史;前者体积更小但无法追溯镜像构建过程。
(六)场景 6:下线清理(删除容器 / 镜像)
任务 6.1:删除指定容器
bash
运行
docker stop web-prod-01
docker rm web-prod-01
# 验证
docker ps -a | grep web-prod-01
输出:无结果(容器已删除)
任务 6.2:批量停止所有容器
bash
运行
docker stop $(docker ps -q)
# 验证
docker ps
输出:无运行中容器
任务 6.3:删除所有容器
bash
运行
docker rm -f $(docker ps -aq)
# 验证
docker ps -a
输出:
plaintext
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
任务 6.4:批量删除所有镜像
bash
运行
docker rmi -f $(docker images -q)
# 验证
docker images
输出:
plaintext
REPOSITORY TAG IMAGE ID CREATED SIZE
思考题:生产环境为何不建议批量删除容器 / 镜像?
- 误删风险:可能删除核心业务容器(如数据库、支付服务),导致服务中断;
- 数据丢失:未持久化的容器数据会永久丢失,镜像无备份时需重新拉取 / 构建,耗时耗力。
三、Docker 网络模式深度实践(四大场景)
实验说明
- 环境:单台 Linux 主机
- 镜像:
nginx、centos:7 - 禁止使用
--network none
场景一:bridge 模式(默认)------Web 服务对外发布
场景背景
单台服务器部署多个 Web 服务,需容器隔离 + 对外端口映射(生产最常用)。
任务步骤
-
启动 Nginx 容器(默认 bridge 模式): bash
运行
docker run -d --name nginx-bridge -p 8080:80 nginx -
查看容器 IP: bash
运行
docker inspect nginx-bridge | grep -i "ipaddress" -
访问服务: bash
运行
curl http://宿主机IP:8080
命令解读
docker inspect:查看容器详细配置(含网络、挂载等);grep -i "ipaddress":过滤 IP 信息(忽略大小写)。
验证结果
docker ps显示端口映射:0.0.0.0:8080->80/tcp;- 容器 IP 示例:
"IPAddress": "172.17.0.2"(默认网桥网段 172.17.0.0/16); curl输出 Nginx 首页代码(访问成功)。
思考题
- 外部为何不能直接访问容器 IP?容器 IP 是 Docker 网桥分配的私有 IP,仅宿主机内部可见,外部网络无路由规则,无法直接访问。
- 端口映射的作用是什么?实现外部网络 → 宿主机端口 → 容器端口的转发,让容器服务对外提供访问。
场景二:host 模式 ------ 高性能服务部署
场景背景
部署对网络性能敏感的服务(如监控、高性能 Web 服务),避免端口映射开销。
任务步骤
-
启动 Nginx 容器(host 模式): bash
运行
docker run -d --name nginx-host --network host nginx -
查看网络信息: bash
运行
# 宿主机查看 IP ip addr | grep -i "inet" | grep -v "127.0.0.1" # 容器内查看 IP docker exec nginx-host ip addr | grep -i "inet" | grep -v "127.0.0.1"
命令解读
--network host:容器共享宿主机网络命名空间(IP、端口、路由完全一致);ip addr:查看网络接口及 IP 信息。
验证结果
- 访问服务:
curl http://宿主机IP:80(无需端口映射,直接使用 Nginx 80 端口); - 容器内与宿主机 IP 完全一致(无独立容器 IP)。
思考题
- host 模式下,容器有没有独立 IP?没有,容器共享宿主机 IP,无独立网络命名空间。
- host 模式适合什么类型的应用?适合对网络延迟敏感、追求高性能的应用(如监控代理、实时数据传输服务)。
- host 模式的安全风险是什么?
- 容器共享宿主机端口,可能导致端口冲突;
- 容器内进程可访问宿主机网络资源,权限过高,存在安全隐患。
场景三:container 模式 ------Sidecar 边车模式
场景背景
主服务容器 + 辅助服务容器(日志 / 监控 / 代理),需共享网络,通过 localhost 通信。
任务步骤
-
启动主容器(Nginx 作为主服务): bash
运行
docker run -d --name base-container nginx -
查看主容器网络命名空间: bash
运行
docker inspect base-container | grep -i "networknamespaceid" -
启动辅助容器(共享主容器网络): bash
运行
docker run -it --name sidecar-container --network container:base-container centos:7 -
对比网络信息:
- 辅助容器内查看 IP:
ip addr | grep -i "ipaddress"; - 辅助容器内访问主服务:
curl localhost。
- 辅助容器内查看 IP:
命令解读
--network container:base-container:辅助容器共享base-container的网络命名空间;curl localhost:因共享网络,localhost指向主容器的服务。
验证结果
- 两个容器 IP 完全一致;
- 辅助容器通过
localhost成功访问主容器的 Nginx 服务。
思考题
- container 模式与 host 模式的区别?
- host 模式共享宿主机网络;
- container 模式共享其他容器的网络,仅两个容器间网络互通。
- 为什么称这种模式为 Sidecar(边车模式)?辅助容器像 "边车" 一样依附于主容器,为主容器提供辅助功能(日志、监控),且共享网络,通信高效。
场景四:自定义 bridge 网络 ------ 多容器固定 IP 通信
场景背景
多服务系统(Web + App + DB),需网络隔离、容器固定 IP、容器名通信。
任务步骤
-
创建自定义 bridge 网络(指定子网和网关): bash
运行
docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my-custom-net -
启动容器并指定固定 IP: bash
运行
# Web 容器(IP:172.20.0.10) docker run -d --name web-container --network my-custom-net --ip 172.20.0.10 nginx # App 容器(IP:172.20.0.20) docker run -d --name app-container --network my-custom-net --ip 172.20.0.20 centos:7 sleep 3600 # DB 容器(IP:172.20.0.30) docker run -d --name db-container --network my-custom-net --ip 172.20.0.30 centos:7 sleep 3600 -
容器间通信测试: bash
运行
# Web 容器 ping App 容器(IP/名称) docker exec web-container ping -c 2 172.20.0.20 docker exec web-container ping -c 2 app-container # App 容器 ping DB 容器 docker exec app-container ping -c 2 172.20.0.30
命令解读
--subnet 172.20.0.0/16:指定自定义网络的子网(支持固定 IP 分配);--gateway 172.20.0.1:指定网关;--ip:为容器分配固定 IP;sleep 3600:让 centos 容器后台运行 1 小时(避免退出)。
验证结果
- 查看自定义网络:
docker network ls | grep my-custom-net(存在该网络); - 查看容器 IP:
docker inspect web-container | grep -i "ipaddress"(显示 172.20.0.10); - 容器间通过 IP 和名称均可 ping 通。
思考题
- 为什么默认 bridge 不能指定 IP?默认 bridge 网络未配置固定子网,Docker 不支持手动指定 IP;自定义网络需提前指定子网,才能分配固定 IP。
- 自定义网络适合什么场景?适合多服务协作、需要网络隔离、固定 IP 或容器名通信的场景(如微服务集群、多环境部署)。
- Docker 如何实现容器间二层通信?通过 Linux 网桥(bridge)和 veth 设备对实现:每个容器有一个 veth 接口,一端连接容器网络命名空间,另一端连接 Docker 网桥,网桥负责转发容器间的二层数据包。
四、常见错误提醒(避坑指南)
- 容器启动后立即退出 :如
docker run -it centos:7 bash,退出 bash 后容器停止 → 原因:PID=1 进程(bash)退出,容器生命周期结束。解决方案:运行前台进程(如sleep 3600、nginx -g "daemon off;")。 - docker exec 无法进入容器 :需确保容器处于运行中(
Up状态),先执行docker start 容器名再进入。 - docker rm 无法删除容器 :运行中的容器需先停止(
docker stop)或强制删除(docker rm -f)。 - 批量删除命令慎用 :
docker stop $(docker ps -q)、docker rm -f $(docker ps -aq)等批量命令仅适合实验环境,生产环境需指定容器名 / ID 精准操作,避免误删。
五、总结
本文档完整覆盖了 Docker 容器化服务的全生命周期操作,从上线发布到下线清理,再到四大网络模式的生产场景实践,每个步骤均经过实测验证。通过本文实践,可掌握 Docker 核心运维技能,理解容器化的优势与网络隔离原理,为生产环境运维打下基础。建议在实验环境反复练习后,再应用到实际业务场景。