Appearance
容器核心概念
容器是一种操作系统级隔离技术。它把应用进程放进受控的运行环境中,让进程看到独立的文件系统、网络、进程空间和资源限制。容器本身不是 Docker,Docker、containerd、CRI-O、Podman 都是围绕容器能力形成的工具或运行时。
容器解决什么问题
传统部署依赖服务器环境:系统版本、动态库、目录、用户权限和启动脚本都可能影响应用运行。容器把这些运行条件收敛成镜像和启动参数,让应用交付更稳定。
| 问题 | 容器提供的能力 |
|---|---|
| 环境不一致 | 镜像封装运行依赖 |
| 进程互相影响 | namespace 隔离进程、网络、挂载等视图 |
| 资源争抢 | cgroup 限制 CPU、内存、IO 等资源 |
| 部署不可复现 | 镜像标签和摘要让制品可追踪 |
| 迁移成本高 | 只要运行时支持标准镜像,就能拉取运行 |
容器不是虚拟机
虚拟机模拟完整硬件并运行独立操作系统,容器共享宿主机内核,只隔离用户态进程的运行视图。因此容器启动更快、资源占用更小,但隔离边界也不同。
| 对比项 | 容器 | 虚拟机 |
|---|---|---|
| 内核 | 共享宿主机内核 | 每台虚拟机有独立内核 |
| 启动速度 | 通常秒级 | 通常更慢 |
| 镜像大小 | 通常较小 | 通常较大 |
| 隔离强度 | 依赖内核隔离能力 | 边界更接近独立机器 |
| 典型用途 | 应用交付、弹性部署、微服务 | 强隔离、多系统、传统虚拟化 |
镜像和容器
镜像是只读模板,包含应用文件、依赖、环境变量、启动命令等信息。容器是镜像启动后的运行实例。一个镜像可以启动多个容器,每个容器都有自己的运行状态。
容器运行时会在镜像只读层上叠加可写层。进程写入容器内部文件时,变化会进入容器可写层。删除容器后,这层数据通常随之消失。需要持久保存的数据,应放在卷、绑定挂载或外部存储中。
| 内容 | 生命周期 |
|---|---|
| 镜像层 | 跟随镜像版本存在,可被多个容器复用 |
| 容器可写层 | 跟随容器存在,删除容器后消失 |
| Volume | 独立于容器存在,可重新挂载 |
| 外部存储 | 由数据库、对象存储、云盘或分布式存储系统维护 |
容器的底层隔离
Linux 容器主要依赖 namespace 和 cgroup:
| 机制 | 作用 |
|---|---|
| PID namespace | 让容器看到独立的进程编号空间 |
| Network namespace | 让容器拥有独立网卡、路由和端口空间 |
| Mount namespace | 让容器看到独立文件系统挂载视图 |
| UTS namespace | 隔离主机名和域名 |
| IPC namespace | 隔离进程间通信资源 |
| User namespace | 映射容器内外用户身份 |
| cgroup | 限制和统计 CPU、内存、IO、进程数等资源 |
理解这些机制有助于排查权限、网络、挂载和资源限制问题。比如容器内端口监听正常但外部访问不到,通常要检查网络命名空间和端口映射;容器内写文件失败,通常要检查挂载点、用户身份和宿主机目录权限。
容器生态分层
容器生态可以按职责分成几层:
| 层级 | 作用 | 例子 |
|---|---|---|
| 镜像构建 | 把应用和依赖做成镜像 | Dockerfile、BuildKit、buildx |
| 镜像分发 | 存储、拉取、推送镜像 | Registry、Harbor、Docker Hub |
| 高层工具 | 提供面向用户的命令和工作流 | Docker、Podman |
| 容器运行时 | 管理镜像、容器生命周期和 CRI | containerd、CRI-O |
| 低层运行时 | 真正创建隔离环境并启动进程 | runc、crun |
| 编排平台 | 管理多节点、多副本、服务发现和发布 | Kubernetes |
Docker 是最常见的容器使用入口,containerd 是常见的容器运行时,Kubernetes 是容器部署和编排平台,Colima 是 macOS 上创建本地容器环境的工具。它们属于不同层级,不应混为同一类。
