予枫个人主页 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 Debug 这个世界Return 更好的自己引言作为Linux程序员你一定听过Namespace和Cgroups——它们是Docker、K8s等容器技术的底层基石也是面试中高频被问的核心考点。很多人只会用容器却搞不懂“容器为什么能隔离资源”“如何限制容器的CPU和内存”甚至把Namespace和Cgroups混为一谈。今天就带大家从底层拆解用通俗的语言极简实操吃透Namespace隔离、Cgroups限制、UnionFS分层存储的核心逻辑帮你夯实Linux进阶基础面试不慌、工作不踩坑文章目录引言一、开篇认知为什么要学Namespace与Cgroups二、NamespaceLinux的“环境隔离神器”2.1 什么是Namespace2.2 常见的Namespace类型重点掌握4种2.2.1 PID Namespace进程ID隔离2.2.2 Net Namespace网络环境隔离2.2.3 Mount Namespace文件系统挂载隔离2.2.4 User Namespace用户和组ID隔离2.3 Namespace的核心特点三、CgroupsLinux的“资源限制工具”3.1 什么是Cgroups3.2 Cgroups的核心功能3.3 Cgroups实操限制进程的CPU和内存极简上手3.3.1 CPU限制实操3.3.2 内存限制实操3.4 Cgroups的核心特点四、UnionFS容器的“分层存储基石”4.1 什么是UnionFS4.2 UnionFS的核心原理分层叠加4.3 常见的UnionFS变体Docker常用五、总结Namespace、Cgroups与UnionFS的协同关系一、开篇认知为什么要学Namespace与Cgroups很多小伙伴入门Linux后很快就会接触到容器技术但大多停留在“docker run”的表层使用对其底层实现一知半解。其实容器之所以能实现“轻量级虚拟化”核心就是靠「Namespace」做环境隔离「Cgroups」做资源限制再加上「UnionFS」做分层存储——三者协同才让容器既有虚拟机的隔离性又有远超虚拟机的轻量性。举个通俗的例子如果把Linux系统比作一栋大楼Namespace就是给这栋大楼划分出多个独立的“套房”每个套房里的住户进程只能看到自己套房里的环境PID、网络、文件系统等看不到其他套房Cgroups就是给每个套房设定“资源配额”比如限制每个套房只能用1颗CPU、2G内存避免某一户过度占用资源影响其他人UnionFS则是给每个套房提供“灵活的存储方案”可以按需叠加、复用存储资源节省空间。对于程序员来说吃透这三个技术不仅能轻松理解容器的底层逻辑在排查进程隔离、资源泄露等问题时也能事半功倍更能在面试中脱颖而出毕竟这是中高级Linux工程师的必备知识点。记得点赞收藏跟着文章一步步拆解看完就能上手实操二、NamespaceLinux的“环境隔离神器”2.1 什么是NamespaceNamespace是Linux内核提供的一种「资源隔离机制」它的核心作用是对进程可见的系统资源进行隔离让不同Namespace下的进程仿佛运行在两个完全独立的系统环境中互不干扰。简单来说Namespace的本质就是“封装隔离”——把进程能访问到的系统资源如PID、网络接口、挂载点等进行封装使得进程只能看到自己Namespace内的资源无法感知到其他Namespace的存在。这里要注意一个误区Namespace隔离的是“进程对资源的可见性”而不是“资源本身”。比如两个不同Namespace的进程依然可以共享物理CPU、内存等硬件资源只是它们看不到对方的进程、网络等信息而已——这也是容器比虚拟机轻量的关键虚拟机是隔离整个操作系统而容器只是隔离进程环境。2.2 常见的Namespace类型重点掌握4种Linux内核支持多种Namespace类型每种类型负责隔离一种或一类系统资源其中最常用、最核心的是以下4种也是面试高频考点建议重点掌握2.2.1 PID Namespace进程ID隔离这是最基础、最常用的一种Namespace负责隔离「进程IDPID」。在默认的Namespace初始Namespace中系统会从1开始分配PID比如init进程的PID是1而当我们创建一个新的PID Namespace后这个Namespace内的进程会重新从1开始分配PID并且只能看到自己Namespace内的进程看不到其他Namespace的进程。举个实操例子极简版可直接复制到Linux终端执行# 创建一个新的PID Namespace并在其中执行bash命令unshare --fork --pid --mount-proc /bin/bash# 查看当前Namespace内的进程会发现PID从1开始当前bash的PID是1ps-ef执行完上述命令后你会发现新的bash进程PID是1而且ps命令只能看到这个bash进程——这就是PID Namespace的隔离效果。退出当前bash执行exit就会回到原来的Namespace。2.2.2 Net Namespace网络环境隔离Net Namespace负责隔离「网络资源」包括网络接口、IP地址、端口、路由表、防火墙规则等。简单来说每个Net Namespace都有自己独立的“网络栈”就像一个独立的虚拟机有自己的网卡、IP、端口。比如我们常用的Docker容器每个容器默认就有一个独立的Net Namespace所以不同容器可以使用相同的端口如80端口互不冲突。实操演示创建一个新的Net Namespace查看网络接口# 创建一个名为my_net的Net Namespaceipnetnsaddmy_net# 查看my_net Namespace内的网络接口只有lo本地回环接口ipnetnsexecmy_netipaddr# 删除创建的Net Namespace用完清理避免占用资源ipnetns delete my_net通过这个例子可以看到新创建的Net Namespace默认只有lo接口没有其他网络接口完全与主系统的网络环境隔离——这就是容器网络隔离的核心原理。2.2.3 Mount Namespace文件系统挂载隔离Mount Namespace负责隔离「文件系统的挂载点」使得不同Namespace下的进程看到的文件系统目录结构是不同的。也就是说我们可以在一个Namespace内挂载某个文件系统如挂载U盘、本地目录而这个挂载操作只会影响当前Namespace不会影响其他Namespace也不会影响主系统的文件系统。这也是容器“镜像挂载”的核心原理——Docker容器就是通过Mount Namespace将镜像挂载到自己的文件系统中与主系统的文件系统隔离避免相互影响。2.2.4 User Namespace用户和组ID隔离User Namespace负责隔离「用户IDUID和组IDGID」允许在一个Namespace内将普通用户映射为主系统的root用户实现“权限隔离”。举个实用的场景在主系统中我们用普通用户UID1000运行容器但是在容器内部User Namespace内这个用户可以被映射为root用户UID0这样容器内的进程就拥有了root权限可以执行一些需要高权限的操作如安装软件、修改配置但这种root权限只局限于当前Namespace不会影响主系统的安全——这也是容器“安全隔离”的重要保障。2.3 Namespace的核心特点轻量级Namespace是内核级别的隔离不需要模拟整个操作系统只隔离进程环境开销极小隔离性不同Namespace下的进程资源可见性完全隔离互不干扰共享性多个Namespace可以共享同一套物理资源CPU、内存等提高资源利用率层级性Namespace支持嵌套比如一个PID Namespace可以包含另一个PID Namespace子Namespace可以看到父Namespace的进程但父Namespace看不到子Namespace的进程。三、CgroupsLinux的“资源限制工具”3.1 什么是CgroupsCgroupsControl Groups控制组是Linux内核提供的一种「资源限制和管理机制」它的核心作用是对进程组多个进程的系统资源CPU、内存、磁盘IO、网络带宽等进行限制、统计和控制。如果说Namespace解决的是“进程看不到彼此”的隔离问题那么Cgroups解决的就是“进程过度占用资源”的管控问题——两者协同才能实现容器的稳定运行。举个例子如果我们在一个服务器上运行多个容器其中一个容器的进程出现死循环疯狂占用CPU和内存如果没有Cgroups限制这个容器就会耗尽服务器的所有资源导致其他容器和服务器本身崩溃而有了Cgroups我们可以给每个容器设定CPU、内存的上限即使某个容器出现异常也不会影响其他容器和服务器的正常运行。3.2 Cgroups的核心功能Cgroups主要提供三大核心功能这也是我们实际使用中最常用的资源限制Resource Limiting限制进程组可使用的资源上限如CPU使用率、内存大小、磁盘IO速率等资源统计Resource Accounting统计进程组实际使用的资源如CPU使用时间、内存占用量、IO读写量等进程控制Process Control对进程组进行管理如暂停、恢复、终止进程组等。其中资源限制是最核心、最常用的功能下面我们重点讲解CPU和内存的限制实操看完就能直接上手使用。3.3 Cgroups实操限制进程的CPU和内存极简上手Cgroups的使用并不复杂Linux系统默认已经启用Cgroups我们可以通过操作/sys/fs/cgroup目录下的文件来配置Cgroups的资源限制这也是Docker等容器工具底层的实现方式。3.3.1 CPU限制实操需求创建一个Cgroup限制该Cgroup下的进程最多只能使用1颗CPU的50%即0.5颗CPU。# 1. 进入CPU Cgroup目录系统默认存在cd/sys/fs/cgroup/cpu# 2. 创建一个名为my_cpu的Cgroup会自动生成相关配置文件mkdirmy_cpu# 3. 配置CPU限制限制CPU使用率为50%核心参数cpu.cfs_quota_us# cpu.cfs_period_usCPU调度周期默认100000微秒即0.1秒# cpu.cfs_quota_us在一个调度周期内进程可使用的CPU时间单位微秒# 50%使用率 0.1秒 * 50% 50000微秒echo50000my_cpu/cpu.cfs_quota_us# 4. 将当前bash进程PID$$加入到my_cpu Cgroup中echo$$my_cpu/cgroup.procs# 5. 测试运行一个占用CPU的命令查看CPU使用率不会超过50%yes/dev/null测试完成后我们可以用top命令查看CPU使用率会发现yes命令的CPU使用率始终在50%左右这就说明Cgroups的CPU限制生效了。3.3.2 内存限制实操需求创建一个Cgroup限制该Cgroup下的进程最多只能使用100M内存。# 1. 进入内存Cgroup目录cd/sys/fs/cgroup/memory# 2. 创建一个名为my_memory的Cgroupmkdirmy_memory# 3. 配置内存限制最多使用100M内存单位字节100M104857600字节echo104857600my_memory/memory.limit_in_bytes# 4. 将当前bash进程加入到my_memory Cgroup中echo$$my_memory/cgroup.procs# 5. 测试运行一个占用内存的命令超过100M会被系统杀死python3 -ca [1]*10000000# 该命令会占用约80M内存可正常运行python3 -ca [1]*20000000# 该命令会占用约160M内存超过限制会被杀死通过这个实操我们可以直观地看到Cgroups的内存限制效果——当进程占用的内存超过设定的上限时系统会自动终止该进程避免过度占用内存。3.4 Cgroups的核心特点精细化控制支持对CPU、内存、磁盘IO、网络等多种资源进行精细化限制进程组管理可以将多个进程归为一个组对整个组进行资源限制方便管理灵活性可以动态调整资源限制无需重启进程满足不同场景的需求兼容性与Namespace完美协同是容器技术的核心底层组件。四、UnionFS容器的“分层存储基石”4.1 什么是UnionFSUnionFSUnion File System联合文件系统是一种「分层、可叠加的文件系统」它的核心作用是将多个独立的文件系统目录以分层的方式叠加在一起形成一个统一的文件系统视图。简单来说UnionFS就像“叠罗汉”——多个目录层叠加在一起上层目录会覆盖下层目录的相同文件用户只能看到最上层的文件系统视图但底层的所有目录层依然保持独立互不修改。这也是Docker镜像分层存储的核心原理——Docker镜像就是由多个只读层layer组成当我们启动容器时Docker会在镜像的只读层之上添加一个可写层容器内的所有修改如创建、删除、修改文件都会只发生在这个可写层不会影响底层的只读镜像层这样既能节省空间多个容器可以共享同一套镜像只读层又能保证镜像的一致性。4.2 UnionFS的核心原理分层叠加UnionFS的分层叠加机制主要分为「只读层Read-Only Layer」和「可写层Read-Write Layer」核心逻辑如下底层是多个只读层这些层是固定不变的只能读取不能修改最上层是一个可写层用户所有的写操作创建、删除、修改文件都会发生在这个可写层当用户读取一个文件时UnionFS会从最上层的可写层开始查找如果找到就返回该文件如果找不到就依次向下查找只读层直到找到为止当用户修改一个文件时UnionFS会先从底层的只读层将该文件复制到最上层的可写层然后在可写层对文件进行修改即“写时复制”Copy-On-Write底层的只读层文件依然保持不变当用户删除一个文件时UnionFS不会真正删除底层只读层的文件而是在可写层创建一个“删除标记”隐藏底层的文件看起来像是删除了一样。这种“写时复制”和“分层叠加”的机制让UnionFS具备了两个核心优势空间高效多个容器可以共享同一套只读镜像层无需重复存储极大节省了磁盘空间一致性底层的镜像只读层不会被修改确保了所有基于该镜像启动的容器初始环境都是一致的。4.3 常见的UnionFS变体Docker常用UnionFS有多种变体不同的变体在实现细节上略有差异其中Docker常用的有以下3种overlay2目前Docker默认使用的UnionFS变体性能优秀支持多层叠加兼容性好是最推荐使用的变体aufs早期Docker使用的UnionFS变体支持多层叠加但性能略逊于overlay2在部分Linux发行版中支持不够完善devicemapper一种基于块设备的存储驱动不是严格意义上的UnionFS但可以实现类似的分层存储功能适合在不支持overlay2的系统中使用。我们可以通过以下命令查看Docker当前使用的存储驱动即UnionFS变体dockerinfo|grepStorage Driver五、总结Namespace、Cgroups与UnionFS的协同关系看到这里相信大家已经对Namespace、Cgroups、UnionFS有了清晰的理解——这三者不是孤立的而是协同工作共同构成了容器技术的底层基石它们的关系可以总结为「Namespace」负责「环境隔离」让容器拥有独立的进程、网络、文件系统等环境实现“进程看不到彼此”「Cgroups」负责「资源限制」让容器只能使用设定的CPU、内存等资源实现“进程不抢占资源”「UnionFS」负责「分层存储」让容器拥有轻量、高效的存储方案实现“镜像可复用、环境可一致”。简单来说三者的协同逻辑就是用Namespace给容器“划一块独立的空间”用Cgroups给容器“设定资源上限”用UnionFS给容器“搭一套高效的存储”——三者结合才让容器实现了“轻量、隔离、高效、可复用”的核心优势。吃透这三个技术不仅能让你轻松理解容器的底层逻辑更能帮你夯实Linux内核基础在排查底层问题、面试中都能占据优势。建议大家收藏本文跟着文中的实操步骤动手练习加深理解