Docker: Docker是什么

Docker 让应用在任何环境里都能以完全相同的方式运行——它把"代码+dependency+config"打包成一个可移植的容器,告别"it works on my machine"的噩梦。

1. 你将学到


2. 一个后端开发者的真实故事

(1) 痛点:环境不一致的灾难

Alice 是一名后端开发者,她本地跑通了项目却频繁遇到"it works on my machine"问题:同事的 Ubuntu 环境缺依赖库、测试服务器的 CentOS 库版本不对、生产环境的 Red Hat 还要重新编译。每次部署都像赌博——3 个环境、5 次调试、2 天时间浪费在"环境配置"上,而不是写代码。

(2) Docker 的解法

Bob 推荐她用 Docker:"一行命令就能让应用在任何 Linux 上以完全相同的方式运行。"

BASH
# Build once, run anywhere
docker build -t myapp:1.0 .
docker run -d -p 8080:80 myapp:1.0

(3) 收益:环境一致性

Alice 把应用打包成 Docker 镜像后,开发、测试、生产三个环境用同一个镜像运行,部署时间从 2 天降到 10 分钟,环境问题归零。


3. 什么是容器化

容器化(Containerization)是一种轻量级虚拟化技术,将应用及其所有依赖打包到一个隔离的运行环境中,确保在任何基础设施上都能一致运行。

100%
graph TB
    A[传统部署<br/>App + OS + Hardware] --> B[虚拟化<br/>App + Guest OS + Hypervisor + Host OS]
    B --> C[容器化<br/>App + Container Engine + Host OS]
    C --> D["更轻 · 更快 · 更一致"]

(1) 容器化的核心思想

(2) 为什么叫"容器"

类比运输行业的集装箱(Container):无论里面装的是汽车、衣服还是食品,外面的轮船、火车、卡车都不需要关心——它们只管搬运标准尺寸的集装箱。Docker 容器就是软件世界的集装箱:

维度 运输集装箱 Docker 容器
标准化 统一尺寸(20/40 英尺) 统一镜像格式(OCI 标准)
隔离 货物之间互不干扰 进程/网络/文件系统隔离
可移植 船/火车/卡车都能运 开发/测试/生产都能跑
高效 不用拆箱换车 不用重装依赖

4. 容器 vs 虚拟机

容器和虚拟机都提供隔离环境,但实现方式截然不同。

100%
graph TB
    subgraph VM["虚拟机架构"]
        VM_APP1["App 1"] --> VM_OS1["Guest OS"]
        VM_APP2["App 2"] --> VM_OS2["Guest OS"]
        VM_OS1 --> VM_H["Hypervisor"]
        VM_OS2 --> VM_H
        VM_H --> VM_HOST["Host OS"]
        VM_HOST --> VM_HW["Hardware"]
    end
    subgraph CT["容器架构"]
        CT_APP1["App 1"] --> CT_APP2["App 2"]
        CT_APP2 --> CT_CE["Container Engine<br/>Docker"]
        CT_CE --> CT_KERNEL["Host OS Kernel"]
        CT_KERNEL --> CT_HW["Hardware"]
    end

(1) 核心区别对比

维度 虚拟机(VM) 容器(Container)
隔离级别 硬件级隔离(独立内核) 进程级隔离(共享内核)
启动速度 分钟级(启动完整 OS) 秒级(启动进程)
资源占用 GB 级(含 Guest OS) MB 级(仅应用依赖)
镜像大小 1-20 GB 5-500 MB
性能损耗 5-15%(虚拟化开销) ≈0%(接近原生)
密度 单机 5-10 个 VM 单机 100-1000 个容器

(2) 适用场景对比

场景 推荐虚拟机 推荐容器
需要不同操作系统内核 ✅(如 Windows + Linux 并行)
微服务/无状态应用 ✅(轻量、快速伸缩)
强隔离安全需求 ✅(内核级隔离) ⚠️(需额外加固)
CI/CD 构建环境 ✅(秒级启动/销毁)
开发环境一致性 ✅(镜像即环境)
运行传统 GUI 应用 ⚠️(需额外配置)
💡 提示: 容器不是虚拟机的替代品,而是互补技术。需要完全内核隔离的场景仍用虚拟机,应用级隔离用容器。


5. Docker 的架构

Docker 采用 Client-Server 架构,由三个核心组件构成。

100%
graph TB
    CLI["Docker Client<br/>docker build/run/pull"]
    CLI -->|REST API| D["Docker Daemon<br/>dockerd"]
    D -->|pull/push| R["Docker Registry<br/>Docker Hub / Private"]
    D -->|create/start| C["Containers<br/>Running instances"]
    D -->|build/cache| I["Images<br/>Read-only templates"]
    I -->|docker run| C
    R -->|docker pull| I

