Docker 容器化技术核心知识笔记

Docker 容器化技术核心知识笔记

配套视频链接:40分钟的Docker实战攻略,一期视频精通Docker_哔哩哔哩_bilibili

0. Docker 常用命令一览表

1. 容器生命周期管理 (Container Lifecycle)

这是最基础的操作,决定了容器的生与死。

命令 常用参数 说明 来源/备注
docker run -d (后台), -p (端口), -v (卷), --name (命名), --restart always, -e (环境变量) 核心命令:创建并启动容器
docker start - 启动一个或多个已被停止的容器
docker stop - 优雅停止容器(发送 SIGTERM 信号)
docker restart - 重启容器
docker kill - 强制停止容器(发送 SIGKILL 信号) 紧急情况下使用
docker rm -f (强制), -v (同时删除挂载卷) 删除容器
docker create - 创建容器但不启动
docker pause/unpause - 暂停/恢复容器内所有进程 较少用,用于冻结状态

2. 容器运维与调试 (Operations & Debugging)

当容器"跑不起来"或者"表现奇怪"时,这些是你的救命稻草。

命令 常用参数 说明 来源/备注
docker ps -a (所有), -q (只显示ID), --format 查看容器列表
docker logs -f (实时跟踪), --tail N (查看末尾N行) 查看容器标准输出日志
docker exec -it (交互式终端), -u (指定用户) 进入运行中的容器执行命令
docker inspect - 查看容器/镜像的元数据 (IP、路径等)
docker stats --no-stream 实时查看容器资源占用 (CPU/内存)
docker top - 查看容器内运行的进程信息 类似 Linux top
docker cp - 在宿主机和容器之间复制文件 docker cp src dest
docker diff - 查看容器文件系统的变更 检查文件是否被篡改

3. 镜像管理 (Image Management)

构建、分发和清理镜像。

命令 常用参数 说明 来源/备注
docker images -a, -q 列出本地镜像
docker pull --platform (指定架构) 从仓库拉取镜像
docker build -t (标签), -f (指定Dockerfile路径), --no-cache 根据 Dockerfile 构建镜像
docker rmi -f (强制删除) 删除本地镜像
docker tag - 给镜像打标签 (常用于推送前)
docker push - 推送镜像到远程仓库
docker history - 查看镜像的构建历史 (层) 分析镜像体积过大原因
docker save -o (输出文件) 将镜像保存为 tar 归档文件 离线迁移
docker load -i (输入文件) 从 tar 归档文件加载镜像 离线迁移
docker search --filter=stars=N 在 Docker Hub 搜索镜像

4. 网络与存储 (Network & Volume)

处理容器间的通信和数据持久化。

命令 常用参数 说明 来源/备注
docker network ls - 列出所有网络
docker network create --driver bridge/overlay 创建自定义网络
docker network connect - 将容器连接到某个网络
docker network inspect - 查看网络详情 (含子网IP信息) 排查网络不通问题
docker volume ls - 列出所有数据卷
docker volume create - 创建数据卷
docker volume inspect - 查看卷详情 (找宿主机真实路径)
docker volume prune -a 慎用:删除未使用的卷

5. 系统维护 (System Maintenance)

保持 Docker 环境的整洁和健康。

命令 常用参数 说明 来源/备注
docker system prune -a (含未使用镜像), --volumes 一键清理:停止的容器、悬空镜像、网络
docker info - 显示 Docker 系统信息 (内核、插件等)
docker version - 显示版本信息
docker login/logout - 登录/登出 镜像仓库

6. Docker Compose (多容器编排)

现在官方推荐使用 docker compose (v2) 而不是 docker-compose (v1)。

命令 常用参数 说明 来源/备注
docker compose up -d (后台), --build (重构) 启动所有服务
docker compose down -v (同时删卷) 停止并移除容器、网络
docker compose ps - 查看当前编排的服务状态
docker compose logs -f 查看编排服务的日志

1. 容器化技术概述

1.1 什么是 Docker

Docker 是一种成熟高效的软件部署技术,利用容器化技术为应用程序封装独立的运行环境。

  • 核心思想:Build, Ship, and Run Any App, Anywhere(一次构建,到处运行)。
  • 本质 :Docker 容器本质上是宿主机上的一个特殊的进程,通过命名空间(Namespaces)和控制组(Cgroups)实现隔离和资源限制。

1.2 容器 vs 虚拟机 (VM)

核心区别

  • Docker (容器):共享宿主机的操作系统内核,属于进程级隔离。启动快(毫秒级),占用资源少。
  • 虚拟机 (VM):通过 Hypervisor 模拟完整的硬件环境,每个 VM 都有独立的操作系统内核。启动慢,资源占用重。
特性 Docker 容器 虚拟机 (Virtual Machine)
架构 共享宿主机 OS 内核,轻量级 包含完整的 Guest OS,重量级
隔离性 进程级隔离 硬件/系统级隔离
启动速度 秒级/毫秒级 分钟级
磁盘占用 MB 级别 GB 级别

容器架构
硬件 Infrastructure
宿主操作系统 Host OS
Docker Engine
Container A
Container B
Libs/App A
Libs/App B
虚拟机架构
硬件 Infrastructure
宿主操作系统 Host OS
Hypervisor
客户机 OS
客户机 OS
Libs/Bins
App A
Libs/Bins
App B


2. Docker 基础

2.1 架构模式 (Client-Server)

Docker 采用标准的 C/S 架构:

  • Client (客户端) : 用户使用的命令行工具 (docker CLI),负责发送指令。
  • Host (宿主机/服务端) : 运行 dockerd 守护进程,负责处理指令、管理容器生命周期。
  • Registry (仓库): 存储镜像的地方。

2.2 核心组件 (三大支柱)

  1. 镜像 (Image) :
    • 定义: 只读的模板,类似于代码中的"类" (Class) 或软件安装包。
    • 特性: 分层存储,复用性强。
  2. 容器 (Container) :
    • 定义: 镜像运行时的实例,类似于"对象" (Object)。
    • 特性: 可读写,包含应用运行所需的一切。
  3. 仓库 (Registry) :
    • 定义: 集中存放镜像的场所。
    • 示例: Docker Hub (官方)、阿里云镜像仓库、Harbor (私有)。

