github编辑

容器

一句话理解容器

容器是镜像的运行实例。如果把镜像比作程序,那么容器就是进程。

用面向对象编程的术语来说:镜像是类(Class),容器是对象(Instance)

  • 一个镜像可以创建多个容器

  • 每个容器相互独立,互不影响

  • 容器可以被创建、启动、停止、删除、暂停

容器的本质

💡 笔者认为,理解这一点是理解 Docker 的关键

容器的本质是一个特殊的进程。

┌─────────────────────────────────────────────────────────────┐
│                     普通进程                                 │
│  • 与其他进程共享系统资源                                     │
│  • 可以看到其他进程                                          │
│  • 共享网络和文件系统                                         │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                     容器进程                                 │
│  ┌───────────────────────────────────────────────────────┐ │
│  │  • 有自己的进程空间(看不到宿主机上的其他进程)           │ │
│  │  • 有自己的网络(独立 IP、端口)                         │ │
│  │  • 有自己的文件系统(独立的 root 目录)                  │ │
│  │  • 有自己的用户(容器内的 root ≠ 宿主机的 root)         │ │
│  └───────────────────────────────────────────────────────┘ │
│     但仍然运行在宿主机的内核上                                │
└─────────────────────────────────────────────────────────────┘

这种隔离是通过 Linux 内核的 Namespace 技术实现的。

容器 vs 虚拟机:核心区别

很多初学者会混淆容器和虚拟机。笔者用一张图来说明:

特性
容器
虚拟机

隔离级别

进程级(Namespace)

硬件级(Hypervisor)

启动时间

秒级(甚至毫秒)

分钟级

资源占用

MB 级别

GB 级别

性能损耗

几乎为零

5-20%

内核

共享宿主机内核

各自独立内核

容器的存储层

镜像层 + 容器层

当容器运行时,Docker 会在镜像的只读层之上创建一个可写层(容器存储层):

Copy-on-Write(写时复制)

当容器需要修改镜像层中的文件时:

  1. Docker 将该文件复制到容器存储层

  2. 在容器层中进行修改

  3. 原始镜像层保持不变

⚠️ 容器存储层的生命周期

笔者特别强调:这是新手最容易踩的坑!

容器存储层与容器生命周期绑定。容器删除,数据就没了!

正确的数据持久化方式

按照 Docker 最佳实践,容器存储层应该保持无状态。需要持久化的数据应该使用:

方式
说明
适用场景

Docker 管理的存储

数据库、应用数据

挂载宿主机目录

开发时共享代码

这些位置的读写会跳过容器存储层,直接写入宿主机,性能更好,也不会随容器删除而丢失。

容器的生命周期

常用生命周期命令

容器与进程的关系

核心概念:容器的生命周期 = 主进程(PID 1)的生命周期

这就是为什么:

详细解释请参考后台运行章节。

容器的隔离性

Docker 容器通过以下 Namespace 实现隔离:

Namespace
隔离内容
效果

PID

进程 ID

容器内 PID 1 是应用进程,看不到宿主机其他进程

NET

网络

独立的网络栈、IP 地址、端口

MNT

文件系统

独立的根目录和挂载点

UTS

主机名

独立的主机名和域名

IPC

进程间通信

独立的信号量、消息队列

USER

用户

独立的用户和组 ID

想深入了解?请阅读底层实现 - 命名空间

本章小结

概念
要点

容器是什么

镜像的运行实例,本质是隔离的进程

容器 vs 虚拟机

共享内核,更轻量,但隔离性较弱

存储层

可写层随容器删除而消失

数据持久化

使用 Volume 或 Bind Mount

生命周期

与主进程(PID 1)绑定

理解了镜像和容器,接下来让我们学习仓库——存储和分发镜像的服务。

延伸阅读

最后更新于