1Docker 深度探索

容器和 Docker 简介

什么是容器

容器虚拟化命名空间

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第1章:容器和Docker简介(Introduction to Containers and Docker)

一、导读

1.1 本章学习目标

本章是容器技术的入门导论。从虚拟化技术的演进讲起,你将理解容器为何成为现代软件交付的标准方式。本章介绍容器的核心优势、Docker 的历史贡献、以及容器的 Linux 内核基础。

本章的核心学习目标包括:

  • 理解虚拟化技术的演进:从物理机到虚拟机再到容器的演进路径。
  • 掌握容器 vs 虚拟机的本质区别:共享内核 vs 独立内核。
  • 了解 Docker 的历史和贡献:Docker 如何民主化了容器技术。
  • 理解容器的 Linux 内核基础:Namespace、Cgroups、UnionFS。
  • 掌握 Docker 的基本操作:安装、运行、管理容器。
  • 了解容器生态系统:Docker、containerd、CRI-O、OCI。

1.2 为什么本章如此重要

容器是 Kubernetes、微服务、云原生等现代技术的基石。不理解容器,就无法理解这些上层技术。本章建立的容器基础认知,将贯穿整本书的学习。

更重要的是,容器不仅仅是一项技术,更是一种软件交付的范式转变。它改变了我们构建、分发、运行软件的方式。理解这种范式转变,才能充分利用容器的价值。

1.3 核心问题引导

容器和虚拟机的根本区别是什么?为什么容器比虚拟机更轻量?

Docker 之前就有容器技术(LXC),为什么 Docker 能改变世界?

什么是 Namespace?它如何隔离进程、网络、文件系统?

什么是 Cgroups?它如何限制容器的 CPU 和内存?

什么是 UnionFS?它如何让镜像分层存储?


二、核心概念详解

2.1 虚拟化技术的演进

2.1.1 物理机时代

一台物理服务器运行一个应用。问题:

  • 资源利用率低(通常 10-15%)
  • 部署慢(数天到数周)
  • 运维成本高

2.1.2 虚拟机时代

Hypervisor(VMware、KVM、Xen)在一台物理机上运行多个虚拟机。每个 VM 有独立的操作系统。

优势:

  • 资源利用率提升(60-80%)
  • 隔离性好(独立内核)
  • 快速部署(分钟级)

问题:

  • 每个 VM 需要完整的 OS,资源浪费
  • 启动慢(数十秒到分钟)
  • 密度有限(单机数十个 VM)

2.1.3 容器时代

容器共享宿主机内核,只隔离应用运行环境。

优势:

  • 秒级启动
  • MB 级镜像
  • 单机数百个容器
  • 接近原生的性能

2.2 容器 vs 虚拟机

特性容器虚拟机
抽象级别OS 级别(共享内核)硬件级别(独立内核)
启动速度< 1秒数十秒到分钟
镜像大小几十 MB几 GB
性能损耗接近原生5-20%
密度单机数百个单机数十个
隔离性进程级(较弱)硬件级(较强)
# 容器架构
┌─────────┐ ┌─────────┐ ┌─────────┐
│  App A  │ │  App B  │ │  App C  │
├─────────┤ ├─────────┤ ├─────────┤
│ Bins/   │ │ Bins/   │ │ Bins/   │
│ Libs    │ │ Libs    │ │ Libs    │
├─────────┴─┴─────────┴─┴─────────┤
│         Docker Engine            │
├─────────────────────────────────┤
│           Host OS                │
├─────────────────────────────────┤
│          Hardware                │
└─────────────────────────────────┘

# 虚拟机架构
┌─────────┐ ┌─────────┐ ┌─────────┐
│  App A  │ │  App B  │ │  App C  │
├─────────┤ ├─────────┤ ├─────────┤
│ Bins/   │ │ Bins/   │ │ Bins/   │
│ Libs    │ │ Libs    │ │ Libs    │
├─────────┤ ├─────────┤ ├─────────┤
│ Guest OS│ │ Guest OS│ │ Guest OS│
├─────────┴─┴─────────┴─┴─────────┤
│         Hypervisor               │
├─────────────────────────────────┤
│          Hardware                │
└─────────────────────────────────┘

2.3 Docker 的历史

2013 年,PaaS 公司 dotCloud 内部开发了一个工具,用于简化应用的打包和部署。这个工具就是 Docker。Docker 的贡献在于:

  • 简化了容器操作:提供友好的 CLI 和 API
  • 引入了镜像构建:Dockerfile 让镜像构建可重复
  • 建立了镜像生态:Docker Hub 让镜像分发变得简单
  • 推动了标准化:推动了 OCI 标准的建立

2.4 容器的 Linux 内核基础

2.4.1 Namespace(隔离)

Namespace 让容器觉得自己独占系统:

Namespace隔离内容
PID进程 ID
Network网络栈
Mount文件系统
User用户 ID
IPC进程间通信
UTS主机名
bash
# 在新的 PID + Mount Namespace 中运行
unshare --pid --fork --mount-proc bash
echo $$  # 输出: 1

2.4.2 Cgroups(资源限制)

Cgroups 限制容器能使用的资源:

bash
# 限制 CPU 和内存
docker run --cpus=1.5 --memory=512m myapp

2.4.3 UnionFS(分层文件系统)

UnionFS 将多个目录联合挂载。Docker 使用 overlay2 驱动实现镜像分层。

2.5 Docker 架构

Docker CLI → Docker Daemon (dockerd) → containerd → runc → Linux Kernel
  • Docker CLI:用户接口
  • Docker Daemon:管理 Docker 对象
  • containerd:容器生命周期管理
  • runc:创建和运行容器
  • Linux Kernel:Namespace + Cgroups + UnionFS

三、实战案例

3.1 安装 Docker

bash
# Ubuntu
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# 验证
docker version
docker info

3.2 运行第一个容器

bash
# 运行 hello-world
docker run hello-world

# 运行 Nginx
docker run -d -p 8080:80 --name web nginx
curl http://localhost:8080

# 查看运行中的容器
docker ps

# 查看容器日志
docker logs web

# 进入容器
docker exec -it web /bin/bash

# 停止和删除
docker stop web
docker rm web

3.3 容器资源观察

bash
# 实时查看容器资源使用
docker stats

# 查看容器详细信息
docker inspect web

# 查看容器进程
docker top web

四、本章小结

容器共享内核,比虚拟机更轻量、启动更快、密度更高。

Docker 民主化了容器技术,提供了友好的工具和镜像生态。

Namespace 提供隔离,Cgroups 提供资源限制,UnionFS 提供分层存储。

Docker 架构:CLI → Daemon → containerd → runc → Kernel。


五、思考与练习

思考题

为什么容器的隔离性不如虚拟机?在什么场景下这可能成为问题?

Docker 之前就有 LXC,为什么 Docker 更成功?

如果两个容器共享内核,一个容器的内核漏洞会影响其他容器吗?

为什么容器启动只需不到1秒,而虚拟机需要数十秒?

练习题

安装 Docker,运行 hello-world 和 nginx 容器。

使用 docker stats 观察容器的资源占用。

对比启动容器和启动虚拟机的时间差异。

使用 unshare 命令手动创建 Namespace,观察隔离效果。

1/8容器和
0%