2.3 基本工作流程

镜像仓库 Docker Daemon 用户 (CLI) 镜像仓库 Docker Daemon 用户 (CLI) docker pull nginx 请求下载 nginx 镜像 返回镜像数据 下载完成 docker run -d nginx 基于镜像创建容器进程 返回 Container ID


3. Docker 安装与配置

Docker安装官方文档: Ubuntu | Docker Docs

docker仅兼容部分操作系统版本的安装,以ubuntu为例,仅支持以下版本的docker适配

  • Ubuntu Questing 25.10
  • Ubuntu Plucky 25.04
  • Ubuntu Noble 24.04 (LTS)
  • Ubuntu Jammy 22.04 (LTS)

3.1 Linux Docker安装步骤

  • 首先清理环境上残留的docker

    shell 复制代码
    for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
  • 更新最新的安装包

    shell 复制代码
    sudo apt-get update
  • 安装Docker官方GPG key

    shell 复制代码
    sudo apt-get install ca-certificates curl
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
  • 添加docker官方仓库

    shell 复制代码
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update
  • 下载最新版本docker

    shell 复制代码
    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  • 查看Docker服务是否启动

    shell 复制代码
    sudo systemctl status docker  # 查看docker状态
    sudo systemctl start docker # 手动启动Docker
  • 配置docker的镜像站

    shell 复制代码
    vim /etc/docker/daemon.json # 编辑docker镜像站配置文件,添加以下内容
    json 复制代码
    {
    	"registry-mirrors":[
    		"https://docker.m.daocloud.io",
    		"https://docker.1panel.live",
    		"https://hub.rat.dev"
    	]
    }
  • 重启docker服务应用镜像站

    shell 复制代码
    sudo service docker restart
  • 运行Docker测试

    shell 复制代码
    sudo docker run hello-world

    docker会首先查找本地镜像仓库是否存在hello-world镜像,当不存在会去远端拉取最新的hello-world并运行,当输出Hello from Docker!就表示Docker可以正常使用了。

3.2 windows安装Docker

  • 打开windows功能,勾选这两个选项

  • 重启电脑

  • 打开windows的cmd控制台,安装wsl

    shell 复制代码
    wsl --update --web-download
  • 安装docker desktop

    下载地址:Docker: Accelerated Container Application Development

    下载完后双击exe文件默认安装在C盘,也可以使用目录安装到指定文件夹

    shell 复制代码
    start /w "" "Docker Desktop Install.exe" install --installation-dir={指定windows目录}
  • windows系统配置镜像站

    打开Docker Desktop->settings->Docker Engine,把镜像站配置信息粘贴进去。

    这样我们就可以在windows上拉取docker镜像了

3.Docker官方镜像站

下载官方镜像网址:https://hub.docker.com/

3.3 验证安装

bash 复制代码
docker --version       # 查看版本
docker run hello-world # 运行测试镜像

4. Docker 镜像管理

Docker 镜像(Image)是容器的只读模板,包含了应用程序运行所需的所有依赖(代码、运行时、库、环境变量和配置文件)。镜像是容器生命周期的基石,理解镜像管理是掌握 Docker 的第一步。

4.1 镜像结构与命名规范

一个完整的 Docker 镜像名称由四个部分组成,遵循以下格式:

[Registry/注册表地址]/[Namespace/命名空间]/[Repository/镜像名]:[Tag/版本标签]

组成部分 说明 默认值 示例
Registry 存放镜像的仓库地址 docker.io (Docker Hub) docker.ioregistry.cn-hangzhou.aliyuncs.com
Namespace 用户或组织的命名空间 library (官方镜像) library (官方 nginx) 或 mysql (mysql 官方)
Repository 镜像的具体名称 无 (必填) nginx, redis, my-app
Tag 镜像的版本标签 latest 1.23, alpine, v1.0

示例解析

  1. 官方镜像简写

    • 命令:docker pull nginx
    • 完整解析:docker pull docker.io/library/nginx:latest
    • 说明:省略了默认注册表、默认命名空间和默认标签。
  2. 第三方私有镜像

    • 命令:docker pull docker.n8n.io/n8nio/n8n:0.12.1
    • 解析:
      • Registry: docker.n8n.io
      • Namespace: n8nio
      • Repository: n8n
      • Tag: 0.12.1

4.2 获取与查看镜像

1. 拉取镜像 (docker pull)

从远程仓库下载镜像到本地。

  • 基础用法

    bash 复制代码
    docker pull nginx:1.23
  • 指定架构拉取 (--platform)

    默认情况下 Docker 会自动拉取匹配当前主机架构的镜像。在跨平台开发(如在 Apple Silicon M1/M2 上开发 x86 应用)时,需显式指定架构。

    bash 复制代码
    # 拉取 Linux AMD64 架构的 Nginx 镜像
    docker pull --platform=linux/amd64 nginx:alpine
2. 查看本地镜像 (docker images)

列出本地主机上已下载的镜像。

  • 基础查看

    bash 复制代码
    docker images
  • 查看所有镜像 (-a)

    显示所有镜像,包括中间层镜像(Intermediate Layers)。

    bash 复制代码
    docker images -a
  • 按条件筛选 (--filter)

    常用于查找悬空镜像 (Dangling Images,即 Repository 和 Tag 均为 <none> 的镜像,通常是构建过程中的残留或旧版本覆盖产生)。

    bash 复制代码
    docker images --filter "dangling=true"
  • 自定义输出格式 (--format)

    仅显示需要的字段,方便脚本处理。

    bash 复制代码
    docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}"

4.3 镜像操作:标记与构建

1. 镜像打标签 (docker tag)

docker tag 本质上是给同一个镜像 ID 创建一个别名(引用),不占用额外的磁盘空间。

  • 场景一:版本管理

    bash 复制代码
    # 将 ID 为 a1b2c3d4 的镜像标记为 myapp:v1.0
    docker tag a1b2c3d4 myapp:v1.0
  • 场景二:推送前准备

    要将镜像推送到远程仓库,必须将镜像标记为 仓库地址/用户名/镜像名:标签 的格式。

    bash 复制代码
    # 为本地镜像添加符合 Docker Hub 规范的标签
    docker tag myapp:v1.0 xuanchen46789/myapp:v1.0
2. 构建镜像 (docker build)

基于 Dockerfile 构建自定义镜像。

  • 命令格式

    bash 复制代码
    docker build -t <镜像名>:<标签> <上下文路径>
  • 示例

    bash 复制代码
    # 在当前目录(.)寻找 Dockerfile 构建镜像,并命名为 my-python-app:v1
    docker build -t my-python-app:v1 .
    • --no-cache:构建时不使用缓存,强制重新执行每一层指令(用于解决依赖更新未生效的问题)。
3. 推送镜像 (docker push)

将本地镜像上传至远程仓库。

  • 步骤

    1. 登录:docker login
    2. 打标签:docker tag ...
    3. 推送:
    bash 复制代码
    docker push xuanchen46789/myapp:v1.0

4.4 清理与删除 (docker rmi)

管理本地磁盘空间,移除不再使用的镜像。

  • 删除指定镜像

    可以通过镜像 ID 或 镜像名称:标签 进行删除。

    bash 复制代码
    docker rmi nginx:latest
    # 或者使用短 ID
    docker rmi 605c77
  • 强制删除 (-f)

    如果镜像正在被某个停止的容器引用,默认无法删除。使用 -f 强制移除。

    bash 复制代码
    docker rmi -f nginx:latest
  • 批量清理悬空镜像

    结合 shell 命令批量删除所有无用的悬空镜像。

    bash 复制代码
    docker rmi $(docker images -q --filter "dangling=true")

4.5 进阶:镜像的导入导出 (离线环境)

在没有外网的服务器环境(如内网部署),无法使用 docker pull,此时需要使用导入导出命令。

1. 导出镜像 (docker save)

将本地的一个或多个镜像打包成 tar 归档文件。

  • 命令

    bash 复制代码
    # 将 nginx:alpine 镜像保存为 nginx-alpine.tar 文件
    docker save -o nginx-alpine.tar nginx:alpine
2. 导入镜像 (docker load)

从 tar 归档文件中加载镜像到本地 Docker 环境。

  • 命令

    bash 复制代码
    # 从 tar 包加载镜像
    docker load -i nginx-alpine.tar

4.6 镜像元数据查看 (docker inspect)

查看镜像的详细配置信息,如 CMD 命令、环境变量、暴露端口、架构等。

  • 命令

    bash 复制代码
    docker inspect nginx:latest
  • 实战用途

    当不知道某个镜像默认启动命令是什么,或者不知道它默认的数据卷挂载路径时,通过 inspect 查看 ConfigMounts 字段。


5. Docker 容器管理

5.1 启动容器 (docker run)

docker run 是 Docker 中最基础也是最重要的命令。
运行机制:当你执行这个命令时,Docker 会首先在本地寻找同名的镜像。如果本地没有找到,它会自动去远程仓库(Registry)拉取最新的镜像,然后启动容器。

关键参数详解:

  1. -d:后台分离模式 (Detached Mode)
  • 作用:让容器在后台运行,而不是直接占用控制台窗口。

  • 原理 :使用 -d 的本质是将容器进程交给 Docker 守护进程(dockerd)托管,使其作为子进程在后台运行。这符合操作系统对守护进程(Daemon)的管理规范。

  • 反馈:执行后会打印出完整的容器 ID。

  • 示例

    bash 复制代码
    docker run -d nginx
  1. -p:端口映射 (Port Mapping)
  • 背景:Docker 容器运行在独立的虚拟网络环境中,默认情况下,外部无法直接访问容器内的服务。

  • 作用:建立宿主机端口与容器端口的映射关系。

  • 语法-p 宿主机端口:容器端口

  • 效果:访问宿主机的 80 端口,流量会被转发到容器内的 80 端口。

  • 示例

    bash 复制代码
    docker run -p 80:80 nginx
  1. -v:数据卷挂载 (Volume Mounting)
  • 核心目的 :实现数据的持久化。如果不挂载,容器一旦被删除,里面的数据也会随之消失。

  • 两种模式对比

    • 绑定挂载 (Bind Mount)

      • 描述:直接把宿主机的具体路径映射到容器内。

      • 注意:如果宿主机路径为空,容器内对应目录的内容会被覆盖(清空),使用时需谨慎。

      • 示例

        bash 复制代码
        docker run -d \
          --name volume-demo \
          -v /usr/share/nginx/html:/usr/share/nginx/html \
          nginx
    • 命名卷 (Named Volume)

      • 描述:由 Docker 管理的存储空间。

      • 优势:首次挂载时,会将容器内的原有文件复制到卷中,不会像绑定挂载那样导致文件丢失。适合在多个容器间共享数据。

      • 示例

        bash 复制代码
        docker run -d \
          --name volume-demo \
          -v my-volume:/usr/share/nginx/html \
          nginx
  1. --name:指定容器名称
  • 作用:给容器起一个易于记忆的名字,方便后续管理。

  • 注意 :如果不指定,Docker 会随机生成一个名字。容器名称和容器 ID 在管理命令(如 docker rm)中是等价的。

  • 示例

    bash 复制代码
    docker run -d --name nginx-demo nginx
  1. -e:设置环境变量 (Environment Variables)
  • 作用:在不修改镜像的情况下,动态调整应用的配置。

  • 场景

    • 动态配置:传入数据库连接地址、日志级别等。
    • 安全隔离:避免将密码等敏感信息硬编码在镜像里。
    • 跨环境适配:不同环境(开发、测试、生产)使用同一镜像,仅通过环境变量区分配置。
  • 示例(启动 MongoDB):

    bash 复制代码
    docker run -d --network some-network --name some-mongo \
      -p 27017:27017 \
      -e MONGO_INITDB_ROOT_USERNAME=mongoadmin \
      -e MONGO_INITDB_ROOT_PASSWORD=secret \
      mongo
  1. -it:交互式终端
  • 作用 :开启一个连接容器内部的通道,允许进入容器执行 Shell 命令。通常与 /bin/bash/bin/sh 配合使用。

  • 示例

    bash 复制代码
    docker run -it --rm alpine
  1. --rm:自动清理
  • 作用:当容器停止运行时,自动删除该容器。
  • 场景 :非常适合用于临时的调试或一次性任务,避免残留大量无用的停止容器。通常与 -it 一起使用。
  1. --restart:重启策略
  • 作用:定义容器退出后的行为,保证服务的高可用性。

  • 选项

    • always:无论什么原因停止,总是尝试重启。
    • unless-stopped:除非是人工手动停止的,否则都会尝试重启(例如服务器重启后,容器会自动启动)。
  • 示例

    bash 复制代码
    docker run -d --restart always nginx

