Docker 容器化 Web 服务全流程实践(含网络深度场景)

前言

本文档是 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:latestcentos: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 端口)
验证证据
  1. 查看容器状态(含端口映射): 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
  2. 访问验证(二选一):

    • 命令行: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
思考题:生产环境为何不建议批量删除容器 / 镜像?
  1. 误删风险:可能删除核心业务容器(如数据库、支付服务),导致服务中断;
  2. 数据丢失:未持久化的容器数据会永久丢失,镜像无备份时需重新拉取 / 构建,耗时耗力。

三、Docker 网络模式深度实践(四大场景)

实验说明

  • 环境:单台 Linux 主机
  • 镜像:nginxcentos:7
  • 禁止使用 --network none

场景一:bridge 模式(默认)------Web 服务对外发布

场景背景

单台服务器部署多个 Web 服务,需容器隔离 + 对外端口映射(生产最常用)。

任务步骤
  1. 启动 Nginx 容器(默认 bridge 模式): bash

    运行

    复制代码
    docker run -d --name nginx-bridge -p 8080:80 nginx
  2. 查看容器 IP: bash

    运行

    复制代码
    docker inspect nginx-bridge | grep -i "ipaddress"
  3. 访问服务: 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 首页代码(访问成功)。
思考题
  1. 外部为何不能直接访问容器 IP?容器 IP 是 Docker 网桥分配的私有 IP,仅宿主机内部可见,外部网络无路由规则,无法直接访问。
  2. 端口映射的作用是什么?实现外部网络 → 宿主机端口 → 容器端口的转发,让容器服务对外提供访问。

场景二:host 模式 ------ 高性能服务部署

场景背景

部署对网络性能敏感的服务(如监控、高性能 Web 服务),避免端口映射开销。

任务步骤
  1. 启动 Nginx 容器(host 模式): bash

    运行

    复制代码
    docker run -d --name nginx-host --network host nginx
  2. 查看网络信息: 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)。
思考题
  1. host 模式下,容器有没有独立 IP?没有,容器共享宿主机 IP,无独立网络命名空间。
  2. host 模式适合什么类型的应用?适合对网络延迟敏感、追求高性能的应用(如监控代理、实时数据传输服务)。
  3. host 模式的安全风险是什么?
    • 容器共享宿主机端口,可能导致端口冲突;
    • 容器内进程可访问宿主机网络资源,权限过高,存在安全隐患。

场景三:container 模式 ------Sidecar 边车模式

场景背景

主服务容器 + 辅助服务容器(日志 / 监控 / 代理),需共享网络,通过 localhost 通信。

任务步骤
  1. 启动主容器(Nginx 作为主服务): bash

    运行

    复制代码
    docker run -d --name base-container nginx
  2. 查看主容器网络命名空间: bash

    运行

    复制代码
    docker inspect base-container | grep -i "networknamespaceid"
  3. 启动辅助容器(共享主容器网络): bash

    运行

    复制代码
    docker run -it --name sidecar-container --network container:base-container centos:7
  4. 对比网络信息:

    • 辅助容器内查看 IP:ip addr | grep -i "ipaddress"
    • 辅助容器内访问主服务:curl localhost
命令解读
  • --network container:base-container:辅助容器共享 base-container 的网络命名空间;
  • curl localhost:因共享网络,localhost 指向主容器的服务。
验证结果
  • 两个容器 IP 完全一致;
  • 辅助容器通过 localhost 成功访问主容器的 Nginx 服务。
思考题
  1. container 模式与 host 模式的区别?
    • host 模式共享宿主机网络;
    • container 模式共享其他容器的网络,仅两个容器间网络互通。
  2. 为什么称这种模式为 Sidecar(边车模式)?辅助容器像 "边车" 一样依附于主容器,为主容器提供辅助功能(日志、监控),且共享网络,通信高效。

场景四:自定义 bridge 网络 ------ 多容器固定 IP 通信

场景背景

多服务系统(Web + App + DB),需网络隔离、容器固定 IP、容器名通信。

任务步骤
  1. 创建自定义 bridge 网络(指定子网和网关): bash

    运行

    复制代码
    docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my-custom-net
  2. 启动容器并指定固定 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
  3. 容器间通信测试: 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 通。
思考题
  1. 为什么默认 bridge 不能指定 IP?默认 bridge 网络未配置固定子网,Docker 不支持手动指定 IP;自定义网络需提前指定子网,才能分配固定 IP。
  2. 自定义网络适合什么场景?适合多服务协作、需要网络隔离、固定 IP 或容器名通信的场景(如微服务集群、多环境部署)。
  3. Docker 如何实现容器间二层通信?通过 Linux 网桥(bridge)和 veth 设备对实现:每个容器有一个 veth 接口,一端连接容器网络命名空间,另一端连接 Docker 网桥,网桥负责转发容器间的二层数据包。

四、常见错误提醒(避坑指南)

  1. 容器启动后立即退出 :如 docker run -it centos:7 bash,退出 bash 后容器停止 → 原因:PID=1 进程(bash)退出,容器生命周期结束。解决方案:运行前台进程(如 sleep 3600nginx -g "daemon off;")。
  2. docker exec 无法进入容器 :需确保容器处于运行中(Up 状态),先执行 docker start 容器名 再进入。
  3. docker rm 无法删除容器 :运行中的容器需先停止(docker stop)或强制删除(docker rm -f)。
  4. 批量删除命令慎用docker stop $(docker ps -q)docker rm -f $(docker ps -aq) 等批量命令仅适合实验环境,生产环境需指定容器名 / ID 精准操作,避免误删。

五、总结

本文档完整覆盖了 Docker 容器化服务的全生命周期操作,从上线发布到下线清理,再到四大网络模式的生产场景实践,每个步骤均经过实测验证。通过本文实践,可掌握 Docker 核心运维技能,理解容器化的优势与网络隔离原理,为生产环境运维打下基础。建议在实验环境反复练习后,再应用到实际业务场景。

相关推荐
代码匠心3 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong4 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode4 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户5433081441944 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo4 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭5 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木5 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮5 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati5 小时前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉5 小时前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain