跳转至

第 1 章 容器与云原生基础

配套实验手册:本课程所有动手实验见《Kubernetes 实验手册》(manual/ 目录)。本章为基础铺垫,无强制实验;若需温故容器操作,可自行用 Docker 快速体验(见 1.2 节命令)。

学习目标

学完本章,你应该能够:

  1. 解释容器的核心技术原理(命名空间隔离、cgroups 资源限制、镜像分层)
  2. 说出 Docker 的镜像/容器/仓库三要素及常用操作
  3. 分析容器化应用在单机场景下的痛点,理解"为什么需要编排器"
  4. 说明云原生(Cloud Native)的定义与 CNCF 生态定位
  5. 对比 Kubernetes / Docker Swarm / Mesos,说出 Kubernetes 胜出的核心理由

1.1 容器技术原理

1.1.1 从虚拟机到容器

维度 虚拟机(VM) 容器
隔离级别 硬件级(Hypervisor 虚拟整机) 操作系统级(内核共享)
每个实例 完整 Guest OS(GB 级) 仅应用 + 依赖(MB 级)
启动时间 分钟级 秒级(进程级启动)
密度 低(每台机几十个) 高(每台机成百上千)
性能 有虚拟化开销 接近原生

为什么容器更快更轻:容器共享宿主机内核,不虚拟硬件和操作系统——它只是宿主上的一组受约束的进程。隔离和限制通过 Linux 内核的两个机制实现。

1.1.2 命名空间(Namespaces):隔离"看得见"

命名空间让容器里的进程"以为"自己独占系统资源。每个容器创建时,内核为它建立独立的命名空间视图:

命名空间 隔离内容 容器里看到
PID 进程编号 自己是 PID 1,看不到宿主机其他进程
Mount 文件系统挂载点 只看到自己的根文件系统
Network 网络栈(网卡/IP/路由) 自己的 IP 和端口
UTS 主机名 自己的 hostname
IPC 进程间通信 独立的信号量/消息队列
User 用户 ID 独立的 UID 映射(容器内 root ≠ 宿主机 root)

1.1.3 cgroups:限制"能用多少"

cgroups(Control Groups)限制容器能消耗多少资源:

  • cpu:CPU 份额与配额(如最多用 0.5 核)
  • memory:内存上限(超限触发 OOM Killer)
  • cpuset:绑定特定 CPU 核
  • blkio:磁盘 IO 带宽

教学记忆:命名空间管"看不见"(隔离),cgroups 管"用多少"(限制)——两者结合,容器既安全隔离又可被资源管控。

1.1.4 镜像分层(Layer)

镜像不是一个大文件,而是只读层的堆叠:

┌─────────────────────┐
│  应用层(App)        │  ← 可写层(容器运行时在此写)
├─────────────────────┤
│  RUN 指令层          │
├─────────────────────┤
│  apt 安装层          │
├─────────────────────┤
│  基础镜像层(OS)     │
└─────────────────────┘
  • 每层只存与上一层的差异(增量)
  • 多个容器共享相同底层 → 磁盘占用小、启动快
  • 容器运行时的写入发生在最上层可写层——删除容器即可写层消失(这就是"容器无状态"的底层原因,第 4 章讲持久化)

1.1.5 OCI 标准:让"容器"不绑死某一家

OCI(Open Container Initiative) 是容器格式与运行时的开放标准(2015 年由 Docker 等发起,现由 Linux 基金会托管),由两个规范组成:

  • Image Spec(镜像规范):镜像的打包格式(分层/配置/manifest)——任何符合规范的镜像,任何符合规范的运行时都能跑
  • Runtime Spec(运行时规范):容器运行时的行为(进程/命名空间/cgroups 配置、生命周期钩子)

为什么重要(本书的伏笔):

  • Docker 构建的镜像(符合 OCI Image Spec)→ containerd(符合 OCI Runtime Spec)直接运行——第 3 章"K8s 用 containerd 替换 Docker"之所以无缝,正是因为大家都遵守 OCI
  • 生态不绑死:镜像可以来自 Docker/Podman/Buildah,运行时可以是 containerd/CRI-O——标准是生态互通的基石

核心认知:OCI 是"容器界的 USB 接口"——第 1 章学的镜像分层、第 3 章装的 containerd,都在 OCI 的框架内工作。Docker 只是"最流行的 OCI 实现之一"。


1.2 Docker 快速回顾(镜像 / 容器 / 仓库)

本课程不要求精通 Docker,但 K8s 使用 OCI 兼容的容器运行时(containerd),理解 Docker 的三要素有助于后续章节。

1.2.1 三大概念

概念 类比 说明
镜像(Image) 安装包/模板 只读的打包产物,包含应用 + 依赖 + 配置
容器(Container) 运行中的进程 镜像的运行实例,有独立命名空间与 cgroups
仓库(Registry) 应用商店 存放和分发镜像(Docker Hub / 私有仓库)

1.2.2 常用命令速查

docker build -t myapp:v1 .        # 构建镜像
docker images                     # 查看本地镜像
docker pull nginx:latest          # 拉取镜像
docker run -d -p 8080:80 nginx    # 运行容器(后台、端口映射)
docker ps                         # 查看运行中容器
docker exec -it <容器> /bin/bash  # 进入容器
docker logs <容器>                # 查看日志
docker rm -f <容器>               # 删除容器
docker rmi <镜像>                 # 删除镜像