5.2 常用管理命令

除了启动容器,日常运维中还需要掌握以下命令来管理容器的状态:

  • 查看容器
    • docker ps:查看当前正在运行的容器。
    • docker ps -a:查看所有容器(包括已停止的)。
  • 进入容器
    • docker exec -it <容器名> /bin/bash:在运行中的容器内开启一个新的终端,是调试问题的神器。
  • 查看日志
    • docker logs -f <容器名>:实时跟踪容器的标准输出日志,用于排查启动报错或运行异常。
  • 停止与删除
    • docker stop <容器名>:优雅地停止容器。
    • docker rm <容器名>:删除已停止的容器。如果要强制删除正在运行的容器,需添加 -f 参数。

6. Docker 生命周期

容器的生命周期是指从容器被创建开始,到最终被删除的整个过程。Docker 守护进程(Daemon)负责管理和监控这些状态的变化。理解生命周期对于排查容器故障(如容器无法启动、无法停止)至关重要。

6.1 五大核心状态详解

Docker 容器在运行过程中主要会在以下五种状态之间流转:

  1. Created (已创建)

    • 描述:容器实例已经由镜像创建,文件系统层(可读写层)已经分配,但容器内的核心进程尚未启动。
    • 触发 :通常通过 docker create 命令触发。
  2. Running (运行中)

    • 描述:容器内的 PID 1 进程正在处于活跃状态。这是容器提供服务的正常状态。
    • 触发 :通过 docker startdocker run 触发。
  3. Paused (暂停)

    • 描述:容器内的所有进程都被挂起(Frozen)。容器的内存状态被保留,但不再消耗 CPU 资源。这类似于虚拟机的挂起操作。
    • 触发 :通过 docker pause 触发。
  4. Exited (停止/退出)

    • 描述:容器内的主要进程已经结束。这可能是任务正常完成(退出码 0),也可能是因为错误崩溃(非 0 退出码),或者是被用户手动停止。此时容器的文件系统依然保留,可以查看到日志。
    • 触发 :进程自动结束、docker stopdocker kill
  5. Dead (死亡)

    • 描述:这是一个异常状态。通常表示 Docker 试图删除容器,但由于某些原因(如文件系统忙、资源未释放)导致删除失败。处于 Dead 状态的容器通常无法启动,需要手动强制清理。
    • 触发:系统错误或移除操作失败。

6.2 容器状态流转图

下图展示了容器在不同命令作用下的状态变迁逻辑,并补充了 Dead 状态:
docker create
docker start
docker run
docker pause
docker unpause
docker stop / 进程自然结束
docker kill (强制停止)
docker start / docker restart
docker rm (操作失败/系统异常)
系统严重错误
docker rm -f (强制删除)
docker rm
docker rm -f (手动清理)
docker rm
Created
Running
Paused
Exited
Dead

6.3 改变生命周期的命令示例

以下是这些命令在实际操作中的具体用法:

1. 创建与启动 (Create / Start / Run)
  • 仅创建容器 (Created)

    如果你想先配置好容器但不立即运行(例如为了后续批量启动),可以使用 create

    bash 复制代码
    # 从 nginx 镜像创建一个名为 my_web 的容器
    docker create --name my_web nginx
  • 启动已存在的容器 (Running)

    用于启动处于 CreatedExited 状态的容器。

    bash 复制代码
    docker start my_web
  • 一键创建并运行 (Running)

    这是开发中最常用的命令,通常配合 -d 参数让容器在后台运行。

    bash 复制代码
    # 创建并启动一个名为 my_redis 的容器,并在后台运行
    docker run -d --name my_redis redis
2. 停止与恢复 (Stop / Restart / Kill)
  • 优雅地停止 (Exited)

    给容器内的进程发送信号,让其有时间保存数据。

    bash 复制代码
    docker stop my_redis
  • 强制杀死进程 (Exited)

    如果容器无响应,强制立即停止。

    bash 复制代码
    docker kill my_redis
  • 重启容器

    常用于配置文件修改后的生效。

    bash 复制代码
    docker restart my_redis
3. 暂停与取消暂停 (Paused)
  • 挂起容器进程

    当你需要临时释放 CPU 资源,但不想完全停止容器时使用。

    bash 复制代码
    docker pause my_redis
  • 恢复运行

    bash 复制代码
    docker unpause my_redis
4. 移除容器 (Deleted)
  • 删除已停止的容器

    bash 复制代码
    docker rm my_web
  • 强制删除运行中的容器

    如果容器正在运行,必须使用 -f (force) 参数。

    bash 复制代码
    docker rm -f my_redis

命令表格如下:

