ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

云原生技术全景:容器演进、底层原理与复习指南

云原生技术全景:容器演进、底层原理与复习指南

简介:云原生技术的前世今生是一份面向云计算开发者和架构师的技术梳理文档,系统讲解云原生从传统IaaS到Cloud 2.0的发展脉络,涵盖CNCF官方定义、容器与Kubernetes演进、服务网格及Serverless等核心议题。资源为1个PDF文件,压缩包大小3.98MB,便于离线阅读和快速检索。内容兼顾理论、历史与关键实现,既介绍容器、微服务、不可变基础设施、声明式API等基础概念,也深入容器底层Linux Cgroup与Namespace隔离机制,还展示了Docker镜像分发、Kubernetes编排、Prometheus监控、Istio服务网格等生态组件如何协同工作。目前已有204人学习,适合正在做云原生入门、希望建立技术全景的读者。通过这份文档可理清容器技术、编排平台与云原生生态的来龙去脉,为后续学习Kubernetes实践和云原生架构设计打下扎实基础。

1. 云原生是一条演进线,不是一堆名词的合集

云原生这个词这几年几乎成了技术社区最热门的前缀,但它的核心并不神秘。梳理下来会发现,它不是某一项技术的名称,而是一条由容器、微服务、服务网格、不可变基础设施和声明式 API 串起来的演进链条。很多人复习时第一个翻车点,就是把云原生当成孤立的考点去背,结果 CNCF 的定义、容器原理、Kubernetes 架构、服务网格各自都懂一点,串在一起就乱了。这份笔记先把整条线捋直:从云原生计算基金会给出的官方定义出发,沿着容器技术从 chroot 到 Docker 再到 Kata 的演进路径,落到底层 Cgroup、Namespace、联合文件系统这三件套的细节,最后用一张自查表查漏补缺。适合正在系统学云原生、或复习备考前想要一份知识地图的读者。

2. 云原生的定义拆解:五个关键词与 CNCF 生态地图

2.1 官方定义里的五个关键词是一条因果链

云原生计算基金会(CNCF)对云原生的定义,是理解整个方向的入口,也是面试和考试里反复出现的高频题眼。定义强调云原生技术有利于在公有云、私有云和混合云等动态环境中构建和运行可弹性扩展的应用,代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。这几个词并不是并列的五个考点,而是一条因果链:容器解决打包与隔离,微服务解决应用拆分,服务网格解决拆分后服务间的通信治理,不可变基础设施解决环境漂移,声明式 API 解决系统状态的管理方式。五个关键词从不同层面回答了同一个问题:在动态的云环境里,怎么让应用跑得稳、改得快、管得动。

把这条链拆开来看。容器的角色是最小交付单元,它把应用和依赖一起打包,屏蔽底层环境的差异,让应用在开发机、测试机和生产机上表现一致。微服务是组织应用的方式,把单体拆成可以独立开发、独立部署的小服务,每个服务只围绕一个业务能力展开。服务网格是微服务之间的通信层,服务数量增多后,调用关系变得复杂,光靠应用代码里写死的重试、熔断、负载均衡逻辑撑不住,于是把通信治理能力下沉到独立的基础设施层,Istio 和 Linkerd 是这一层的代表项目。

不可变基础设施和声明式 API 是定义里最容易被扫一眼就放过的两个词。不可变基础设施的意思是基础设施一旦部署就不再原地修改,要变更就重新创建新实例,这直接规避了环境漂移问题。声明式 API 则是指开发者只描述期望的系统状态,比如“我要 3 个副本”,至于怎么从当前状态到达期望状态,由控制面自己计算和执行。Kubernetes 是声明式 API 最典型的落地,它的各类 API 对象——Deployment、Service、ConfigMap——都是用户描述期望状态,控制面负责调和。

复习这一小节时,建议把五个关键词、解决的问题、典型项目、常见误用拉成一张四列对应表。表格不要求背下来,但能帮助你回答一个高频问题:“云原生到底包括什么?”用这条因果链回答,比背诵定义原文显得清晰得多。以下表格可用作参考:

关键词解决的问题典型代表常见误用
容器打包与隔离Docker、Containerd把容器当成轻量虚拟机来修补
微服务应用拆分与独立部署各类微服务框架拆得越细越好导致运维爆炸
服务网格服务间通信治理Istio、Linkerd与 API 网关混为一谈
不可变基础设施环境一致性容器镜像、自动化交付部署后手动登录机器改配置
声明式 API状态管理Kubernetes API 对象用命令式 kubectl 操作代替描述状态

2.2 CNCF 生态地图:按功能分层,而不是按热度记

CNCF 旗下有上百个开源项目,按热度一个个背没有意义。更高效的整理方式是按功能分层,每一层解决一类问题。梳理下来,可以从五层去记忆:容器运行时与镜像层、编排调度层、服务发现与网络层、监控运维层、安全与策略层。

容器运行时与镜像层是地基,解决容器怎么运行、镜像怎么存储和分发。核心项目是 Containerd 和容器引擎,镜像安全由 Notary 与 TUF 负责,它们提供镜像签名和信任链校验,确保从仓库拉下来的镜像没有被篡改。编排调度层是整个生态的大脑,Kubernetes 是绝对的核心,负责容器的调度、伸缩与故障自愈;Helm 做 Kubernetes 资源的打包管理,解决一组相关对象能不能一次发布的问题。

服务发现与网络层解决服务之间如何找到彼此、如何通信。CoreDNS 提供集群内部的域名解析,Envoy 是高性能数据面代理,也是服务网格默认的数据平面;Linkerd 是服务网格早期的代表项目,主打轻量。监控运维层里整合了指标、日志、链路三大块——Prometheus 负责指标采集和告警,Fluentd 负责日志收集,Jaeger 负责分布式链路追踪,OpenTracing 则是链路追踪的标准接口。

安全与策略层在复习中被漏掉的概率最高。SPIFFE 和 SPIRE 解决工作负载身份的颁发与校验,Open Policy Agent 把策略写成代码,CloudEvents 是云事件的标准化格式。这层的特点是项目不显眼,但踩坑时才会意识到它们的必要性。复习建议是能够做到看见一个项目名,根据它的功能描述判断属于哪一层;而不是记住每一个项目的名字。考场上遇到没见过的项目,这个分类能力能帮你稳定得分。

除了分层,还要注意 CNCF 的基金会有三个不同成熟度阶段:Sandbox、孵化项目和毕业项目。这个成熟度概念在考试里可以选择性了解,核心还是把 Kubernetes、Prometheus、Envoy、CoreDNS 这几个“毕业级”项目的定位抓准。

3. 容器技术演进:从 chroot 到 Docker 再到 Kata

3.1 二十多年演进路:隔离技术如何进入内核主线

容器不是凭空出现的发明,也不是 Docker 开创的。梳理这条演进线会发现,它的主线是“操作系统级隔离在内核中逐步成熟的过程”。最早的雏形可以追溯到 1980 年代的 chroot,它只能改变进程看到的根目录,实现最小粒度的文件系统隔离;之后陆续出现的 Linux-Vserver、OpenVZ、AIX WPAR、Solaris Zone 都算轻量级虚拟化产品,早期多用于 VPS 场景,但彼此之间缺乏统一标准,也没有进入 Linux 内核主线,必须靠额外补丁才能运行。

2007 年是这条线的关键拐点,cgroup 和 namespace 合入了 Linux 内核主线。容器底层的两大机制终于得到内核原生支持,不再依赖厂商补丁,任何发行版只要内核版本满足要求就能跑容器。2008 年 LXC 开源项目成立,把内核的隔离能力封装成用户态管理工具,容器才算有了比较友好的命令行入口。如果在这里梳理“容器技术发展的重要节点”,2007、2008、2013 是三个必须记住的时间点:内核提供基础能力,LXC 提供管理工具,Docker 提供统一平台。

