news 2026/7/29 15:59:31

一文读懂Docker与Kubernetes:从容器引擎到编排平台,底层原理全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文读懂Docker与Kubernetes:从容器引擎到编排平台,底层原理全解析

一文读懂Docker与Kubernetes:从容器引擎到编排平台,底层原理全解析

作为云原生时代的基石,Docker 与 Kubernetes 几乎成了现代软件交付的标配。但你真的了解它们的底层运作机制吗?本文将从容器本质出发,深入 Linux 内核的 namespace、cgroup 和联合文件系统,再延伸到 Pod、调度、网络、存储等 K8s 核心原理,带你构建完整知识体系。


目录

  1. 容器不是虚拟机

  2. Docker 底层三驾马车

    • 2.1 命名空间 (Namespace) —— 隔离的魔法

    • 2.2 控制组 (Cgroup) —— 资源的围栏

    • 2.3 联合文件系统 (UnionFS) —— 镜像分层与复用

  3. Docker 工作流程全景

  4. 为什么需要 Kubernetes?

  5. Kubernetes 架构解密

    • 5.1 控制平面与工作节点

    • 5.2 Pod:最小的调度单元

    • 5.3 声明式 API 与控制循环

  6. Kubernetes 核心底层原理

    • 6.1 调度器如何做决策

    • 6.2 网络模型与 CNI

    • 6.3 持久化存储与 CSI

  7. 从 Docker 到 K8s:协作关系演变

  8. 总结与学习建议


1. 容器不是虚拟机

很多人刚接触容器时,会把它类比为“轻量级虚拟机”。这个说法不够准确。

虚拟机通过 Hypervisor 模拟完整硬件,每个虚拟机拥有独立的内核、操作系统,隔离性强但资源开销大。
容器直接运行在宿主机内核上,通过 Linux 内核特性实现进程级别的隔离和资源限制,启动时间可以达到毫秒级,单机可运行成百上千个容器。

理解容器,必须回到 Linux 内核的三大机制:Namespace、Cgroup 和 UnionFS。


2. Docker 底层三驾马车

Docker 本身是容器运行时和管理工具,它把底层技术包装成易用的命令行和 API。真正干活的是内核特性。

2.1 命名空间 (Namespace) —— 隔离的魔法

Namespace 让一组进程“以为自己独占系统”,实际上彼此不可见。Linux 内核提供 8 种命名空间:

命名空间类型隔离内容作用
Mount文件系统挂载点容器拥有独立根文件系统
PID进程编号容器内进程 PID=1 看不到外部进程
Network网络设备、IP、端口容器可拥有独立网卡和 IP
IPC消息队列、信号量防止进程间通信干扰
UTS主机名和域名容器可设置自己的 hostname
User用户和用户组允许非 root 用户映射
CgroupCgroup 根目录视图限制容器只能看到自己的资源限制
Time系统时间 (较新内核)容器可有独立系统时间

当你执行docker run,Docker 会创建一组新的 namespace,把容器进程放进去,实现隔离。

动手体验:在宿主机查看容器内进程

bash

# 查看宿主机上的 PID 命名空间隔离 docker run -d --name test nginx # 容器内查看 nginx 的 PID 是 1 docker exec test ps aux # 回到宿主机查看真实 PID ps aux | grep nginx # 发现 PID 完全不同

2.2 控制组 (Cgroup) —— 资源的围栏

Cgroup(control group)负责限制、审计和隔离进程组使用的物理资源(CPU、内存、磁盘 I/O、网络等)。没有 Cgroup,一个容器可能耗尽宿主机资源。

关键子系统:

  • cpu:限制 CPU 使用率 (--cpus--cpu-shares)

  • memory:限制内存使用,达到上限触发 OOM Kill

  • blkio:限制磁盘 I/O

  • net_cls:标记网络包,配合流量控制

  • devices:控制设备访问权限

Docker 命令示例:

bash

docker run -d --memory="256m" --cpus="1.5" myapp

这背后实际是往/sys/fs/cgroup/目录下的对应子系统目录里写入限制值。Cgroup v2 进一步统一了层级结构,简化管理。

2.3 联合文件系统 (UnionFS) —— 镜像分层与复用

Docker 镜像为何能快速分发、分层构建?答案就是联合文件系统(如 OverlayFS、AUFS 等)。

它将多个目录(层)挂载为单一视图。最下层是只读的镜像层,最上层是可写的容器层。

写时复制(Copy-on-Write):当容器修改只读层的文件时,联合文件系统会先将文件复制到可写层,再修改。删除文件则通过“白out文件”标记隐藏。