(1) 三层架构详解

组件 作用 常见命令
Docker Client 用户与 Docker 交互的命令行界面 docker run / docker build / docker pull
Docker Daemon 后台服务,管理镜像、容器、网络、卷 systemctl start docker / dockerd
Docker Registry 存储和分发镜像的仓库 docker pull / docker push

(2) 镜像与容器的关系

镜像是只读模板,容器是镜像的运行实例。类比面向对象编程:

概念 OOP 类比 说明
镜像(Image) 类(Class) 只读模板,定义了应用运行所需的一切
容器(Container) 实例(Instance) 镜像的运行态,可读写,有生命周期
Dockerfile 源代码(Source) 构建镜像的指令文件

(3) OCI 标准

Docker 遵循 OCI(Open Container Initiative)标准,确保容器可移植:

📌 重点: OCI 标准意味着用 Docker 构建的镜像,也能在 Podman、containerd 等其他容器运行时上运行。


6. Docker 的核心应用场景

(1) 场景概览

场景 说明 示例
开发环境标准化 团队统一开发环境 新成员 10 分钟搭建完整开发栈
微服务部署 每个服务独立容器 API + DB + Cache 各自容器化
CI/CD 流水线 构建环境一致可重复 GitHub Actions + Docker 自动部署
快速伸缩 秒级启动/销毁实例 流量高峰时 1→10 副本,低谷时 10→1
遗留应用容器化 旧应用无需改造即可迁移 把 2015 年的 PHP 5.4 项目打包成容器

(2) 容器的启动流程

当你执行 docker run hello-world 时,Docker 内部经历了以下步骤:

100%
graph LR
    A["docker run<br/>hello-world"] --> B{"本地有镜像?"}
    B -->|No| C["docker pull<br/>从 Registry 拉取"]
    B -->|Yes| D["创建容器<br/>可写层"]
    C --> D
    D --> E["启动容器<br/>执行 CMD"]
    E --> F["输出结果<br/>Hello from Docker!"]

7. 动手体验 Docker

▶ 示例:运行 hello-world(难度⭐)

最简单的 Docker 体验——验证 Docker 已正确安装。

BASH
# Pull and run the hello-world image
docker run hello-world
💻 输出:

TEXT 📖 仅展示
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
e6590344b1a5: Pull complete
Digest: sha256:7be1...2c2d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

▶ 示例:查看 Docker 配置信息(难度⭐)

docker info 显示 Docker 守护进程的完整配置。

BASH
# Display system-wide Docker information
docker info
💻 输出(节选):

TEXT 📖 仅展示
Client: Docker Engine - Community
 Version:    24.0.7
 Context:    default

Server:
 Containers: 3
  Running: 1
  Paused: 0
  Stopped: 2
 Images: 5
 Server Version: 24.0.7
 Storage Driver: overlay2
 Kernel Version: 5.15.0-91-generic
 Operating System: Ubuntu 22.04

▶ 示例:浏览 Docker 命令分类(难度⭐)

Docker CLI 按管理对象分类,方便记忆。

BASH
# List all Docker management commands
docker --help
💻 输出(节选):

TEXT 📖 仅展示
Management Commands:
  builder     Manage builds
  container   Manage containers
  image       Manage images
  network     Manage networks
  volume      Manage volumes
  system      Manage Docker

Commands:
  run         Create and run a new container
  ps          List containers
  images      List images
  build       Build an image from a Dockerfile
  pull        Pull an image from a registry

▶ 示例:体验运行 Nginx Web server(难度⭐⭐)

用 Docker 一行命令启动一个 Web server,无需安装 Nginx。

BASH
# Run Nginx in detached mode, map port 8080 to container port 80
docker run -d -p 8080:80 --name my-nginx nginx:latest

# Verify the container is running
docker ps
💻 输出:

TEXT 📖 仅展示
CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
a1b2c3d4e5f6   nginx:latest   Up 10 seconds  0.0.0.0:8080->80/tcp   my-nginx

打开浏览器访问 http://localhost:8080 即可看到 Nginx 欢迎页。

▶ 示例:查看当前运行的容器列表(难度⭐)

BASH
# List all running containers
docker ps

# List all containers (including stopped ones)
docker ps -a
💻 输出:

