一文读懂Docker与Kubernetes从容器引擎到编排平台底层原理全解析作为云原生时代的基石Docker 与 Kubernetes 几乎成了现代软件交付的标配。但你真的了解它们的底层运作机制吗本文将从容器本质出发深入 Linux 内核的 namespace、cgroup 和联合文件系统再延伸到 Pod、调度、网络、存储等 K8s 核心原理带你构建完整知识体系。目录容器不是虚拟机Docker 底层三驾马车2.1 命名空间 (Namespace) —— 隔离的魔法2.2 控制组 (Cgroup) —— 资源的围栏2.3 联合文件系统 (UnionFS) —— 镜像分层与复用Docker 工作流程全景为什么需要 KubernetesKubernetes 架构解密5.1 控制平面与工作节点5.2 Pod最小的调度单元5.3 声明式 API 与控制循环Kubernetes 核心底层原理6.1 调度器如何做决策6.2 网络模型与 CNI6.3 持久化存储与 CSI从 Docker 到 K8s协作关系演变总结与学习建议1. 容器不是虚拟机很多人刚接触容器时会把它类比为“轻量级虚拟机”。这个说法不够准确。虚拟机通过 Hypervisor 模拟完整硬件每个虚拟机拥有独立的内核、操作系统隔离性强但资源开销大。容器直接运行在宿主机内核上通过 Linux 内核特性实现进程级别的隔离和资源限制启动时间可以达到毫秒级单机可运行成百上千个容器。理解容器必须回到 Linux 内核的三大机制Namespace、Cgroup 和 UnionFS。2. Docker 底层三驾马车Docker 本身是容器运行时和管理工具它把底层技术包装成易用的命令行和 API。真正干活的是内核特性。2.1 命名空间 (Namespace) —— 隔离的魔法Namespace 让一组进程“以为自己独占系统”实际上彼此不可见。Linux 内核提供 8 种命名空间命名空间类型隔离内容作用Mount文件系统挂载点容器拥有独立根文件系统PID进程编号容器内进程 PID1 看不到外部进程Network网络设备、IP、端口容器可拥有独立网卡和 IPIPC消息队列、信号量防止进程间通信干扰UTS主机名和域名容器可设置自己的 hostnameUser用户和用户组允许非 root 用户映射CgroupCgroup 根目录视图限制容器只能看到自己的资源限制Time系统时间 (较新内核)容器可有独立系统时间当你执行docker runDocker 会创建一组新的 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) —— 资源的围栏Cgroupcontrol group负责限制、审计和隔离进程组使用的物理资源CPU、内存、磁盘 I/O、网络等。没有 Cgroup一个容器可能耗尽宿主机资源。关键子系统cpu限制 CPU 使用率 (--cpus--cpu-shares)memory限制内存使用达到上限触发 OOM Killblkio限制磁盘 I/Onet_cls标记网络包配合流量控制devices控制设备访问权限Docker 命令示例bashdocker run -d --memory256m --cpus1.5 myapp这背后实际是往/sys/fs/cgroup/目录下的对应子系统目录里写入限制值。Cgroup v2 进一步统一了层级结构简化管理。2.3 联合文件系统 (UnionFS) —— 镜像分层与复用Docker 镜像为何能快速分发、分层构建答案就是联合文件系统如 OverlayFS、AUFS 等。它将多个目录层挂载为单一视图。最下层是只读的镜像层最上层是可写的容器层。写时复制Copy-on-Write当容器修改只读层的文件时联合文件系统会先将文件复制到可写层再修改。删除文件则通过“白out文件”标记隐藏。典型 Overlay2 结构textoverlay2 ├── lower (镜像层可多层只读) ├── upper (容器层读写) ├── merged (统一视图) └── work (内部工作目录)这种分层技术使镜像构建缓存复用、启动容器极快、存储占用小。开发者常写的 Dockerfile 中每一行指令就会产生一个新层。3. Docker 工作流程全景整体架构可以分为Docker 客户端(dockerCLI) 通过 REST API 与守护进程通信。Docker 守护进程(dockerd) 负责构建、运行、管理容器。containerd管理容器生命周期拉取镜像、创建容器、管理存储网络。runc是最终的容器运行时基于 OCI 标准使用 libcontainer 直接与内核打交道创建 namespace、cgroup 等。一个docker run命令背后大致流程CLI 发送请求到 dockerddockerd 调用 containerd 启动容器containerd 转化成 runc 能理解的 OCI bundlerunc 创建容器进程、设置 namespace、cgroup、mount rootfs容器启动进程完成隔离4. 为什么需要 Kubernetes单机 Docker 可以打包应用、隔离环境但生产环境中必须解决多主机调度哪个机器有资源跑新容器服务发现与负载均衡容器 IP 会变如何自动注册与发现滚动更新与回滚不停机更新版本。健康检查与自动修复挂掉的容器自动重启。配置和密钥管理不改镜像而更新配置。KubernetesK8s正是为了解决大规模容器编排问题而生。它借鉴了 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 Looptextfor { 实际状态 : 观察集群当前状态 期望状态 : 从 API 对象读取 spec if 实际状态 ! 期望状态 { 执行操作使实际状态趋向期望状态 } }每个控制器如 Deployment、ReplicaSet都是一个独立的控制循环它们监听特定资源变化持续驱动系统向用户声明的目标收敛。6. Kubernetes 核心底层原理6.1 调度器如何做决策kube-scheduler 负责把未调度的 Pod 绑定到合适的 Node。主要流程过滤Predicates剔除不满足条件的节点资源不足、节点选择器不符、污点容忍等。打分Priorities对剩余节点按策略打分如资源均衡度、镜像本地化等选出最优。调度器是可插拔的你可以自定义调度策略。6.2 网络模型与 CNIK8s 网络要求所有 Pod 可以直接通信无需 NAT节点可以与 Pod 通信Pod 看到的 IP 与其他 Pod 看到的 IP 一致。这并非 Docker 默认网络能实现。CNI (Container Network Interface)定义容器网络插件标准。常见实现Flannel简单 overlay通过 VXLAN 或 host-gwCalico基于 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 内核的强大能力抽象成开发者友好的工具。掌握底层原理不仅能从容应对故障排查还能更好地设计云原生应用。进阶建议手动用unshare、cgroup创建容器加深理解。阅读runc源码中 namespace 设置部分。研究一个 CNI 插件的工作原理。部署一个多节点 K8s 集群并观察控制循环日志。容器技术仍在快速演进eBPF、WebAssembly 等新技术不断融入但 Namespace、Cgroup、UnionFS 始终是根基。打好底层基础才能无惧技术变革。本文深入介绍了 Docker 和 Kubernetes 的底层技术原理如果对你有帮助欢迎点赞、收藏、转发也欢迎在评论区讨论你的见解
一文读懂Docker与Kubernetes:从容器引擎到编排平台,底层原理全解析
一文读懂Docker与Kubernetes从容器引擎到编排平台底层原理全解析作为云原生时代的基石Docker 与 Kubernetes 几乎成了现代软件交付的标配。但你真的了解它们的底层运作机制吗本文将从容器本质出发深入 Linux 内核的 namespace、cgroup 和联合文件系统再延伸到 Pod、调度、网络、存储等 K8s 核心原理带你构建完整知识体系。目录容器不是虚拟机Docker 底层三驾马车2.1 命名空间 (Namespace) —— 隔离的魔法2.2 控制组 (Cgroup) —— 资源的围栏2.3 联合文件系统 (UnionFS) —— 镜像分层与复用Docker 工作流程全景为什么需要 KubernetesKubernetes 架构解密5.1 控制平面与工作节点5.2 Pod最小的调度单元5.3 声明式 API 与控制循环Kubernetes 核心底层原理6.1 调度器如何做决策6.2 网络模型与 CNI6.3 持久化存储与 CSI从 Docker 到 K8s协作关系演变总结与学习建议1. 容器不是虚拟机很多人刚接触容器时会把它类比为“轻量级虚拟机”。这个说法不够准确。虚拟机通过 Hypervisor 模拟完整硬件每个虚拟机拥有独立的内核、操作系统隔离性强但资源开销大。容器直接运行在宿主机内核上通过 Linux 内核特性实现进程级别的隔离和资源限制启动时间可以达到毫秒级单机可运行成百上千个容器。理解容器必须回到 Linux 内核的三大机制Namespace、Cgroup 和 UnionFS。2. Docker 底层三驾马车Docker 本身是容器运行时和管理工具它把底层技术包装成易用的命令行和 API。真正干活的是内核特性。2.1 命名空间 (Namespace) —— 隔离的魔法Namespace 让一组进程“以为自己独占系统”实际上彼此不可见。Linux 内核提供 8 种命名空间命名空间类型隔离内容作用Mount文件系统挂载点容器拥有独立根文件系统PID进程编号容器内进程 PID1 看不到外部进程Network网络设备、IP、端口容器可拥有独立网卡和 IPIPC消息队列、信号量防止进程间通信干扰UTS主机名和域名容器可设置自己的 hostnameUser用户和用户组允许非 root 用户映射CgroupCgroup 根目录视图限制容器只能看到自己的资源限制Time系统时间 (较新内核)容器可有独立系统时间当你执行docker runDocker 会创建一组新的 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) —— 资源的围栏Cgroupcontrol group负责限制、审计和隔离进程组使用的物理资源CPU、内存、磁盘 I/O、网络等。没有 Cgroup一个容器可能耗尽宿主机资源。关键子系统cpu限制 CPU 使用率 (--cpus--cpu-shares)memory限制内存使用达到上限触发 OOM Killblkio限制磁盘 I/Onet_cls标记网络包配合流量控制devices控制设备访问权限Docker 命令示例bashdocker run -d --memory256m --cpus1.5 myapp这背后实际是往/sys/fs/cgroup/目录下的对应子系统目录里写入限制值。Cgroup v2 进一步统一了层级结构简化管理。2.3 联合文件系统 (UnionFS) —— 镜像分层与复用Docker 镜像为何能快速分发、分层构建答案就是联合文件系统如 OverlayFS、AUFS 等。它将多个目录层挂载为单一视图。最下层是只读的镜像层最上层是可写的容器层。写时复制Copy-on-Write当容器修改只读层的文件时联合文件系统会先将文件复制到可写层再修改。删除文件则通过“白out文件”标记隐藏。典型 Overlay2 结构textoverlay2 ├── lower (镜像层可多层只读) ├── upper (容器层读写) ├── merged (统一视图) └── work (内部工作目录)这种分层技术使镜像构建缓存复用、启动容器极快、存储占用小。开发者常写的 Dockerfile 中每一行指令就会产生一个新层。3. Docker 工作流程全景整体架构可以分为Docker 客户端(dockerCLI) 通过 REST API 与守护进程通信。Docker 守护进程(dockerd) 负责构建、运行、管理容器。containerd管理容器生命周期拉取镜像、创建容器、管理存储网络。runc是最终的容器运行时基于 OCI 标准使用 libcontainer 直接与内核打交道创建 namespace、cgroup 等。一个docker run命令背后大致流程CLI 发送请求到 dockerddockerd 调用 containerd 启动容器containerd 转化成 runc 能理解的 OCI bundlerunc 创建容器进程、设置 namespace、cgroup、mount rootfs容器启动进程完成隔离4. 为什么需要 Kubernetes单机 Docker 可以打包应用、隔离环境但生产环境中必须解决多主机调度哪个机器有资源跑新容器服务发现与负载均衡容器 IP 会变如何自动注册与发现滚动更新与回滚不停机更新版本。健康检查与自动修复挂掉的容器自动重启。配置和密钥管理不改镜像而更新配置。KubernetesK8s正是为了解决大规模容器编排问题而生。它借鉴了 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 Looptextfor { 实际状态 : 观察集群当前状态 期望状态 : 从 API 对象读取 spec if 实际状态 ! 期望状态 { 执行操作使实际状态趋向期望状态 } }每个控制器如 Deployment、ReplicaSet都是一个独立的控制循环它们监听特定资源变化持续驱动系统向用户声明的目标收敛。6. Kubernetes 核心底层原理6.1 调度器如何做决策kube-scheduler 负责把未调度的 Pod 绑定到合适的 Node。主要流程过滤Predicates剔除不满足条件的节点资源不足、节点选择器不符、污点容忍等。打分Priorities对剩余节点按策略打分如资源均衡度、镜像本地化等选出最优。调度器是可插拔的你可以自定义调度策略。6.2 网络模型与 CNIK8s 网络要求所有 Pod 可以直接通信无需 NAT节点可以与 Pod 通信Pod 看到的 IP 与其他 Pod 看到的 IP 一致。这并非 Docker 默认网络能实现。CNI (Container Network Interface)定义容器网络插件标准。常见实现Flannel简单 overlay通过 VXLAN 或 host-gwCalico基于 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 内核的强大能力抽象成开发者友好的工具。掌握底层原理不仅能从容应对故障排查还能更好地设计云原生应用。进阶建议手动用unshare、cgroup创建容器加深理解。阅读runc源码中 namespace 设置部分。研究一个 CNI 插件的工作原理。部署一个多节点 K8s 集群并观察控制循环日志。容器技术仍在快速演进eBPF、WebAssembly 等新技术不断融入但 Namespace、Cgroup、UnionFS 始终是根基。打好底层基础才能无惧技术变革。本文深入介绍了 Docker 和 Kubernetes 的底层技术原理如果对你有帮助欢迎点赞、收藏、转发也欢迎在评论区讨论你的见解