如果你曾被“在我电脑上能跑”的部署难题折磨,或为服务器资源占用过高而头疼,那Docker一定是你的救星。作为容器化技术的标杆,Docker彻底改变了应用的开发、测试和部署模式。本文将从核心原理到实操步骤,带你系统性掌握Docker,让容器化技术落地到实际开发中。

一、Docker核心原理:看透容器化的本质

Docker的核心思想是“封装”与“隔离”,它不仅是工具,更是一种DevOps理念的落地。

在学习操作前,我们必须先搞懂:Docker到底是什么?它凭什么实现“一次构建,到处运行”?这就需要从其解决的痛点和底层技术说起。

1.1 为什么需要Docker?传统部署的三大痛点

在Docker出现前,开发者和运维人员常陷入这些困境:

  • 环境不一致:开发机上跑的好好的代码,部署到测试机或生产机就报错,原因可能是依赖版本、系统配置不同,俗称“环境污染”。
  • 资源占用高:为了解决环境隔离,传统方案用虚拟机(VM),但每个VM都需要独立的操作系统,存在占用内存、CPU资源多,启动慢等问题。
  • 部署效率低:部署一个应用需要手动安装依赖、配置环境,步骤繁琐且易出错,无法快速规模化复制。

Docker的核心价值就是解决这些问题:通过容器化技术,实现环境一致性、轻量级隔离和高效部署。而这一切的背后,依赖于Linux内核的三大核心技术——镜像、容器、仓库。

1.2 Docker核心概念:镜像、容器、仓库

Docker有三个最基础的概念,理解它们就理解了Docker的80%:

  1. 镜像(Image):可理解为“应用的模板”,包含了运行应用所需的代码、依赖、系统库、配置等所有内容。比如“nginx镜像”就是包含nginx服务的完整环境模板,镜像本身是只读的,不能修改。
  2. 容器(Container):镜像的“运行实例”,是一个独立的可执行单元。相当于基于镜像创建的“临时沙箱”,可以启动、停止、删除。容器和镜像的关系,就像“类和对象”的关系——一个镜像可以创建多个容器。
  3. 仓库(Repository):存放镜像的“云端仓库”,类似GitHub等平台存放代码的逻辑。Docker官方提供了公共仓库Docker Hub,包含数十万现成镜像(如Nginx、MySQL等);企业或个人也可搭建私有仓库,用于存放内部业务镜像,保障安全性。

1.3 底层技术支撑:Docker为什么能“轻量级隔离”?

很多人会把Docker和虚拟机混淆,其实二者本质不同:虚拟机是“硬件级隔离”,需要模拟完整操作系统;而Docker是“内核级隔离”,共享宿主机内核,仅隔离应用所需的资源。这一切依赖Linux内核的三个关键技术:

  • Namespace(命名空间):实现“环境隔离”的核心。Linux内核提供了PID(进程)、NET(网络)、Mount(文件系统)等多种命名空间,每个容器会被分配独立的命名空间。比如PID命名空间让容器内的进程以为自己是“进程1”(初始化进程),但在宿主机看来只是普通进程;NET命名空间让容器拥有独立的网卡、IP,实现网络隔离。
  • Cgroups(控制组):实现“资源限制”的关键。用于限制容器对CPU、内存、磁盘IO等资源的占用,避免某个容器过度消耗资源影响其他容器。比如可限制某个容器最多使用1核CPU和2GB内存。
  • UnionFS(联合文件系统):实现“镜像分层”和“写时复制”的基础。镜像由多个只读层叠加而成,比如一个Nginx镜像可能包含“操作系统基础层”“依赖库层”“Nginx应用层”,分层设计让镜像复用性更高(多个镜像可共享基础层)。容器启动时会在镜像顶层加一个“可写层”,所有修改都只作用于该层,镜像本身保持只读,这就是“写时复制”,既节省空间又保障镜像安全。

1.4 Podman和Docker

