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 核心运维技能,理解容器化的优势与网络隔离原理,为生产环境运维打下基础。建议在实验环境反复练习后,再应用到实际业务场景。

相关推荐
Ronin3052 小时前
【Linux网络】多路转接poll
linux·网络·io·多路转接·poll
一字白首2 小时前
Vuex 进阶,模块化开发(Modules):解决单状态树臃肿问题
前端·javascript·vue.js
ICT技术最前线2 小时前
H3C策略路由如何优化企业网络?
网络
allk552 小时前
Android 性能优化深水区:电量与网络架构演进
android·网络·性能优化
旧梦吟2 小时前
脚本网页 linux内核源码讲解
linux·前端·stm32·算法·html5
李少兄3 小时前
深入理解 CSS :not() 否定伪类选择器
前端·css
wanhengidc4 小时前
物理服务器与云服务器的不同之处
运维·服务器·网络·游戏
Lucky小小吴4 小时前
ClamAV扫描速度提升6.5倍:服务器杀毒配置优化实战指南
java·服务器·网络·clamav