典型 Overlay2 结构:

text

overlay2 ├── lower (镜像层,可多层,只读) ├── upper (容器层,读写) ├── merged (统一视图) └── work (内部工作目录)

这种分层技术使镜像构建缓存复用、启动容器极快、存储占用小。开发者常写的 Dockerfile 中每一行指令就会产生一个新层。


3. Docker 工作流程全景

整体架构可以分为:

  1. Docker 客户端(dockerCLI) 通过 REST API 与守护进程通信。

  2. Docker 守护进程(dockerd) 负责构建、运行、管理容器。

  3. containerd管理容器生命周期(拉取镜像、创建容器、管理存储网络)。

  4. runc是最终的容器运行时,基于 OCI 标准,使用 libcontainer 直接与内核打交道,创建 namespace、cgroup 等。

一个docker run命令背后大致流程:

  • CLI 发送请求到 dockerd

  • dockerd 调用 containerd 启动容器

  • containerd 转化成 runc 能理解的 OCI bundle

  • runc 创建容器进程、设置 namespace、cgroup、mount rootfs

  • 容器启动,进程完成隔离


4. 为什么需要 Kubernetes?

单机 Docker 可以打包应用、隔离环境,但生产环境中必须解决:

  • 多主机调度:哪个机器有资源跑新容器?

  • 服务发现与负载均衡:容器 IP 会变,如何自动注册与发现?

  • 滚动更新与回滚:不停机更新版本。

  • 健康检查与自动修复:挂掉的容器自动重启。

  • 配置和密钥管理:不改镜像而更新配置。

Kubernetes(K8s)正是为了解决大规模容器编排问题而生。它借鉴了 Google 内部 Borg 系统的经验,构建在声明式 API 和控制循环之上。


5. Kubernetes 架构解密

5.1 控制平面与工作节点

K8s 集群分为:

  • Control Plane:大脑,管理集群状态

    • kube-apiserver:统一入口,RESTful API 网关

    • etcd:持久化存储所有集群数据(键值数据库)

    • kube-scheduler:决定 Pod 分配到哪个节点

    • kube-controller-manager:运行各种控制器(副本、节点等)

  • Worker Node:运行工作负载

    • kubelet:节点代理,负责与 apiserver 通信,管理本机容器

    • kube-proxy:实现 Service 网络代理和负载均衡

    • 容器运行时(containerd、CRI-O 等):运行容器

5.2 Pod:最小的调度单元

Kubernetes 不直接管理容器,而是管理Pod。Pod 是一组共享网络和存储命名空间的容器集合。
同一个 Pod 内的容器可以通过localhost通信,共享 Volume。设计模式上,Pod 常用于“边车”模式,如主容器+日志收集容器。

Pod 的底层实现原理
Kubelet 在启动 Pod 时,会先创建一个infra 容器(也叫 pause 容器),它负责创建并持有 Network Namespace。然后业务容器加入这个命名空间,从而共享同一个网络栈,因此看到相同的 IP 和端口空间。

5.3 声明式 API 与控制循环

不同于命令式操作(一步步告诉怎么做),K8s 采用声明式:你提交期望状态(yaml),由控制器调谐到该状态。

核心机制是控制循环(Control Loop):

text

for { 实际状态 := 观察集群当前状态 期望状态 := 从 API 对象读取 spec if 实际状态 != 期望状态 { 执行操作使实际状态趋向期望状态 } }

每个控制器(如 Deployment、ReplicaSet)都是一个独立的控制循环,它们监听特定资源变化,持续驱动系统向用户声明的目标收敛。


6. Kubernetes 核心底层原理

6.1 调度器如何做决策

kube-scheduler 负责把未调度的 Pod 绑定到合适的 Node。主要流程:

  1. 过滤(Predicates)
    剔除不满足条件的节点:资源不足、节点选择器不符、污点容忍等。

  2. 打分(Priorities)
    对剩余节点按策略打分(如资源均衡度、镜像本地化等),选出最优。

调度器是可插拔的,你可以自定义调度策略。

6.2 网络模型与 CNI

K8s 网络要求:所有 Pod 可以直接通信,无需 NAT;节点可以与 Pod 通信;Pod 看到的 IP 与其他 Pod 看到的 IP 一致。这并非 Docker 默认网络能实现。

CNI (Container Network Interface)定义容器网络插件标准。常见实现:

  • Flannel:简单 overlay,通过 VXLAN 或 host-gw

  • Calico:基于 BGP 的三层网络,支持网络策略

  • Cilium:基于 eBPF,高性能且具备可观测性