CentOS 8 及后续版本默认使用 Podman 替代 Docker,这是由红帽(Red Hat)主导的技术战略调整,核心原因包括架构革新、安全增强和生态适配。以下是具体原因分析:

  • RHEL 8 官方弃用 Docker
  • 自 RHEL 8 起,红帽不再将 Docker 作为官方支持的容器引擎,转而主推由其开发的 Podman + Buildah + CRI-O 工具链。这一策略直接影响了 CentOS 8 及后续发行版本(如 CentOS Stream 10)的默认配置。
  • 红帽通过 Podman(容器运行时)、Buildah(镜像构建)、Skopeo(镜像传输)等工具,构建了一个基于 OCI 标准的模块化容器生态。这种设计更符合 Unix 哲学,每个工具专注解决单一问题,而非像 Docker 那样采用 “大而全” 的单体架构。

二、Docker实操教程:从安装到实战部署

原理讲透后,进入实操环节。以下步骤适配Windows、macOS、Linux三大系统,以“安装→核心操作→实战部署”为逻辑展开。

2.1 第一步:Docker安装(三大系统适配)

Docker分为社区版(CE)和企业版(EE),个人和中小企业用CE足够,免费且功能完整。如果需要私有化搭建一套镜像云仓库,可以采用由VMWare公司开源的容器镜像仓库——Harbor,搭建方式和流程具体可以访问Harbor - Harbor 镜像仓库文档查看详情。

2.1.1 Windows系统安装(Win10及以上)

由于Docker依赖Linux内核,那就需要在Windows系统上开启WSL环境支持。

WSL的本质是 Windows 内核中集成的轻量级 Linux 子系统,从WSL2开始不再依赖 Windows 内核翻译 Linux 系统调用,而是自带完整 Linux 内核(由微软编译维护),性能接近物理机或虚拟机,基于 Hyper-V 技术实现,但无需完整虚拟机的资源开销,核心是让 Linux 环境在 Windows 上 “原生运行” 而非模拟。

  1. 开启“虚拟化”:进入BIOS(开机时按ESC/F2/F10/F12等,不同主板不同),找到“Virtualization Technology”等类似选项并开启。
  2. 安装WSL2(适用于Windows的Linux子系统):Docker Desktop依赖WSL2运行,Win10需升级到2004版本以上,通过“设置→应用→可选功能→更多Windows功能”勾选“适用于Linux的Windows子系统”和“虚拟机平台”,重启电脑后安装WSL2(可参考微软官方文档)。
  3. 下载Docker Desktop:从Docker官网下载Windows版本,双击安装,启动后桌面右下角托盘处出现鲸鱼图标,即表示安装成功。

2.1.2 macOS系统安装

  1. 检查系统版本:需macOS 11(Big Sur)及以上版本,M1/M2芯片和Intel芯片均适配。
  2. 下载安装:从Docker官网下载macOS版本,拖拽到应用文件夹,启动后在顶部菜单栏出现鲸鱼图标,打开终端输入 docker --version,显示版本信息即安装成功。

输出内容示例:

[root@data ~]# docker --version
Docker version 28.4.0, build d8eb465

2.1.3 Linux系统安装(以CentOS 8为例)