2013 年 Docker 发布,是这条线上最显著的分水岭。Docker 不是第一个容器项目,但它第一次把“构建—分发—运行”做成标准流程,让容器从开发者的玩具变成了应用交付的标准方式。演进路线看到这里,可以得出一个准确的历史定位:容器技术的成熟经历了“内核能力积累(2007 年之前)→ 用户态工具化(2008 年 LXC)→ 平台化分发(2013 年 Docker)→ 大规模编排(2014 年 Kubernetes)→ 安全加固(Kata、gVisor)”五个阶段。

注意:历史演进类考点最容易丢分在“先后顺序”上。Docker 晚于 LXC 出现,Kubernetes 晚于 Docker 出现,Kata 容器又是在 Docker 生态成熟后才出现的。顺序记反,整个时间线的逻辑就全乱了。

3.2 容器技术的三波热潮与云计算的分代

容器技术的发展从 2013 年之后可以分成三波热潮。第一波是容器虚拟化本身,用容器做应用隔离和资源利用率的提升,替代传统虚拟机的一部分场景;第二波是容器编排,2014 年 Kubernetes 开源项目发布,解决了成百上千个容器的调度、服务发现和故障自愈问题,Kubernetes 自此成为容器编排的事实标准;第三波是云原生化,在容器和编排之上叠加微服务、服务网格、Serverless,让应用从“跑在容器里”升级为“原生适合云环境”。

这与云计算的分代是对应的。云计算 1.0 阶段的典型形态是 IaaS,代表是某公有云厂商在 2006 年推出的 EC2 弹性计算服务;传统虚拟化技术如 KVM、Xen 等是这一代的基础,用户购买的是虚拟机资源。云计算 2.0 阶段转向以应用为中心,PaaS 和 CaaS 成为主流,Docker 和 Kubernetes 的爆发推动了这个转型。OpenStack 社区成立于 2010 年,CloudFoundry 在 2011 年推出,它们代表了云 1.0 到云 2.0 之间的过渡探索。

云计算 2.0 的特点可以从四个现象观察:容器化替代虚拟化成为应用的主要载体,微服务化替代单体架构成为主流的应用架构,混合云成为常见部署形态,IoT 和视频等重负载场景逐步跑在云端。这个背景知识的价值在于,容器技术不是孤立发展的,它恰好踩在云计算从“卖资源”到“卖能力”的转换节点上。复习时抓住这条背景线,遇到“为什么容器在这个时间点爆发”之类的问题就有了回答框架。

3.3 从 Docker 到安全容器:普通容器与 Kata、gVisor 的区别

普通容器共享宿主机内核,这是它高效的根本原因,也是它安全弱点的根源。如果容器内进程利用内核漏洞逃逸,影响的不只是这一个容器,而是宿主机上所有容器。安全容器的出现就是为了解决这个问题。Kata 容器合并了 RunV 和 Clear Container 两个项目,每个容器或 Pod 对应一个轻量虚拟机,Guest OS 被高度裁剪和优化,启动时间极短,性能损耗极小,但虚拟化层的存在把容器和宿主机内核隔开,即使容器内发生逃逸,攻击者面对的也是虚拟化层。

Kata 容器与普通容器的技术差异值得用一张表对比理解:

维度普通容器Kata 容器
隔离机制Namespace + Cgroup轻量虚拟机 + 虚拟化层
内核共享宿主机内核每个容器独立 Guest OS 内核
启动速度毫秒级极短(裁剪优化后的 KVM)
镜像兼容Docker 镜像完全兼容 Docker 镜像
编排适配Docker / CRI-ODocker / CRI-O,融入 K8s 生态

gVisor 是另一种安全容器思路。它不启动虚拟机,而是在用户态实现一个应用内核,拦截容器进程的系统调用,经过用户态处理后再转发给宿主机内核。gVisor 的开销比 Kata 小,但隔离强度不如真正的虚拟化层。复习时需要能够区分:Kata 走硬件虚拟化路线,gVisor 走用户态系统调用拦截路线,二者解决的问题相同而原理不同。安全容器的典型使用场景是多租户平台,在共享平台上跑不同客户的容器,强隔离决定了平台的安全边界。

