前言

刚接触 K8s(Kubernetes)的小伙伴大概率会有这样的困惑:K8s 动辄提及的 “容器隔离”“资源限制”,到底是靠什么技术实现的?为什么部署 K8s 集群必须用 Linux 系统,Windows 或 macOS 只能做开发调试?

其实答案很简单:K8s 就像一套功能强大的港口智能管理系统,而 Linux 就是支撑这个港口的地基与核心设施。没有 Linux 内核提供的底层能力,K8s 的所有容器管理、资源调度功能都无从谈起。今天这篇文章就从通俗比喻入手,拆解 K8s 与 Linux 的共生关系,再通过实操实验让你直观感受底层原理,最后用架构图理清完整链路。

一、通俗理解:集装箱、港口与地基的关系

要搞懂 K8s 和 Linux 的关系,咱们先从生活中的 “集装箱港口” 说起:

角色对应技术核心作用
集装箱容器(Docker/containerd)标准化封装应用及依赖,像集装箱一样统一规格,方便搬运和部署
港口管理系统K8s调度集装箱(容器)的存放位置、运输路线,监控集装箱状态,处理异常情况
港口地基 + 基础设施(货轮、起重机、公路)Linux 内核提供集装箱存放的物理空间(服务器资源),以及标准化的 “约束规则”,确保集装箱之间互不干扰,资源使用可控

举个具体的例子:当你在 K8s 中创建一个 Pod 时,就像港口收到一批集装箱。K8s 负责决定这批集装箱放在哪个泊位(节点)、用哪台起重机(调度器)卸载,但真正让这批集装箱 “安稳待着” 且不影响其他集装箱的,是 Linux 提供的隔离机制;限制这批集装箱占用多少场地(CPU / 内存)的,是 Linux 的资源控制机制。

没有 Linux 这套 “基础设施”,K8s 就是一个空架子,根本无法实现对容器的有效管理。

二、核心原理:K8s 依赖的 2 个 Linux 内核 “黑科技”

K8s 本身不具备虚拟化和资源隔离能力,它所有的容器化相关功能,都依赖 Linux 内核的命名空间(Namespaces) 和控制组(Control Groups,简称 cgroups) 这两大核心机制。这两个机制就像 Linux 给容器打造的 “专属牢笼”—— 既让容器里的应用觉得自己独占一台机器,又能限制它不能 “胡作非为” 占用过多资源。

2.1 命名空间(Namespaces):容器的 “隔离结界”

命名空间的核心作用是隔离,它会为容器创建一个独立的 “虚拟环境”,让容器内的进程看不到宿主机和其他容器的资源。就像给每个容器拉了一道看不见的结界,彼此互不干扰。

Linux 内核提供了 6 种关键命名空间,分别负责不同维度的隔离,具体如下:

命名空间类型隔离对象通俗说明K8s 中的作用
PID Namespace进程 ID容器内的进程有独立的 PID 编号,比如容器内的/bin/sh可能是 PID=1,但在宿主机上是另一个普通 PID避免容器内进程与宿主机 / 其他容器进程 ID 冲突,让容器内应用认为自己是独占系统
Network Namespace网络栈容器有独立的网卡、IP 地址、端口和路由表实现 Pod 间网络隔离,K8s 的 Service、Ingress 等网络功能都基于此实现
Mount Namespace文件系统挂载点容器有自己独立的文件目录结构,比如/etc /var等目录与宿主机隔离保证容器内应用依赖的文件环境独立,避免不同应用文件冲突
UTS Namespace主机名和域名容器可以设置自己的主机名,与宿主机无关让 Pod 拥有独立的主机名,满足应用对主机名的依赖需求
IPC Namespace进程间通信容器内的 IPC 通信(如信号量、消息队列)只能在容器内进行隔离不同容器的进程通信,提升安全性
User Namespace用户和用户组 ID容器内的 root 用户,在宿主机上可能只是普通用户限制容器内用户的权限,防止容器内恶意程序获取宿主机高权限

简单来说,Namespaces 让容器实现了 “看起来像一台独立电脑” 的效果。

2.2 控制组(cgroups):容器的 “资源枷锁”

光有隔离还不够,如果某个容器的应用疯狂占用 CPU 和内存,很可能导致宿主机和其他容器崩溃。而 cgroups 的核心作用就是限制、记录和隔离进程组对系统资源的使用,相当于给容器戴上 “资源枷锁”。

cgroups 支持对多种系统资源进行精细化控制,核心功能如下:

  1. 资源限制:比如限制某个容器最多使用 2 核 CPU、4GB 内存,避免资源滥用;
  2. 资源统计:统计容器使用的 CPU 时长、内存占用量等,为 K8s 调度提供数据依据;
  3. 优先级分配:给核心业务的容器分配更高的 CPU 优先级,确保核心服务稳定运行;
  4. 资源控制:比如限制容器的磁盘 IO 速率、网络带宽等。

在 K8s 中,当你通过resources.limitsresources.requests配置 Pod 的资源时:

yaml

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
  - name: demo-container
    image: busybox
    resources:
      limits:    # 资源上限
        cpu: "2"
        memory: "4Gi"
      requests:  # 调度时的资源请求
        cpu: "1"
        memory: "2Gi"

K8s 最终会将这些配置转化为 Linux cgroups 的规则,写入宿主机的/sys/fs/cgroup目录下(cgroups 的配置目录),由 Linux 内核强制执行这些资源限制。