CentOS默认安装

  1. 卸载旧版本(若有):

    [root@data ~]# yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
    
  2. 安装依赖:

    [root@data ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
    
  3. 设置镜像源:使用阿里云镜像源加速

    [root@data ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
  4. 安装Docker CE:

    [root@data ~]# yum install -y docker-ce docker-ce-cli containerd.io
    
  5. 启动Docker并设置开机自启:sudo

    [root@data ~]# systemctl enable --now docker
    
  6. 验证:sudo docker --version,显示版本信息即成功。

    [root@data ~]# docker --version
    Docker version 28.4.0, build d8eb465
    

2.2 核心操作:镜像与容器的常用命令

Docker的操作核心围绕“镜像”和“容器”展开,记住以下命令,就能应对80%的日常场景。建议先打开终端(Windows用PowerShell,Linux/macOS用终端),跟着实操。

2.2.1 镜像操作:拉取、查看、删除

操作目的 命令 说明
拉取镜像 docker pull 镜像名:标签 标签指定版本, 如:docker pull nginx:1.24(不写标签默认latest)
查看本地镜像 docker images 显示镜像ID、标签、大小等信息
删除镜像 docker rmi 镜像ID/镜像名:标签 需先删除依赖该镜像的容器,加 -f强制删除
搜索镜像 docker search 镜像名 从Docker Hub搜索镜像,如 docker search mysql

2.2.2 容器操作:创建、启动、进入、删除

操作目的 命令 说明
创建并启动容器 docker run [参数] 镜像名:标签 最核心命令,常用参数:-d 后台运行
-p 宿主机端口:容器端口(端口映射)
--name 容器名(自定义名称)
--rm 运行一次,容器停止后自动移除挂载本机目录到容器目录
查看运行中容器 docker ps -a查看所有容器(包括停止的)
进入运行中容器 docker exec -it 容器ID/容器名 /bin/bash -it 实现交互模式 /bin/bash进入容器终端(部分容器用sh)
容器ID可输入部分内容,容器名称需要完整输入
启动/停止容器 docker start/stop 容器ID/容器名 停止后可重新启动,无需重新创建
删除容器 docker rm 容器ID/容器名 需先停止容器,加-f强制删除运行中的容器
查看容器日志 docker logs -f 容器ID/容器名 -f 实时跟踪日志输出,排查问题常用
复制文件命令 docker cp 宿主机目录 容器ID/容器名:路径 将容器内容复制到宿主机:docker cp 容器ID/容器名:路径 宿主机路径

重点提示:端口映射是容器对外提供服务的关键,比如 docker run -d -p 8080:80 --name mynginx nginx,表示将宿主机8080端口映射到容器80端口,访问宿主机 IP:8080即可进入Nginx首页。

命令示例:

docker ps :

[root@data volumes]# docker ps
CONTAINER ID   IMAGE                                                                                    COMMAND                   CREATED        STATUS                          PORTS                                                                                                                                                                                                                                                   NAMES
1916a6118e62   docker.1ms.run/openlistteam/openlist:latest                                              "/entrypoint.sh"          2 weeks ago    Up 2 weeks                      0.0.0.0:5244->5244/tcp, [::]:5244->5244/tcp, 5245/tcp                                                                                                                                                                                                   openlist
80e2b0cce056   1panel/node:20.14.0                                                                      "docker-entrypoint.s…"   4 weeks ago    Up 4 weeks                      0.0.0.0:8801->8000/tcp                                                                                                                                                                                                                                  SoftEtherAdmin-ns1
b7d80b27e64a   1panel/node:20.14.0                                                                      "docker-entrypoint.s…"   4 weeks ago    Up 4 weeks                      0.0.0.0:8800->8000/tcp                                                                                                                                                                                                                                  SoftEtherAdmin-90
054180110f19   homeassistant/home-assistant:2025.10.1                                                   "/init"                   4 weeks ago    Up 4 weeks                                                                                                                                                                                                                                                                              home-assistant
addf356c6e41   docker.1ms.run/emqx/emqx:6.0.0                                                           "/usr/bin/docker-ent…"   4 weeks ago    Up 4 weeks (healthy)            4370/tcp, 0.0.0.0:1883->1883/tcp, [::]:1883->1883/tcp, 0.0.0.0:8883->8883/tcp, [::]:8883->8883/tcp, 5369/tcp, 0.0.0.0:8882->8083/tcp, [::]:8882->8083/tcp, 0.0.0.0:8884->8084/tcp, [::]:8884->8084/tcp, 0.0.0.0:8073->18083/tcp, [::]:8073->18083/tcp   emqx
7e98d02e92ce   docker.1ms.run/grafana/promtail:1.5.0                                                    "/usr/bin/promtail -…"   5 weeks ago    Up 5 weeks                                                                                                                                                                                                                                                                              promtail
6cdd1a81cfa7   docker.1ms.run/grafana/loki:1.5.0                                                        "/usr/bin/loki -conf…"   5 weeks ago    Up 5 weeks                      0.0.0.0:3100->3100/tcp, [::]:3100->3100/tcp                                                                                                                                                                                                             loki
c4100dc56acc   docker.1ms.run/houyuxi/mobakey:x86                                                       "/docker-entrypoint.…"   6 weeks ago    Up 6 weeks                      0.0.0.0:8083->80/tcp, [::]:8083->80/tcp                                                                                                                                                                                                                 mobaxterm-license
9e324c2c326e   docker.1ms.run/mayswind/ezbookkeeping:latest                                             "/docker-entrypoint.…"   6 weeks ago    Up 3 weeks                      0.0.0.0:8076->8080/tcp, [::]:8076->8080/tcp                                                                                                                                                                                                             ezbookkeeping
a349b1802c01   docker.1ms.run/vaultwarden/server:latest                                                 "/start.sh"               7 weeks ago    Up 7 weeks (healthy)            0.0.0.0:5080->80/tcp, [::]:5080->80/tcp                                                                                                                                                                                                                 vaultwarden
bc77bb2a9541   docker.1ms.run/geekyouth/moodist:v1.2.0                                                  "/docker-entrypoint.…"   7 weeks ago    Up 7 weeks                      80/tcp, 0.0.0.0:8095->8080/tcp, [::]:8095->8080/tcp                                                                                                                                                                                                     moodist
255b332ce515   docker.1ms.run/monday1/threat-intel-hub:latest                                           "python app.py"           7 weeks ago    Up 7 weeks                      0.0.0.0:8891->8891/tcp, [::]:8891->8891/tcp                                                                                                                                                                                                             threat-intel-hub-app
eab119505e89   php:8.0.30-fpm-alpine                                                                    "docker-php-entrypoi…"   7 weeks ago    Up 7 weeks                      127.0.0.1:9009->9000/tcp                                                                                                                                                                                                                                1Panel-php8-uYLI
148b47d1a4ef   1panel/node:20.14.0                                                                      "docker-entrypoint.s…"   8 weeks ago    Up 8 weeks                      0.0.0.0:3008->3000/tcp                                                                                                                                                                                                                                  OfficeHub
d2b54491f9a5   1panel/node:20.14.0                                                                      "docker-entrypoint.s…"   8 weeks ago    Up 8 weeks                      0.0.0.0:8043->80/tcp                                                                                                                                                                                                                                    miku
3f7eb3bc5662   docker.1ms.run/yunyoujun/cook:latest                                                     "/docker-entrypoint.…"   2 months ago   Up 2 months                     0.0.0.0:5091->80/tcp, [::]:5091->80/tcp

2.3 进阶操作:自定义镜像(Dockerfile)

现成镜像无法满足所有需求,比如我们需要一个包含自定义代码的 Python应用镜像,这就需要用 Dockerfile构建自定义镜像。Dockerfile是一个文本文件,包含构建镜像的指令集合。

2.3.1 Dockerfile核心指令

指令 作用
FROM 指定基础镜像,如:FROM python:3.9(基于Python 3.9镜像构建)
WORKDIR 设置容器工作目录,后续指令在此目录执行,如:WORKDIR /app (工作目录为 /app)
COPY 将宿主机文件复制到镜像中,如:COPY . /app(复制当前shell所在目录到镜像 /app目录)
RUN 构建镜像时执行的命令,如:RUN pip install -r requirements.txt(安装依赖)
EXPOSE 声明容器运行时监听的端口(仅声明,不映射)
CMD 容器启动时执行的命令,如:CMD ["python", "app.py"](启动Python应用)

Dockerfile示例:

FROM docker.1ms.run/node:21
# 设置工作目录
WORKDIR /app
# 复制项目文件到容器中
COPY ./ /app
# 安装依赖
#RUN ping -w 3 so.com
RUN npm config set registry http://mirrors.cloud.tencent.com/npm && npm install -f
# 构建项目
RUN npm config set registry http://mirrors.cloud.tencent.com/npm && npm run build
# 暴露端口
EXPOSE 3000
# 启动服务
CMD ["npm", "run", "start"]

2.3.2 构建自定义镜像实操

以构建一个简单的Python Flask应用镜像为例:

准备应用文件:创建文件夹app,内有app.py(Flask代码)和requirements.txt(依赖列表,写flask)。

  1. 编写Dockerfile:在app文件夹内创建Dockerfile,内容如下:
    # 基础镜像
    FROM python:3.9
    # 工作目录
    WORKDIR /app
    # 复制依赖文件
    COPY requirements.txt
    # 安装依赖
    RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
    # 复制应用代码
    COPY .
    # 声明端口
    EXPOSE 5000 # 启动命令 CMD ["python", "app.py"]
    
  2. 构建镜像:进入app文件夹,执行命令 docker build -t myflask:1.0 . 其中 -t指定镜像名和标签,.表示Dockerfile所在目录。

启动容器:docker run -d -p 5000:5000 --name myflaskapp myflask:1.0,访问宿主机IP:5000即可看到Flask应用页面。

2.4 实战案例:用Docker部署Nginx并挂载配置

实际开发中,常需要修改容器配置文件,直接进入容器修改会丢失(容器删除后配置消失),因此需要“数据挂载”——将宿主机文件挂载到容器,实现配置持久化。以Nginx为例:

  1. 宿主机准备配置:创建文件夹/nginx/conf,将Nginx配置文件 nginx.conf放入该目录(可从容器中复制默认配置:docker cp mynginx:/etc/nginx/nginx.conf /nginx/conf/mynginx是临时启动的容器名)。
  2. 挂载启动容器:docker run -d -p 80:80 --name mynginx -v /nginx/conf/nginx.conf:/etc/nginx/nginx.conf nginx,其中 -v表示挂载,格式为“宿主机路径:容器路径”。
  3. 修改配置:直接修改 宿主机/nginx/conf/nginx.conf,执行 docker restart mynginx 重启容器,配置即可生效,无需重新构建镜像。

三、Docker常用技巧与注意事项

3.1 镜像加速:解决拉取镜像慢的问题

国内访问Docker Hub速度较慢,可配置国内镜像源(如阿里云、网易云):

  • Windows/macOS:打开Docker Desktop,进入Settings→Docker Engine,在配置文件中添加:

    "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]```bash
    
  • Linux:创建 /etc/docker/daemon.json文件,写入:

    { "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"] }
    

    然后执行 systemctl daemon-reload && sudo systemctl restart docker

  • 具体Docker加速源可以在网上可以查找到:

    常用加速源示例
    1. 常见国内加速源
    阿里云: https://<你的专属加速器地址>(需登录阿里云获取)
    腾讯云: https://mirror.ccs.tencentyun.com
    网易云: https://hub-mirror.c.163.com
    华为云: https://repo.huaweicloud.com
    中国科技大学(已改为科大内网使用): https://docker.mirrors.ustc.edu.cn
    

3.2 数据持久化:容器数据不丢失的关键

容器删除后,内部数据会丢失,除了上述“绑定挂载”(-v 宿主机路径:容器路径),还可使用“数据卷”(Docker管理的宿主机目录,更安全):

  1. 创建数据卷:docker volume create nginx-vol
  2. 挂载数据卷启动:docker run -d -p 80:80 -v nginx-vol:/etc/nginx/conf nginx,Docker会将数据卷映射到宿主机 /var/lib/docker/volumes/nginx-vol/目录。

3.3 常见问题示例和排查

创建容器启动失败输出内容示例:

  1. 端口已经被其他进程绑定

    Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:8080 -> 0.0.0.0:0: listen tcp 0.0.0.0:8080: bind: address already in use
    
  2. 镜像不存在:

    Error response from daemon: pull access denied for myapp, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
    
  3. 标签类

    Error response from daemon: No such image: myapp:v1.0 (tag: v1.0, digest: none)
    
  4. 权限类

    Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied
    

四、网络

在 Docker 容器化部署中,网络是连接容器与容器、容器与宿主机、容器与外部网络的核心桥梁。无论是单机部署的多容器协作,还是跨主机的集群通信,理解 Docker 网络的工作机制都是实现灵活、可靠部署的关键。本文将从基础概念出发,逐步拆解 Docker 的网络模式、核心原理、实战配置及常见问题,帮助你全面掌握 Docker 网络。

4.1 Docker 网络核心概念

在深入网络模式前,先明确几个关键术语,避免理解偏差:

  • Docker 守护进程(Docker Daemon):管理容器生命周期的核心服务,网络功能由其内置的网络驱动实现。
  • 网络命名空间(Network Namespace):Linux 内核提供的网络隔离技术,每个容器默认拥有独立的命名空间,包含独立的网卡、IP、路由表、端口等网络资源,实现容器间网络隔离。
  • 网络驱动(Network Driver):Docker 通过不同的网络驱动支持多种网络模式,默认包含 bridge、host、none、overlay 等,也支持第三方驱动(如 macvlan、calico)。
  • 容器网络栈(Container Network Stack):容器的网络配置集合,包括网卡(eth0)、回环设备(lo)、路由规则、DNS 配置等,由 Docker 根据网络模式自动配置或自定义配置。

4.2 Docker 默认网络模式详解

Docker 安装后会自动创建 3 种默认网络,可通过 docker network ls 查看:

[root@data ~]# docker network ls
NETWORK ID     NAME                              DRIVER    SCOPE
efafba1633bd   bridge                            bridge    local
575d852f775a   host                              host      local
ced83d6171f4   none                              null      local

4.2.1 bridge 模式(默认模式)

工作原理

  • 当启动容器时,若未指定网络模式,Docker 会自动将容器连接到 bridge 网络(默认名称为 bridge,可自定义)。
  • Docker 在宿主机上创建一个虚拟网桥 docker0(默认 IP 为 172.17.0.1/16),每个容器会获得一个虚拟网卡 eth0,并分配该网段内的私有 IP(如 172.17.0.2)。
  • 容器通过 docker0 网桥与宿主机、其他容器通信,宿主机通过 NAT(网络地址转换)实现容器访问外部网络,外部网络通过端口映射(-p)访问容器。

核心特点

  • 隔离性:容器间默认可通过 IP 通信,但需暴露端口才能被外部访问。
  • 灵活性:支持端口映射、自定义 IP、DNS 配置,满足大多数单机多容器场景(如前端 + 后端 + 数据库的组合部署)。
  • 局限性:跨主机容器通信需额外配置(如端口映射、overlay 网络),默认不支持容器名称直接通信(需通过 --link 或自定义网络实现)。

示例

# 1. 启动两个容器(默认连接bridge网络)
docker run -d --name app1 nginx
docker run -d --name app2 tomcat

# 2. 查看容器IP(通过inspect命令)
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' app1  # 输出172.17.0.2
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' app2  # 输出172.17.0.3

3. 容器间通信(通过IP)

docker exec -it app1 ping 172.17.0.3  # app1可ping通app2

4. 端口映射(外部访问容器)

docker run -d --name app3 -p 8080:80 nginx  # 宿主机8080端口映射容器80端口

外部通过 http://宿主机IP:8080 访问nginx

4.2.2 host 模式

工作原理

  • 容器直接使用宿主机的网络命名空间,不创建独立的网卡和 IP,容器内的端口直接映射到宿主机的对应端口。
  • 容器内的网络配置(IP、路由、DNS)与宿主机完全一致,相当于在宿主机上直接运行应用程序。

核心特点

  • 性能最优:无网络隔离开销,网络通信效率与宿主机原生应用一致。
  • 无端口映射:容器端口直接暴露在宿主机,无需通过 -p 参数映射(如容器内启动 80 端口,外部直接访问宿主机 IP:80 即可)。
  • 局限性:端口冲突风险高(多个容器不能使用同一端口),网络隔离性差(容器可访问宿主机所有网络资源),不支持跨平台(Docker Desktop for Mac/Windows 不支持 host 模式)。

示例

# 启动容器使用host模式(注意:宿主机80端口需未被占用)
docker run -d --name app4 --network host nginx

# 外部直接访问宿主机IP:80(无需端口映射)
curl http://宿主机IP  # 即可访问nginx默认页面

4.2.3 none 模式

工作原理

  • 容器拥有独立的网络命名空间,但 Docker 不配置任何网络资源(无网卡、IP、路由),容器仅能通过回环设备(lo)进行内部通信。
  • 适用于无需网络通信的场景(如离线数据处理、本地计算任务),或需要完全自定义网络配置的场景(如手动配置网卡、IP)。

核心特点

  • 完全隔离:与外部网络、其他容器、宿主机均无网络连接。
  • 高度自定义:需手动通过 ip 命令配置网络(如添加网卡、设置 IP),灵活性极高但配置复杂。

示例

# 启动容器使用none模式
docker run -it --name app5 --network none alpine

# 容器内查看网络配置(仅lo设备)
ip addr  # 输出:1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000

4.2.4 overlay 模式(跨主机网络)

工作原理

  • overlay 网络是 Docker Swarm(Docker 原生集群编排工具)的默认跨主机网络模式,基于 VXLAN(虚拟扩展局域网)技术,将多个宿主机的网络连接成一个虚拟网络。
  • 每个 overlay 网络包含两个子网:一个用于容器间通信(虚拟子网),一个用于宿主机间的控制平面通信( gossip 协议),容器在跨主机通信时,数据包通过 VXLAN 隧道加密传输。

核心特点

  • 跨主机通信:不同宿主机上的容器可在同一 overlay 网络中直接通信,无需端口映射。
  • 服务发现:支持通过 Docker Swarm 的服务名称(Service Name)自动解析 IP,实现容器间服务发现。
  • 局限性:依赖 Docker Swarm 或第三方编排工具(如 Kubernetes),单机场景下无意义,配置相对复杂。

示例(Docker Swarm 环境)

# 1. 初始化Docker Swarm(主节点)
docker swarm init --advertise-addr 宿主机IP

# 2. 创建overlay网络
docker network create -d overlay my-overlay-network

# 3. 部署服务到overlay网络(跨主机可访问)
docker service create --name web --network my-overlay-network -p 80:80 nginx

# 4. 其他宿主机加入Swarm后,服务会自动调度,容器间可通过服务名通信

4.2.5 macvlan 模式(模拟物理网络)

工作原理

  • macvlan 网络允许容器直接使用宿主机的物理网卡,为每个容器分配独立的 MAC 地址和 IP 地址(与宿主机在同一网段),相当于将容器伪装成物理网络中的独立设备。
  • 容器与宿主机、其他物理设备在同一广播域,可直接通过 IP/MAC 通信,无需 NAT 或端口映射。

核心特点

  • 物理网络集成:容器完全融入现有物理网络,适用于需要与物理设备(如打印机、IoT 设备)通信的场景。
  • 无网络转发开销:通信效率接近物理机,无 NAT 转发损耗。
  • 局限性:需宿主机网卡支持混杂模式(Promiscuous Mode),可能与部分网络设备(如路由器)不兼容,IP 地址需手动规划(避免与物理设备冲突)。

示例

# 1. 创建macvlan网络(指定宿主机物理网卡eth0,子网与宿主机一致)
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \  # 宿主机所在子网
  --gateway=192.168.1.1 \    # 网关(与宿主机一致)
  --ip-range=192.168.1.100/28 \  # 容器IP地址范围
  -o parent=eth0 \  # 宿主机物理网卡
  my-macvlan-network

# 2. 启动容器使用macvlan网络
docker run -d --name app6 --network my-macvlan-network --ip 192.168.1.101 nginx

# 3. 物理网络中的设备可直接访问192.168.1.101(无需端口映射)

4.3 Docker 网络核心原理

1. 网络命名空间隔离

  • Linux 内核通过 network namespace 实现网络资源隔离,每个容器启动时,Docker 会调用 ip netns add 命令创建独立的命名空间。
  • 容器的网络命名空间与宿主机、其他容器完全隔离,仅通过虚拟设备(如 veth pair、网桥)实现通信。

2. 虚拟设备通信

  • veth pair(虚拟网卡对):Docker 为每个 bridge 模式的容器创建一对虚拟网卡(veth0 和 veth1),一端绑定到容器的网络命名空间(eth0),另一端连接到宿主机的 docker0 网桥,实现容器与网桥的通信。
  • docker0 网桥:宿主机上的虚拟网桥,相当于一个交换机,连接所有 bridge 模式的容器,负责转发容器间、容器与宿主机的网络数据包。

3. 网络地址转换(NAT)

  • 容器访问外部网络:容器发出的数据包经 docker0 网桥转发到宿主机,宿主机通过 SNAT(源地址转换)将容器私有 IP 转换为宿主机公网 IP,实现外部网络访问。
  • 外部访问容器:通过 -p 宿主机端口:容器端口 配置 DNAT(目的地址转换),外部数据包访问宿主机端口时,被转发到对应容器的端口。

4. DNS 与服务发现

  • Docker 内置 DNS 服务(默认监听 127.0.0.11:53),容器内的 DNS 配置默认指向该服务,实现:
    • 容器名称解析(自定义网络中,容器可通过名称直接通信,无需 IP);
    • 服务名称解析(Docker Swarm 或 Kubernetes 环境中,通过服务名自动解析到容器 IP)。

4.4 Docker 网络配置

1. 自定义 bridge 网络(推荐)

默认的 bridge 网络不支持容器名称解析,自定义 bridge 网络可解决该问题,且支持更多配置(如子网、网关、DNS):

# 1. 创建自定义bridge网络
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \  # 自定义子网
  --gateway=172.20.0.1 \    # 网关
  --dns=8.8.8.8 \           # DNS服务器
  my-bridge-network

# 2. 启动容器连接到自定义网络
docker run -d --name app7 --network my-bridge-network nginx
docker run -d --name app8 --network my-bridge-network tomcat

# 3. 容器间可通过名称通信(无需IP)
docker exec -it app7 ping app8  # 直接ping容器名称,自动解析IP

2. 容器网络连接与断开

# 1. 为运行中的容器添加网络
docker network connect my-bridge-network app1  # 将app1连接到my-bridge-network

# 2. 断开容器与网络的连接
docker network disconnect my-bridge-network app1

# 3. 查看容器的网络连接状态
docker inspect -f '{{.NetworkSettings.Networks}}' app1

3. 端口映射高级配置

  • 指定绑定 IP:仅允许特定 IP 访问容器端口

    docker run -d --name app9 -p 192.168.1.10:8080:80 nginx  # 仅宿主机192.168.1.10的8080端口映射容器80端口
    
  • UDP 端口映射:默认映射 TCP 端口,需显式指定 UDP

    docker run -d --name app10 -p 53:53/udp dnsmasq  # 映射UDP 53端口(DNS服务)
    
  • 随机端口映射:让 Docker 自动分配宿主机端口(范围 49153-65535)

    docker run -d --name app11 -p 80 nginx  # 宿主机随机端口映射容器80端口,通过docker ps查看端口
    

4. 网络数据卷与网络共享

通过 --mount-v 挂载网络存储(如 NFS、Ceph),实现容器间数据共享:

# 挂载NFS网络存储到容器
docker run -d --name app12 -v nfs-server:/data nginx

4.5 Docker网络常见问题与排查

1. 容器间无法通信

  • 检查容器是否在同一网络:docker inspect -f '{{.NetworkSettings.Networks}}' 容器名
  • 自定义网络支持名称解析,默认 bridge 网络需通过 IP 通信或 --link(不推荐)
  • 检查防火墙规则:宿主机防火墙(如 iptables、firewalld)是否阻止容器间通信

2. 外部无法访问容器

  • 检查端口映射配置:docker ps 查看端口映射是否正确(如宿主机端口是否被占用)
  • 检查容器状态:容器是否正常运行(docker ps 查看状态为 up)
  • 检查宿主机 IP:外部访问需使用宿主机的公网 IP(云服务器需配置安全组开放端口)

3. 容器无法访问外部网络

  • 检查 DNS 配置:容器内 cat /etc/resolv.conf 查看 DNS 是否正确(可自定义 --dns 参数)
  • 检查宿主机网络:宿主机是否能正常访问外部网络(如 ping 8.8.8.8
  • 检查 iptables 规则:宿主机 iptables 是否禁止 NAT 转发(可通过 iptables -L -n 查看)

4. 网络冲突

  • 自定义网络子网避免与宿主机、其他网络重叠(如默认 bridge 网络是 172.17.0.0/16,自定义网络可使用 172.20.0.0/16)
  • macvlan 网络的 IP 地址需避免与物理网络中的设备冲突

五、总结与进阶方向

本文从原理到实操覆盖了Docker的核心内容:通过Namespace、Cgroups、UnionFS三大技术实现轻量级隔离的原理,镜像、容器、仓库的核心概念,以及安装、命令操作、自定义镜像、实战部署的完整流程。掌握这些内容后,你已经能应对日常开发中的容器化需求。

进阶方向建议:

  • 容器编排:学习Docker Compose(管理多容器应用)、Kubernetes(大规模容器集群编排)。
  • 镜像优化:减少镜像体积(如使用多阶段构建、精简基础镜像)。
  • CI/CD集成:将Docker与Jenkins等工具结合,实现自动化构建、测试、部署。

image.png

评论