命令 作用 状态变迁方向 说明
docker create 创建新容器 None -> Created 仅加载镜像并配置层,不启动进程。
docker start 启动容器 Created/Exited -> Running 启动容器的主进程。
docker run 创建并启动 None -> Running 相当于 docker create + docker start 的组合原子操作。
docker stop 优雅停止 Running -> Exited 先发送 SIGTERM 信号给容器,等待一段时间(默认10秒)后若未停止则发送 SIGKILL
docker kill 强制停止 Running -> Exited 直接发送 SIGKILL 信号,立即终止进程,可能导致数据丢失。
docker restart 重启容器 Running -> Running 先执行 stop,再执行 start
docker pause 暂停容器 Running -> Paused 利用 cgroups 的 freezer 特性挂起进程。
docker unpause 恢复容器 Paused -> Running 解除进程挂起状态。
docker rm 删除容器 Exited/Created -> Deleted 移除容器的文件层和元数据。只能删除非运行状态的容器(除非加 -f)。

7. Docker 网络管理

Docker 网络子系统允许容器之间以及容器与宿主机之间进行通信。Docker 的网络架构是可插拔的,默认提供了多种驱动程序来适应不同的用例。

7.1 核心网络模式详解

通过 docker network ls 可以查看当前 Docker 环境中的网络列表。Docker 默认包含以下三种核心模式:

网络模式 驱动名称 特点与适用场景
Bridge (桥接模式) bridge 默认模式。容器通过虚拟网桥(docker0)连接,通过 NAT(网络地址转换)访问外部网络。容器间网络隔离,需通过端口映射暴露服务。
Host (主机模式) host 无隔离。容器直接共享宿主机的网络栈(IP 和端口)。性能最高,但容易导致端口冲突。
None (无网络模式) none 完全隔离。容器没有外部网络接口,仅保留回环接口(lo, 127.0.0.1)。适用于安全性要求极高或不需要网络的离线任务。

宿主机
Bridge 模式
Host 模式容器
虚拟网桥 docker0
应用
物理网卡 Eth0
NAT 转换
veth pair
容器1
veth pair
容器2

7.2 常用网络管理命令

命令 说明 示例
docker network ls 列出所有网络 docker network list
docker network create 创建自定义网络 docker network create my-net
docker network rm 删除网络 docker network rm my-net (需确保网络中无运行容器)
docker network connect 将容器加入网络 docker network connect my-net my-container
docker network disconnect 将容器移出网络 docker network disconnect my-net my-container
docker network inspect 查看网络详情 docker network inspect my-net (查看子网段、网关、连接的容器)

7.3 深入 Bridge 模式 (桥接)

这是 Docker 的默认网络驱动。

1. 默认桥接 vs 自定义桥接
  • 默认桥接 (bridge)
    • 容器安装后默认加入此网络。
    • 缺点:不支持通过容器名称(Container Name)进行 DNS 解析,容器间通信必须使用 IP 地址(而 IP 可能会变)。
  • 自定义桥接 (User-defined bridge)
    • 优点 :支持 自动 DNS 解析 。同一自定义网络下的容器,可以通过容器名称直接互相 ping 通或访问,无需关心 IP 变化。
2. 实战:创建自定义子网与 DNS 解析

场景 :创建两个容器 app1app2,让它们通过名字互相访问。

  1. 创建自定义网络

    bash 复制代码
    docker network create my-network
  2. 启动容器并加入网络

    bash 复制代码
    # 启动 app1
    docker run -d --name app1 --network my-network nginx
    
    # 启动 app2
    docker run -d --name app2 --network my-network nginx
  3. 验证通信

    进入 app1 容器,尝试 ping app2

    bash 复制代码
    docker exec -it app1 ping app2

    结果:可以 ping 通,说明 Docker 内部 DNS 成功将 app2 解析为了对应的 IP 地址。

3. 实战案例:MongoDB 与 Mongo Express 互联

这是您笔记中的一个典型微服务连接案例。如果不使用 Docker Compose,我们需要手动配置网络来实现服务发现。

  1. 创建网络

    bash 复制代码
    docker network create network1
  2. 启动数据库 (MongoDB)

    注意:这里不需要 -p 映射 27017 端口,因为我们希望数据库只在 Docker 网络内部被访问,不对外暴露,增加安全性。

    bash 复制代码
    docker run -d \
        --name my_mongodb \
        -e MONGO_INITDB_ROOT_USERNAME=admin \
        -e MONGO_INITDB_ROOT_PASSWORD=secret \
        --network network1 \
        mongo
  3. 启动管理界面 (Mongo Express)

    这里通过环境变量 ME_CONFIG_MONGODB_SERVER 指定数据库地址为容器名 my_mongodb

    bash 复制代码
    docker run -d \
        --name mongo-express \
        -p 8081:8081 \
        -e ME_CONFIG_MONGODB_SERVER=my_mongodb \
        -e ME_CONFIG_BASICAUTH_USERNAME="admin" \
        -e ME_CONFIG_BASICAUTH_PASSWORD="secret" \
        --network network1 \
        mongo-express

效果:访问宿主机 http://localhost:8081 即可管理数据库。虽然 DB 端口未对外开放,但 Web UI 容器可以通过 network1 访问到它。

7.4 Host 模式 (主机)

特点:容器直接共享宿主机的网络命名空间。容器不会拥有自己的 IP 地址,而是直接绑定到宿主机的 IP。

  • 适用场景:对网络性能要求极高,或者需要处理大量端口范围的场景。

  • 命令

    bash 复制代码
    docker run -d --network host --name my-nginx nginx
  • 验证

    进入容器查看 IP,会发现它显示的是宿主机的网络配置,而不是 Docker 的虚拟网段。

    bash 复制代码
    docker exec -it my-nginx ip addr show

7.5 None 模式 (无网络)

特点:容器只有本地回环地址(127.0.0.1),无法连接互联网。

  • 命令

    bash 复制代码
    docker run -d --network none busybox

7.6 网络清理

当不再需要某个自定义网络时,应当删除以释放资源。

  • 删除单个网络

    bash 复制代码
    docker network rm my-network

    注意:删除前必须断开或停止所有连接到该网络的容器。

  • 清理所有未使用网络

    bash 复制代码
    docker network prune