三、动手实验:亲手揭开容器的 “真面目”

看完原理可能还是有点抽象,咱们通过一个简单实验,直观感受容器的本质 ——容器本质上就是宿主机上被 Namespaces 和 cgroups 限制的普通进程

3.1 实验准备

  • 环境:CentOS 9/RHEL 9(其他 Linux 发行版也可)
  • 工具:已安装 Docker 或 Podman(这里以 Docker 为例)

3.2 实验步骤

步骤 1:启动一个容器

打开第一个终端,运行一个 busybox 容器,并进入容器的交互终端:

bash

# 启动busybox容器,进入/bin/sh交互模式
docker run -it busybox /bin/sh

此时你会进入容器的命令行界面,输入ps命令查看容器内的进程:

bash

# 容器内执行ps,查看进程
ps

预期结果:容器内只会显示一个PID=1/bin/sh进程,这就是容器的初始化进程,容器内的进程视角是独立的。

步骤 2:在宿主机查找容器对应的真实进程

打开第二个终端,不要关闭第一个容器终端,执行以下命令查找容器对应的宿主机进程:

bash

# 查找/bin/sh相关的进程,排除grep自身进程
ps aux | grep /bin/sh | grep -v grep

预期结果:会输出一条类似如下的进程信息:

plaintext

root      12345  0.0  0.0   1234  5678 pts/0    Ss+  10:00   0:00 /bin/sh

这里的12345就是容器进程在宿主机上的真实 PID。

步骤 3:验证进程的 cgroups 限制

咱们再进一步,查看这个进程的 cgroups 配置,验证资源限制:

bash

# 替换12345为上一步查到的真实PID
cat /proc/12345/cgroup

预期结果:会输出该进程所属的 cgroups 分组,比如:

plaintext

12:devices:/docker/abcdef123456...
11:cpuset:/docker/abcdef123456...
10:memory:/docker/abcdef123456...

这些路径对应 Docker 为该容器创建的专属 cgroups 分组,所有资源限制都会通过这些分组生效。

3.3 实验结论

这个实验清晰地证明了:容器并不是什么 “虚拟机器”,而是宿主机上一个被 Namespaces 隔离、被 cgroups 限制资源的普通进程。而这一切底层能力,都是 Linux 内核提供的,K8s 只是调用和管理这些能力的 “上层管理者”。

四、架构图解:K8s Pod 运行时的 Linux 内核调用链路

当你在 K8s 中创建一个 Pod 时,请求会从上到下贯穿 K8s 组件和 Linux 内核,下面用一张架构图(Mermaid 语法,CSDN 支持直接渲染)展示完整链路:

链路详细说明

  1. 用户发起请求:通过kubectl run命令创建 Pod,请求发送到 K8s 的核心组件 kube-apiserver;
  2. 调度决策:kube-apiserver 将请求转发给 kube-scheduler,kube-scheduler 根据节点资源情况,选择一个合适的节点;
  3. 节点执行:目标节点的 kubelet 接收到调度指令,调用容器运行时(如 containerd);
  4. 内核能力调用:容器运行时向 Linux 内核发送请求,同时创建对应的 Namespaces 和 cgroups 规则;
  5. Pod 启动:Linux 内核根据规则创建一个受限进程,Pod 内的应用就在这个进程中运行,最终完成 Pod 启动。

从这个链路能看出,K8s 的所有容器管理操作,最终都会落到 Linux 内核的两个核心机制上。没有 Linux,K8s 就失去了运行的 “土壤”。

五、延伸思考:为什么 Windows/macOS 不能部署 K8s 集群?

看到这里你可能会问,那 Windows 和 macOS 上也能装 Docker 运行容器,为什么不能部署 K8s 集群?

答案很简单:Windows 和 macOS 上的容器本质是通过虚拟机模拟的 Linux 环境运行的。比如 macOS 的 Docker Desktop,会在后台启动一个 Linux 虚拟机,所有容器其实都运行在这个虚拟机里;Windows 则是通过 WSL2(Windows 子系统)提供 Linux 内核环境。

这种模拟环境性能有限,且无法像原生 Linux 那样提供完整的内核能力,因此只能用于开发调试,无法支撑生产环境的 K8s 集群运行。这也从侧面印证了 K8s 对 Linux 原生环境的依赖。

总结

回到文章开头的问题:为什么说 Linux 是 K8s 的土壤?

因为 K8s 赖以生存的容器隔离(Namespaces)、资源控制(cgroups)等核心能力,都源于 Linux 内核的底层支撑。K8s 就像一个功能强大的 “驾驶舱”,而 Linux 是提供动力的 “发动机”,没有发动机,再先进的驾驶舱也无法让车辆行驶。

理解了这层关系,你在后续学习 K8s 的调度、网络、存储等高级功能时,就能更轻松地看透底层逻辑 —— 很多 K8s 的高级特性,本质上都是对 Linux 内核能力的封装和扩展。

下一篇文章,我们将基于这个基础,动手搭建 K8s 集群,并深入分析 K8s 如何通过 Linux 内核参数优化集群性能,感兴趣的小伙伴可以点赞收藏,避免迷路~

配套资源

  1. Docker 安装脚本:
  2. curl -fsSL https://get.docker.com -o get-docker.sh
  3.  sudo sh get-docker.sh

更多推荐