Service 的底层实现
ClusterIP Service 本质是一个虚拟 IP,由 kube-proxy 在节点上设置 iptables 或 IPVS 规则,将 Service IP + Port 的流量负载均衡到后端 Pod。

例如,使用 iptables 模式,访问 ClusterIP 时,规则做 DNAT 转换到随机选中的 Pod IP。这也解释了为什么 Service IP ping 不通,因为它没有真正绑定网卡。

6.3 持久化存储与 CSI

容器本身是无状态的,Pod 销毁数据消失。K8s 通过Volume解决持久化。除了简单的 emptyDir、hostPath,最常用的是PV (PersistentVolume) / PVC (PersistentVolumeClaim)体系。

  • PV:管理员或 StorageClass 动态创建的集群存储资源(如云盘)

  • PVC:用户声明的存储需求(大小、访问模式)

  • 绑定后,Pod 引用 PVC,就可以挂载持久化存储。

底层依赖CSI (Container Storage Interface)驱动,实现对不同存储系统的统一接入(AWS EBS、Ceph、NFS 等)。挂载过程涉及 Attach(将远程卷关联到节点)、Mount(挂载到容器内文件系统)两步,由 kubelet 与 CSI 插件协作完成。


7. 从 Docker 到 K8s:协作关系演变

早期 Kubernetes 直接内置 Docker 支持,后来抽象出CRI (Container Runtime Interface)标准,让任何符合 CRI 的运行时都可接入。由于 Docker 本身的臃肿(包含 dockerd、containerd 链太长),社区转向更精简的运行时。

containerd目前是 kubelet 默认的 CRI 实现,它还直接兼容 OCI 镜像。从用户角度看,依然可以用docker build构建镜像,K8s 能直接使用。

这条链路体现了分层解耦的思想:
Docker CLI → dockerd → containerd → runc → 容器进程
在 Kubernetes 中变为:
kubelet → CRI plugin (containerd) → runc → 容器进程


8. 总结与学习建议

Docker 和 Kubernetes 的成功,源于它们巧妙地将 Linux 内核的强大能力抽象成开发者友好的工具。掌握底层原理,不仅能从容应对故障排查,还能更好地设计云原生应用。

进阶建议

  • 手动用unsharecgroup创建容器,加深理解。

  • 阅读runc源码中 namespace 设置部分。

  • 研究一个 CNI 插件的工作原理。

  • 部署一个多节点 K8s 集群并观察控制循环日志。

容器技术仍在快速演进,eBPF、WebAssembly 等新技术不断融入,但 Namespace、Cgroup、UnionFS 始终是根基。打好底层基础,才能无惧技术变革。


本文深入介绍了 Docker 和 Kubernetes 的底层技术原理,如果对你有帮助,欢迎点赞、收藏、转发,也欢迎在评论区讨论你的见解!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 15:58:47

角色塑造实战:从人物小传到个性展示的三大支柱框架

1. 项目概述:从“角色塑造”到“个性展示”的课程设计 最近在筹备一个关于角色塑造的系列课程,第一期的主题就定为“展示角色的个性”。这个想法源于我过去几年在内容创作、剧本写作以及游戏叙事设计中的反复实践与观察。我发现,无论是写一个…

作者头像 李华
网站建设 2026/7/29 15:58:30

践行金融惠民责任——金融赋能省运盛会,建行惠民燃动好心茂名

近日,广东省第十七届运动会在茂名火热开赛,全省运动健儿齐聚好心之城,同台竞技、逐梦赛场。为积极响应省运盛会氛围,践行金融惠民、服务民生的社会责任,建设银行广东省茂名市分行依托赛事场景、深耕本土服务&#xff0…

作者头像 李华
网站建设 2026/7/29 15:58:11

SpringBoot+Vue共享单车管理系统开发实践

1. 项目概述:共享单车管理系统的技术实现方案 这个共享单车管理系统是我去年带队完成的一个校企合作项目,当时为本地共享单车运营商解决了车辆调度混乱、用户投诉率高的问题。系统采用现在主流的前后端分离架构,后端用SpringBoot实现业务逻辑…

作者头像 李华
网站建设 2026/7/29 15:57:43

k6压测中思考时间如何导致TPS瓶颈:从原理到排查实战

1. 项目概述:当TPS曲线“躺平”,问题可能出在“思考”上 最近在做一个电商大促活动的全链路压测,用k6模拟用户下单流程。脚本设计上,我采用了Ramping VUs(渐进式虚拟用户)场景,期望随着用户数稳…

作者头像 李华