8. Docker 数据卷管理

容器的文件系统是临时的,当容器被删除时,容器内的所有数据都会丢失。为了实现数据的持久化保存 以及在宿主机和容器之间共享数据,Docker 提供了数据卷(Volume)机制。

8.1 核心概念

  • 数据持久化:将容器内的数据保存在宿主机上,即使容器被删除,数据依然存在。
  • 解耦:数据卷独立于容器的生命周期,可以被多个容器同时挂载和共享。

8.2 挂载方式对比

Docker 提供了两种主要的挂载方式,分别适用于不同的场景:

特性 绑定挂载 (Bind Mount) 命名卷 (Named Volume)
语法 -v <宿主机绝对路径>:<容器路径> -v <卷名>:<容器路径>
存储位置 用户指定的宿主机任意路径 Docker 管理的特定路径 (/var/lib/docker/volumes/)
初始化行为 覆盖:宿主机目录内容会覆盖容器目录(若宿主机为空,容器目录也被清空) 复制:首次挂载时,会将容器内目标目录的原有文件复制到卷中
移植性 差(依赖宿主机特定路径) 好(仅依赖 Docker 环境)
适用场景 开发环境:代码热更新(本地修改代码,容器内即时生效) 生产环境:数据库存储、日志持久化、多容器数据共享
1. 绑定挂载 (Bind Mount) 实战

直接将宿主机的目录映射到容器内。

bash 复制代码
# 将宿主机当前目录下的 html 文件夹挂载到 Nginx 容器的网页目录
docker run -d -p 80:80 -v /website/html:/usr/share/nginx/html nginx
  • 注意 :如果宿主机的 /website/html 是空的,启动后容器内的 /usr/share/nginx/html 也会变成空的(原有的 index.html 被隐藏/覆盖)。
2. 命名卷 (Named Volume) 实战

使用 Docker 管理的卷。

bash 复制代码
# 将名为 my-nginx-volume 的卷挂载到 Nginx 容器
docker run -d -v my-nginx-volume:/usr/share/nginx/html nginx
  • 机制 :如果 my-nginx-volume 不存在,Docker 会自动创建。容器启动时,Docker 会把 Nginx 容器内 /usr/share/nginx/html 下的默认文件自动复制到这个卷中,不会导致数据丢失。

8.3 数据卷管理命令

Docker 提供了 docker volume 子命令来专门管理数据卷。

1. 创建数据卷
bash 复制代码
docker volume create <卷名>
# 示例
docker volume create nginx_html
2. 查看所有数据卷
bash 复制代码
docker volume ls
3. 查看数据卷详情

查看卷在宿主机上的真实存储路径(Mountpoint)。

bash 复制代码
docker volume inspect <卷名>
# 示例
docker volume inspect nginx_html
  • 输出示例 :通常位于 /var/lib/docker/volumes/nginx_html/_data
4. 删除数据卷
bash 复制代码
docker volume rm <卷名>
# 示例
docker volume rm nginx_html
  • 注意 :只能删除未被任何容器使用的卷。如果卷正在被挂载(即使容器已停止),删除会失败,需先删除相关容器。
5. 清理未使用的卷

一键清理所有未被引用的卷,释放磁盘空间。

bash 复制代码
# 清理所有未被容器引用的卷
docker volume prune

# 清理所有卷(包括未被运行中容器引用的,慎用!)
docker volume prune -a

9. Docker 系统维护

随着 Docker 的长期使用,系统中会积累大量的临时容器、未使用的镜像、废弃的网络和构建缓存,这些资源会占用大量磁盘空间并可能影响性能。掌握系统维护命令对于保持 Docker 环境的健康至关重要。

9.1 查看系统版本与信息

  • 查看版本信息 (docker version)

    显示 Docker 客户端(Client)和服务器端(Server/Daemon)的版本详细信息,包括 Go 语言版本、Git commit ID、操作系统架构等。用于确认环境一致性。

    bash 复制代码
    docker version
  • 查看系统全局信息 (docker info)

    显示 Docker 系统的汇总报告,常用于排查环境问题。包含信息如下:

    • 容器统计:总数、运行中、停止、暂停的数量。
    • 镜像统计:本地镜像总数。
    • 基础设施:存储驱动(Overlay2 等)、内核版本、操作系统类型、CPU 架构、内存总量等。
    bash 复制代码
    docker info

9.2 资源监控 (docker stats)

作用 :提供一个实时的流式数据界面,监控所有运行中容器的资源占用情况,功能类似于 Linux 的 top 命令。

  • 基础命令

    bash 复制代码
    docker stats
  • 输出关键指标解析

    • CPU %:CPU 使用率。
    • MEM USAGE / LIMIT:当前内存使用量 / 容器内存限制。
    • MEM %:内存使用百分比。
    • NET I/O:网络输入/输出流量。
    • BLOCK I/O:磁盘读写数据量。

9.3 系统大扫除 (docker system prune)

作用 :一键清理 Docker 系统中所有未使用的资源。这是释放磁盘空间最有效的命令,但具有破坏性,需谨慎使用

1. 安全清理 (日常维护)

默认情况下,docker system prune 仅删除"悬空"和"无用"的临时资源。

bash 复制代码
docker system prune

清理范围

  • 所有已停止的容器 (Stopped containers)。
  • 所有未被任何容器使用的网络 (Unused networks)。
  • 所有悬空镜像 (Dangling images,即标签为 <none> 的镜像)。
  • 构建缓存 (Build cache)。
2. 彻底清理 (深度释放)

如果磁盘空间严重不足,可以添加参数进行深度清理。

bash 复制代码
docker system prune -a --volumes

新增清理范围

  • -a :删除所有未被运行中容器使用的镜像(即使它有正常的标签,只要没在跑,就会被删掉)。
  • --volumes :删除所有未被任何容器使用 的数据卷(警告:这可能导致持久化数据丢失!)。

清理建议

  • 日常维护仅使用 docker system prune
  • 仅在确认数据已备份且环境需要重置时,才使用 docker system prune -a --volumes