与 Kubernetes 的衔接:K8s 用 containerd(兼容 OCI 镜像)替代 Docker 守护进程作为运行时,但镜像的构建、仓库、分层机制完全一致——实验 01 安装时配置的镜像加速就是针对 Docker Hub 的镜像分发。


1.3 容器化的价值与挑战

1.3.1 价值

  • 可移植性:构建一次,处处运行(开发/测试/生产一致)
  • 资源效率:高密度、秒级启动,弹性伸缩的基础
  • 一致性:环境差异消失("在我机器上是好的"不再成立)
  • 快速交付:镜像即部署产物,CI/CD 流水线化

1.3.2 单机场景的挑战(编排器的需求来源)

用 Docker 跑一个容器很简单,但跑一组容器做生产时:

挑战 具体问题
单点故障 容器崩了谁重启?机器挂了谁迁移?
扩缩容 流量大了手动 docker run 复制十份?流量降了呢?
服务发现 容器 IP 每次重启都变,前端怎么找到后端?
负载均衡 多个副本之间流量怎么分发?
健康检查 容器"活着"不代表"能用",谁来探测?
存储 容器删了数据没了,数据库怎么办?
配置与密钥 几十个容器的环境变量/密码怎么统一管理?

结论:单机 Docker 解决"如何跑一个容器",编排器解决"如何运维一群容器"——这正是 Kubernetes 的定位(第 2 章)。


1.4 云原生与 CNCF

1.4.1 云原生的定义

CNCF(Cloud Native Computing Foundation)对云原生的定义:

云原生技术使组织能够在现代动态环境(如公有云、私有云、混合云)中构建和运行可扩展的应用程序。容器、服务网格、微服务、不可变基础设施和声明式 API 是这一方法的典型特征。

核心要素:

  • 容器化:应用打包为容器(可移植、隔离)
  • 微服务:单体拆分为可独立部署的服务
  • 动态编排:Kubernetes 自动调度、扩缩、自愈
  • DevOps:开发与运维一体化,CI/CD 自动化
  • 声明式:描述"期望状态",系统自行达到(第 2 章核心概念)

1.4.2 CNCF 项目全景(与本课程相关)

层次 代表项目 本课程对应
编排 Kubernetes 全书
容器运行时 containerd / CRI-O 第 1、3 章
网络 Calico / Cilium / Flannel 第 9 章(实验手册(实验 07))
存储 Rook / Longhorn 第 10 章(实验手册(实验 08))
可观测性 Prometheus / Grafana 第 15 章
服务网格 Istio / Linkerd 进阶(本课程略)

1.5 容器编排器对比:为什么是 Kubernetes

能力 Docker Swarm Apache Mesos Kubernetes
定位 Docker 原生集群 数据中心级资源调度 容器编排事实标准
成熟度 简单但功能有限 复杂、运维门槛高 生态最完整
服务发现/负载均衡 内建(简单) 需额外组件 Service + Ingress(第 9 章)
自愈/扩缩容 有限 有限 Deployment/HPA(第 5、7 章)
存储/网络插件 少 少 丰富的 CSI/CNI 生态
社区与生态 停滞 停滞 CNCF 最大项目,事实标准

Kubernetes 胜出的核心理由:

  1. 声明式 API + 控制循环:用户描述"期望状态",控制器持续调和——设计优雅,可扩展
  2. 可扩展性:CRD、Operator、CNI/CSI 插件机制,生态爆炸式增长
  3. 云厂商背书:AWS/Azure/GCP/阿里云全部提供托管 K8s(EKS/AKS/GKE/ACK)
  4. CKA 认证体系:人才市场认可(本课程目标)

实验演练指引

本章为基础铺垫,无强制实验。若希望热身,可在任意 Linux 机器上:

# 体验容器三要素(需已装 Docker/containerd)
docker run -d --name demo -p 8080:80 nginx
docker exec -it demo bash        # 进入容器:ps 看 PID 1、hostname 看隔离
docker rm -f demo                # 删除容器:进程消失,镜像还在

目的:直观感受"容器 = 隔离的进程"(PID 1、独立 hostname),为第 2 章"Pod 是 K8s 的最小调度单元"建立直觉。不熟悉 Docker 不影响后续学习,遇到镜像操作照抄实验手册命令即可。

本章小结

  • 容器 = 命名空间(隔离)+ cgroups(限制) 的受控进程,比虚拟机轻量得多
  • 镜像 = 只读分层 + 可写层(容器运行时),共享底层省空间、启动快
  • 单机 Docker 的六大痛点(故障/扩缩/发现/均衡/健康/存储)→ 编排器的需求来源
  • 云原生 = 容器 + 微服务 + 动态编排 + DevOps + 声明式
  • Kubernetes 凭声明式 API + 生态 + 云厂商背书成为容器编排事实标准

衔接:第 2 章将进入 Kubernetes 本身——它的架构、组件与"声明式 API + 控制循环"的核心设计。

思考题

  1. 容器与虚拟机共享内核,那容器内执行 reboot 会发生什么?为什么?
  2. 为什么说"容器没有持久化"?镜像分层中哪一层解释了这一点?
  3. 单机 Docker 的痛点中,你认为哪一个对生产影响最大?Kubernetes 用什么机制解决它(可以提前翻第 2/5 章找答案)?
  4. 云原生的"声明式"与传统"命令式"运维的区别是什么?举一个生活中的例子。

CKA 考点标注:本章为前置基础,无直接 CKA 考点;但容器原理是理解后续所有章节(尤其第 3 章运行时、第 4 章 Pod)的前提,考试中的排障题常要求理解容器生命周期。