TEXT 📖 仅展示
CONTAINER ID   IMAGE           STATUS                    PORTS       NAMES
a1b2c3d4e5f6   nginx:latest    Up 5 minutes              8080->80    my-nginx
f7e8d9c0b1a2   hello-world     Exited (0) 3 minutes ago              hungry_einstein
⚠️ 注意: hello-world 容器运行后自动退出(状态为 Exited),这不是错误——它本身就是一个"运行完就退出"的演示容器。


8. Docker 版本与安装确认

(1) Docker 版本体系

version position 更新频率 适用场景
Docker Desktop 开发者桌面版 季度更新 Windows / Mac 开发环境
Docker Engine 服务器版 季度更新 Linux 生产环境
Docker CE 社区版(免费) 持续更新 个人和小团队
Docker EE 企业版(付费) 持续更新 大企业 + 商业支持

(2) 验证安装是否成功

BASH
# Check Docker client and server versions
docker version

# Quick verification: run hello-world
docker run hello-world

如果 docker version 同时显示 Client 和 Server 信息,说明安装成功。


9. 完整示例:Docker 初体验全流程

BASH
# ============================================
# Complete walkthrough: First Docker experience
# Covers: version check, info, run, ps, clean
# ============================================

# 1. Verify Docker is installed and running
docker version

# 2. View Docker system information
docker info

# 3. Run the hello-world container (first pull, then run)
docker run hello-world

# 4. Run an Nginx web server
docker run -d -p 8080:80 --name web nginx:latest

# 5. List running containers
docker ps

# 6. Stop and remove the Nginx container
docker stop web
docker rm web

# 7. View all containers (including stopped)
docker ps -a

# 8. Clean up: remove the stopped hello-world container
docker rm $(docker ps -a -q --filter "ancestor=hello-world")
💻 输出(节选):

TEXT 📖 仅展示
# docker version
Client: Docker Engine - Community
 Version:    24.0.7
Server: Docker Engine - Community
 Version:    24.0.7

# docker run hello-world
Hello from Docker!

# docker ps (while Nginx is running)
CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
a1b2c3d4e5f6   nginx:latest   Up 10 seconds  0.0.0.0:8080->80/tcp   web

❓ 常见问题

Q Docker 和 VirtualBox 有什么区别?
A VirtualBox 模拟完整操作系统(含内核),启动需分钟级,占用 GB 级资源。Docker 共享主机内核,只隔离进程,启动秒级,占用 MB 级。Docker 更轻更快,但不支持在 Linux 主机上运行 Windows 容器(反之亦然)。
Q 容器里跑的是操作系统吗?
A 不是。容器共享主机内核,没有自己的内核。容器里的"Ubuntu"只是用户空间工具集(bash、apt 等),不是完整操作系统。这也是容器比虚拟机轻量的根本原因。
Q Docker 只能在 Linux 上用吗?
A Docker 容器依赖 Linux 内核特性(namespace/cgroup),所以原生运行在 Linux 上。Windows/Mac 的 Docker Desktop 通过内置 Linux 虚拟机(WSL2/Hypervisor)间接运行容器,对用户透明。
Q Windows 上怎么装 Docker?
A 安装 Docker Desktop for Windows,它会自动使用 WSL2 作为后端。前提是 Windows 10 64-bit(version 1903+)且启用 WSL2。安装后打开 Docker Desktop,在终端执行 docker run hello-world 验证即可。
Q 容器会泄露主机数据吗?
A 默认不会。容器通过 Linux namespace 实现文件系统/网络/进程隔离,无法直接访问主机文件。除非显式挂载主机目录(-v parameter),容器与主机是隔离的。但以 --privileged 运行会突破隔离,生产环境禁用。
Q Docker 和 Kubernetes 是什么关系?
A Docker 是容器运行时(负责构建和运行单个容器),Kubernetes 是容器编排平台(负责管理成百上千个容器的调度、伸缩、自愈)。K8s 使用 containerd(Docker 拆分出的运行时)来运行容器,不再直接依赖 Docker。
Q 学 Docker 一定要会 Linux 吗?
A 需要基本的 Linux 命令行能力(ls/cd/mkdir/cat/grep),但不需要精通 Linux。Docker 的核心操作都是 docker 命令,本教程会从零讲起,所需的 Linux 知识会同步解释。

📖 小节


📝 作业

  1. 基础题(难度⭐):安装 Docker Desktop 并运行 docker run hello-world,截图或复制输出结果。
  2. 进阶题(难度⭐⭐):运行 docker info 查看本机 Docker config,记录 Containers 数量、Storage Driver、Kernel Version 三个字段的值。
  3. 挑战题(难度⭐⭐⭐):列举容器和虚拟机的优缺点各 3 条,并说明在什么场景下应该选择容器、什么场景下应该选择虚拟机。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