10. Dockerfile (构建自定义镜像)

Dockerfile 是一个没有后缀名的文本文件,它包含了一系列指令,用于自动化构建 Docker 镜像。

10.1 核心指令详解

指令 说明 关键细节
FROM 指定基础镜像 必须是 Dockerfile 的第一行指令 。例如 FROM python:3.13-slim
WORKDIR 设置工作目录 相当于 Linux 的 cd。如果目录不存在会自动创建。后续的 RUN, CMD, COPY 等指令都会基于此目录执行。
COPY 复制文件 格式:COPY <本地路径> <镜像路径>。将宿主机当前上下文目录的文件复制到镜像内。
RUN 构建时执行命令 镜像构建阶段执行(Build time)。常用于安装依赖、创建目录等。可以写多条 RUN 指令。
EXPOSE 声明端口 仅作为文档声明,告知使用者容器打算监听的端口(如 EXPOSE 8000)。注意 :实际端口映射仍需在 docker run 时通过 -p 参数指定。
CMD 容器启动默认命令 容器启动时执行的命令。推荐使用数组格式 ["exe", "param"]一个 Dockerfile 只能有一个 CMD,如果有多个,只有最后一个生效。
ENTRYPOINT 容器固定入口 设置容器启动时的固定程序。与 CMD 不同,ENTRYPOINT 指定的命令不易被 docker run 后的参数覆盖。

10.2 RUN vs CMD vs ENTRYPOINT

这是面试和实战中的高频考点,三者区别如下:

  1. RUN (构建时)
    • 触发时机docker build 构建镜像时。
    • 作用:安装软件、配置环境。
  2. CMD (启动默认值)
    • 触发时机docker run 容器启动时。
    • 可覆盖性 :如果在 docker run 后面指定了命令,CMD 会被覆盖。
      • CMD ["python", "app.py"]。若运行 docker run ... python test.py,则原 CMD 不执行,改执行 python test.py
    • 配合 ENTRYPOINT :如果有 ENTRYPOINT,CMD 会变成 ENTRYPOINT 的默认参数
  3. ENTRYPOINT (固定入口)
    • 触发时机docker run 容器启动时。
    • 不可覆盖性 :默认不会被 docker run 后的命令覆盖(除非使用 --entrypoint 强制替换)。
    • 场景:将容器当作一个可执行程序使用。

组合示例

dockerfile 复制代码
ENTRYPOINT ["nginx"]       # 固定程序:nginx
CMD ["-g", "daemon off;"]  # 默认参数:前台运行
  • 如果不传参:执行 nginx -g "daemon off;"
  • 如果传参(docker run ... -v):执行 nginx -v

10.3 示例 (Python FastAPI 应用)

以下是一个完整的 Dockerfile 编写示例:

dockerfile 复制代码
# 1. 基础镜像
FROM python:3.13-slim

# 2. 设置工作目录 (后续操作都在 /app 下)
WORKDIR /app

# 3. 复制项目文件 (将当前目录所有文件复制到镜像的 /app)
COPY . .

# 4. 安装依赖 (构建阶段执行)
RUN pip install -r requirements.txt

# 5. 声明端口 (仅做声明)
EXPOSE 8000

# 6. 启动命令 (容器启动时执行)
CMD ["python", "main.py"]

10.4 镜像构建与发布流程

1. 构建镜像 (Build)

使用 docker build 命令将 Dockerfile 打包为镜像。

bash 复制代码
# 格式:docker build -t <镜像名:标签> <上下文路径>
# 注意:最后的 . 表示当前目录为构建上下文
docker build -t xuanchen46789/docker-test .

注意 :命令最后的 . 表示将当前目录作为构建上下文(Context),必须确保该目录下存在 Dockerfile。

2. 镜像打标签 (Tag)

给镜像起别名,通常用于推送到远程仓库前的规范命名。

bash 复制代码
# 格式:docker tag <源镜像ID/名> <新镜像名:版本>
docker tag a1b2c3d4 xuanchen46789/myapp:v1.0
3. 推送镜像 (Push)

将镜像上传至 Docker Hub 或私有仓库。

bash 复制代码
# 1. 登录 (首次需要)
docker login

# 2. 推送
docker push xuanchen46789/docker-test

11. Docker Compose 与多容器管理

Docker Compose 是 Docker 官方推出的轻量级容器编排工具。它允许用户通过一个 YAML 文件定义多个关联容器(如 Web 应用 + 数据库),实现"一键启动/停止"整个应用栈。

11.1 核心概念

  • 服务 (Services) :应用的一个组成部分(如 webdb),对应一个容器。
  • 项目 (Project):由一组关联的应用容器组成的一个完整业务单元,默认以目录名作为项目名。
  • 自动化网络 :Compose 会自动为该项目创建一个默认网络,服务之间可以通过服务名(Hostname)直接通信,无需知道具体 IP。

11.2 docker-compose.yml 结构解析

以下是一个典型的 Web + Database 架构配置示例:

yaml 复制代码
version: '3.8'  # Compose 文件版本

services:       # 定义服务列表
  web:          # 服务名称:web
    build: .    # 从当前目录 (.) 的 Dockerfile 构建镜像
    ports:
      - "8000:8000" # 端口映射:宿主机:容器
    depends_on:
      - db      # 依赖声明:确保 db 服务先启动
    networks:
      - my-net  # 加入自定义网络

  db:           # 服务名称:db
    image: postgres:13 # 直接使用官方镜像,不需构建
    volumes:
      - db-data:/var/lib/postgresql/data # 挂载数据卷实现持久化
    environment:
      - POSTGRES_PASSWORD=secret # 设置环境变量
    networks:
      - my-net

volumes:        # 定义数据卷
  db-data:      # 自动管理的命名卷

networks:       # 定义网络
  my-net:       # 自定义桥接网络