4. 容器底层三件套:Cgroup、Namespace 与联合文件系统

4.1 Cgroup:资源配额表与 Docker 参数对应

Cgroup 是 Linux 内核的资源管理机制,全称是 Control Group。Docker 用 Cgroup 给每个容器设定资源上限,没有它,容器之间会互相抢资源。把 Cgroup 理解为每个容器挂着的“资源配额表”最直观——这张表规定了容器最多能用多少内存、多少 CPU、多少磁盘 IO。配额设置不合理时,一个容器就能拖垮同宿主机上的所有邻居。

Cgroup 的子系统与 Docker 参数有明确的映射关系,这是复习的重点和易漏点。memory 子系统限制内存上限,对应-m参数,同时还有--memory-swap、--memory-reservation、--oom-kill-disable等细化控制。cpu 子系统通过--cpu-period和--cpu-quota组合限制 CPU 用量。cpuset 子系统负责为容器分配独立的 CPU 和内存节点,对应--cpuset-cpus和--cpuset-mems。blkio 子系统限制块设备读写,对应--blkio-weight、--device-read-bps、--device-write-iops等参数。

# 限制容器最多使用 512MB 内存、最多 1GB 交换分区 docker run -m 512m --memory-swap 1g myapp # 限制容器最多使用半个 CPU 核 # period = 100000 微秒(100ms),quota = 50000 微秒 docker run --cpu-period=100000 --cpu-quota=50000 myapp # 将容器绑定到 CPU 0 和 CPU 1 上运行 docker run --cpuset-cpus=0,1 --cpuset-mems=0 myapp # 限制块设备读速率,防止容器占满磁盘 IO docker run --device-read-bps=/dev/sda:1mb myapp

上面每组参数都对应一个 Cgroup 子系统:第一组属于 memory,第二组属于 cpu,第三组属于 cpuset,第四组属于 blkio。如果只记住-m和--cpus而不了解它背后的子系统,遇到题目中出现不认识的参数时就无法推理。反过来,当你看到任何一组以--memory-、--cpu-、--cpuset-、--blkio-开头的参数,都能快速判断它属于哪个子系统,这类题目就不会丢分。

Cgroup 版本问题也值得注意。Cgroup v1 按子系统分散管理,Cgroup v2 统一了层级结构,资源控制更精确,Docker 新版本默认使用 v2。很多旧书籍和旧文档写的还是 v1,遇到文档与实测不一致时,先检查内核版本和 Docker 的 cgroup 驱动再下结论。

4.2 Namespace:容器眼中的“世界”

Namespace 是 Linux 内核的隔离机制,Docker 用它让每个容器拥有独立的进程视图、主机名、IPC 资源、网络栈和挂载点。Namespace 解决的不是资源限制,而是“看得到什么”:一个容器里的进程看不到另一个容器的进程,也操作不了另一个容器的网络接口。它与 Cgroup 的分工是一句话可以讲清的:Cgroup 管资源多少,Namespace 管视野边界。

六个 Namespace 是必考的清单。PID namespace 隔离进程列表,不同 namespace 里可以有相同的 PID,且允许嵌套,这就是 Docker in Docker 能做的基础。UTS namespace 隔离主机名和域名,让容器在网络中表现为独立节点。IPC namespace 隔离信号量、消息队列和共享内存。Network namespace 隔离网络栈,每个容器有自己的网络设备、IP 地址、路由表和 /proc/net 目录。Mount namespace 隔离挂载点,容器里的 /proc/mounts 只包含属于自己命名空间的挂载。User namespace 隔离用户和组 ID,容器内可以有 root,但映射到宿主机可能是普通用户。

# 在宿主机上查看当前 shell 的 namespace 标识 ls -l /proc/$$/ns/ # 查看容器的进程 PID,并进一步查看该进程所在 namespace docker inspect <容器ID> --format '{{.State.Pid}}' sudo ls -l /proc/<该PID>/ns/

执行后能看到两类 namespace 标识之间的差异:宿主机进程和容器进程虽然共享内核,但每个 namespace 的 inode 编号不同,证明视图边界不同。用这个命令实操一遍,比背六种 namespace 的系统调用参数记得更牢。六个 Namespace 对应的系统调用参数分别是 CLONE_NEWPID、CLONE_NEWUTS、CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWUSER,建议把“参数—隔离内容—典型效果”做成一张三列对照表复习。

Namespace 的局限性同样要记住:隔离的是视图,不是内核。同一个宿主机上所有容器共享一个内核,内核漏洞一旦被利用,Namespace 层面的隔离并不能阻止横向影响,安全边界必须依靠虚拟化层或系统调用拦截来增强,这正是前面提到的 Kata 和 gVisor 存在的意义。

4.3 联合文件系统:分层镜像的存储基石

联合文件系统的核心思想是将一组目录交错叠加,形成单一视图。Docker 镜像的分层结构正是建立在它之上:镜像由多层只读层组成,容器启动时追加一个可写层,读取文件时从最上层逐层查找,写入时写入最上层。镜像层的复用因此成为可能——多个容器共享同一个镜像时,底层只读层只保存一份,每个容器只需维护自己的可写层,这也使新容器的启动速度更快。

Docker 曾经支持多种存储驱动,包括 devicemapper、overlay2、aufs、btrfs、vfs。其中 overlay2 是现代 Docker 的默认驱动,基于内核的 OverlayFS,性能好且稳定;devicemapper 是早期驱动,基于块设备,配置复杂而且已逐步退出;aufs 功能稳定但没有进入内核主线,需要额外内核模块;btrfs 本身是功能强大的文件系统,但运维踩坑的点比较多;vfs 没有任何写时复制能力,只用于测试场景。

联合文件系统带来的两个直接价值:一是存储空间节省,多个容器共享镜像层,底层数据不用重复存储;二是部署速度提升,基础镜像层已经在本地时,新容器启动不需要重新拉取完整镜像,真正需要拷贝的只有新增层。这两个价值是容器相对于传统虚拟机在交付效率上的核心优势。

最容易忽略的是写时复制机制。容器内修改一个来自底层镜像的文件时,系统先把该文件从只读层复制到可写层,再在可写层执行修改,底层镜像保持原样。多个容器即使改同一个底层文件,也不会互相影响。把写时复制、可写层、commit 保存新镜像这三件事串起来,就理解了整个镜像分层体系的运作方式。

5. 易漏易错点:容器安全、编排边界与概念混淆

5.1 易漏点:Namespace 隔离的不是“安全”

最容易被忽略也最可能在考试中被反问的,是把 Namespace 的“视图隔离”当作“安全隔离”。Namespace 让容器内的进程看不到宿主机的其他进程,但这不是权限意义上的安全隔离。

为什么漏:日常演示中,进到容器里执行ps只能看到自己的进程,给人“隔离得很好”的直观印象。怎么补:意识到所有容器共享同一个宿主机内核。一旦内核漏洞被利用,容器与容器之间、容器与宿主机之间都没有真正的安全边界。答题时凡涉及容器安全的逻辑题,第一反应都应该是“共享内核”这个事实。

5.2 易漏点:Cgroup 子系统和 Docker 参数的映射关系

第二个高频失分点是 Cgroup 子系统和 Docker 参数对不上。能写出-m限制内存,也知道--cpus限制 CPU,但被问“--cpuset-mems属于哪个子系统、解决什么问题”时容易卡壳。

为什么漏:日常使用基本只碰内存和 CPU 两个维度,cpuset、blkio 这类子系统很少触及。怎么补:把六个子系统逐个与 Docker 参数对一遍,特别是 cpu 子系统的 period/quota 组合和 memory 子系统的多参数细节,并整理到一张映射表上。掌握了“参数背后对应哪个子系统”,考试时遇到陌生参数就能通过子系统去推断它的用途。

5.3 易漏点:镜像层、可写层与 commit 的边界

第三个易错点是把镜像和容器当成同一个东西。容器运行后对所有文件的修改都发生在可写层,commit 会把可写层保存成新镜像的一层,但原镜像的每一层只读层都不会被改动。