关键配置说明:

  • build vs imagebuild 用于开发阶段构建本地代码;image 用于直接拉取现成镜像。
  • depends_on:控制启动顺序。注意:它只保证启动顺序,不保证被依赖的服务(如数据库)已经完全初始化完毕(Ready)。
  • environment:注入配置信息,避免硬编码敏感数据。

11.3 常用命令

Docker Compose 命令主要用于管理整个服务的生命周期。

命令 描述 关键参数与场景
docker compose up 创建并启动服务 -d: 后台运行 (Detached mode)。 --build: 启动前强制重新构建镜像(当代码更新时使用)。
docker compose down 停止并删除资源 默认删除容器和网络。 -v: 同时删除数据卷 (慎用!会导致数据库数据丢失)。 --rmi all: 删除相关镜像。
docker compose logs 查看服务日志 -f: 实时跟踪日志输出。 docker compose logs -f web: 仅查看 web 服务的日志。
docker compose ps 查看服务状态 列出当前项目下所有容器的运行状态。
docker compose stop/start 暂停/恢复服务 仅停止/启动容器,不删除容器和网络(不同于 down)。

11.4 最佳实践

  1. 数据持久化 :数据库服务一定要使用 volumes 挂载数据卷,否则 docker compose down 后数据会丢失。
  2. 环境隔离 :可以通过 -f 参数指定不同的配置文件(如 docker-compose.dev.yml vs docker-compose.prod.yml)来区分开发和生产环境。
  3. 服务通信 :在代码中连接数据库时,Host 地址直接填服务名(如 db),不要填 IP 地址。

12. Docker 技术原理 (进阶)

Docker 并非像虚拟机那样通过 Hypervisor 虚拟化硬件,而是利用 Linux 内核的特性实现操作系统层面的虚拟化。Docker 容器本质上是宿主机上的一个特殊的进程。

12.1 核心技术架构

Docker 的魔法主要由 Linux 内核的三大基石支撑:Namespaces (隔离)、Cgroups (限制)和 UnionFS(分层)。

1. Namespaces (命名空间) ------ 负责"隔离"
  • 作用:为容器提供独立的系统视图。让容器内的进程"以为"自己独占了整个操作系统。
  • 原理:Linux 内核通过 Namespaces 将全局系统资源包裹起来,使得处于不同 Namespace 的进程拥有独立的资源视图。
  • 常见的 Namespace
    • PID:进程隔离(容器内 PID 为 1 的进程,在宿主机上只是一个普通进程)。
    • NET:网络栈隔离(独立的 IP、端口、网卡)。
    • MNT:文件挂载点隔离(独立的文件系统)。
    • USER:用户和用户组隔离。
    • UTS:主机名和域名隔离。
    • IPC:进程间通信隔离。
2. Cgroups (Control Groups) ------ 负责"限制"
  • 作用:限制容器能使用的资源上限,防止单个容器耗尽宿主机资源(如 CPU、内存、磁盘 I/O)。
  • 原理:Cgroups 是 Linux 内核提供的一种机制,可以限制、记录和隔离进程组所使用的物理资源。
  • 场景:如果没有 Cgroups,一个死循环的容器可能会占满 100% 的 CPU,导致宿主机和其他容器崩溃。
3. UnionFS (联合文件系统) ------ 负责"分层"
  • 作用:支持镜像的分层存储和复用,实现极速的文件操作。
  • 原理:UnionFS 允许将多个不同位置的目录(分支)联合挂载到同一个目录下,表现为一个统一的文件系统。
  • 写时复制 (CoW - Copy on Write)
    • 镜像层 (Read-Only):底层的镜像层是只读的。
    • 容器层 (Read-Write):当容器启动时,Docker 会在镜像层之上挂载一个可写的"容器层"。
    • 修改机制 :当你尝试修改一个文件时,Docker 不会直接修改只读层,而是将文件复制到可写层进行修改。这使得镜像可以被多个容器安全共享。

12.2 架构原理图

以下图表展示了容器进程如何依赖 Linux 内核特性实现虚拟化:
Docker 容器
Linux 内核
宿主机硬件
看到的视图被隔离
使用的资源被限制
文件系统被分层
管控
管控
读取/写入
CPU
内存
磁盘
Namespaces

(视图隔离)
Cgroups

(资源限制)
UnionFS

(分层文件系统)
容器进程 (App)

12.3 总结:Docker vs 虚拟机

回顾核心区别,这有助于理解为什么 Docker 启动更快:

特性 Docker 容器 虚拟机 (VM)
核心原理 进程级隔离 (Namespaces + Cgroups) 硬件级虚拟化 (Hypervisor)
操作系统 共享宿主机内核 拥有独立的 Guest OS (重)
启动速度 毫秒/秒级 分钟级
磁盘占用 MB 级 (镜像分层复用) GB 级 (完整 OS)
相关推荐
小北方城市网1 分钟前
第 6 课:云原生架构终极落地|K8s 全栈编排与高可用架构设计实战
大数据·人工智能·python·云原生·架构·kubernetes·geo
❀͜͡傀儡师4 分钟前
Kubernetes 1.34.3部署PostgresSQL的v18.1
云原生·容器·kubernetes·postgressql
阿杰 AJie1 小时前
安装 docker.io(不走外网 Docker 域名)
docker·容器·eureka
m0_485614671 小时前
K8S项目生命周期管理
云原生·容器·kubernetes
忍冬行者1 小时前
k8s的etcd的一键备份和故障恢复
docker·云原生·容器·kubernetes·云计算
QWsin1 小时前
【k8s】为什么statefulSet初始化pod需要service name
云原生·容器·kubernetes
lin张1 小时前
k8s(三)pod详解(精简版)
云原生·容器·kubernetes
youxiao_902 小时前
kubernetes 插件、操作管理(二)
云原生·容器·kubernetes
NineData2 小时前
NineData云原生智能数据管理平台新功能发布|2025年12月版
数据库·云原生·数据库管理工具·ninedata·数据库迁移·数据库迁移工具·智能数据管理平台
Mr_sun.4 小时前
Day03——微服务网关与配置中心
微服务·云原生·架构