为什么漏:容器用起来像虚拟机,容易默认“改了系统里的文件就等于改了整个系统镜像”。怎么补:记住三层结构——只读镜像层、容器可写层、临时挂载卷;可写层随容器删除而消失,需要持久化的数据应放挂载卷而不是可写层。这个知识点同时也是运维场景中的高频踩坑点。

5.4 易漏点:Kubernetes 与容器运行时的职责边界

第四点是分不清 Kubernetes 和容器运行时的关系。Kubernetes 负责编排调度,不直接运行容器;真正运行容器的是容器运行时,如 Containerd、CRI-O。Kubernetes 通过 CRI 接口与运行时通信,Kubelet 下发任务,运行时负责真正把镜像启成容器。

为什么漏:大量教程里的命令仍然是docker run,新手容易默认“Docker 就是 Kubernetes 的一部分”。怎么补:画一条请求链路——kubectl 请求到 API Server,API Server 写入状态,Kubelet 监听变化,通过 CRI 调用容器运行时,运行时启动容器。把这条链路的每一环职责标清楚,两个概念就不会混在一起。

5.5 易漏点:容器三大好处的隐含前提

容器有一条流传很广的总结——资源隔离与利用率提升、秒级弹性、环境一致性。背下来容易,但三条分别有隐含前提。资源隔离与利用率提升的前提是 Cgroup 配额设置合理,否则容器间抢占资源反而会降低稳定性;秒级弹性的前提是镜像已在本地可用,第一次从远端拉镜像的耗时不算在“秒级”里;环境一致性的前提是不可变基础设施理念被真正执行,如果镜像构建后还要登进容器改配置,一致性便无从谈起。

为什么漏:这三个好处是宣传语式的表达,很容易被当成结论直接接受。怎么补:给每条好处追加一句“它依赖什么才能成立”,例如秒级弹性依赖的是“镜像分层 + 本地缓存 + 快速启动”。复习到这个细度,容器技术这条线才算真正织成了网。

6. 复习清单:把云原生串成一张自查表

复习到这一步,需要的不再是重新看一遍资料,而是把知识网在脑内“过电影”。我常用的方式是分三层自查,每层过一遍就去对应的文档里找盲点。

第一层是概念层。合上书,能不能默写出 CNCF 云原生定义里的五个关键词,并且说出每个关键词解决什么问题、对应哪个典型项目?比如 Prometheus 是监控,CoreDNS 是服务发现,Envoy 和 Istio 构成服务网格的数据面与控制面,Notary 和 TUF 负责镜像签名。能默写下来的,说明概念层过关;写不完整的,就是补课清单。

第二层是原理层。能不能用自己的话解释 Cgroup 和 Namespace 的关系?能不能说出六个 Namespace 各自隔离了什么?能不能说明 Cgroup 的子系统与 Docker 参数之间的映射?联合文件系统为什么能让多个容器共享镜像底层?三层结构——只读镜像层、容器可写层、临时挂载卷——分别解决什么问题?这一层要求不光记住名词,而是能回答“为什么是这样”。

第三层是链路层。能不能在纸上从左到右画出完整链路:应用打包成镜像 → push 到镜像仓库 → 生产环境 pull 镜像 → 容器运行时启动容器 → Cgroup 限制资源 → Namespace 提供隔离 → Kubernetes 调度与故障自愈 → CoreDNS 发现服务 → Prometheus 监控状态 → 服务网格治理流量。每经过一个环节,写出它的输入是什么、输出是什么、依赖哪个底层机制。链路画得越顺,说明知识结构越完整;卡住的点,就是需要重看对应章节的地方。

这个三层自查法是我在某次备考时踩了坑之后才总结出来的。之前我喜欢对着大纲一遍遍从头翻,效果很差——每一条都“看着眼熟”,但合上书写不出来。从那以后,我每次复习技术笔记,都强制自己先按上述三层各过一遍,把写不出来的点集中回看,效率比从头翻资料高很多。希望这份笔记能帮你在复习云原生时少走弯路,把这张地图真正装进自己脑子里。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进