容器-资源隔离机制

一. 引言: 

  大家都知道,在一台机器上,可以运行任意(根据系统资源)个容器实例。且各容器间是相互独立,不做任何关联的。那么,docker是通过什么方式来实现容器隔离的呢? 接下来我们了解下。

二. 关于容器隔离机制:

   容器的隔离机制是实现 “轻量级虚拟化” 的核心,通过Linux 内核原生技术与容器运行时(如 docker、containerd)的封装,在共享宿主机内核的同时,为每个容器提供独立的资源、网络、文件系统等环境,避免容器间相互干扰。其本质是 “在同一内核中为进程组划定资源与权限边界”,而非像虚拟机那样完全隔离操作系统。

   主要分为一下三个大方向: 

Namespace  可实现容器间的隔离
Cgroups    可限制容器的资源使用
Chroot     文件系统的隔离(挂载到物理根目录(文件系统)下的子目录(虚拟文件系统))

 1. 关于namespace:

    Linux 内核从版本 2.4.19 开始陆续引入了 namespace 的概念。其目的是将某个特定的全局系统资源(global system resource)通过抽象方法使得namespace 中的进程看起来拥有它们自己的隔离的全局系统资源实例。Linux 内核中实现了六种 namespace,按照引入的先后顺序,列表如下:

namespace

引入的相关内核版本被隔离的全局系统资源在容器语境下的隔离效果
Mount Linux 2.4.19文件系统挂接点每个容器能看到不同的文件系统层次结构
šUTS Linux 2.6.19主机名和域名每个容器可以有自己的 hostname 和 domainame
IPC Linux 2.6.19

System V IPC:消息队列,信号量,共享内存

每个容器有其自己的 System V IPC 和消息队列文件系统,因此,只有在同一个 IPC namespace 的进程之间才能互相通信
PID Linux 2.6.24进程 ID(编号) 每个 PID namespace 中的进程可以有其独立的 PID; 每个容器可以有其 PID 为 1 的root 进程;也使得容器可以在不同的 host 之间迁移,因为 namespace 中的进程 ID 和 host 无关了。这也使得容器中的每个进程有两个PID:容器中的 PID 和 host 上的 PID。
Network 始于Linux 2.6.24 完成于 Linux 2.6.29网络相关的系统资源每个容器用有其独立的网络设备,IP 地址,IP 路由表,/proc/net 目录,端口号等等。这也使得一个 host 上多个容器内的同一个应用都绑定到各自容器的 80 端口上。
User 始于 Linux 2.6.23 完成于 Linux 3.8)用户和组 ID 空间 在 user namespace 中的进程的用户和组 ID 可以和在 host 上不同; 每个 container 可以有不同的 user 和 group id;一个 host 上的非特权用户可以成为 user namespace 中的特权用户;
 

Linux内核实现namespace的主要目的就是为了实现轻量级虚拟化(容器)服务。在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身于一个独立的系统环境中,以此达到独立和隔离的目的。

2. Cgroups:

   容器通过namespace机制实现了环境上的隔离。但只有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存 等。一方面,是为了防止它占用了太多的资源而影响到其它进程;另一方面,在系统资源耗尽的时候,linux 内核会触发 OOM,这会让一些被杀掉的进程成了无辜的替死鬼。因此,为了让容器中的进程更加可控,Docker 使用 Linux cgroups 来限制容器中的进程允许使用的系统资源。 

 Linux Cgroup 可为系统中所运行任务(进程)的用户定义组群分配资源 — 比如 CPU 时间、系统内存、网络带宽或者这些资源的组合。可以监控您配置的 cgroup,拒绝 cgroup 访问某些资源,甚至在运行的系统中动态配置您的 cgroup。它以一组进程为目标进行系统资源分配和控制。

它主要提供了以下功能:

Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制。
Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐。
Accounting: 资源统计,一些审计或一些统计,主要目的是为了计费。
Control: 进程控制,挂起进程,恢复执行进程。
使用 cgroup,系统管理员可更具体地控制对系统资源的分配、优先顺序、拒绝、管理和监控。可更好地根据任务和用户分配硬件资源,提高总体效率。在实际中,系统管理员一般会利用CGroup做下面这些事:
隔离一个进程集合(比如:nginx的所有进程),并限制他们所消费的资源,比如绑定CPU的核。
为这组进程分配其足够使用的内存
为这组进程分配相应的网络带宽和磁盘存储限制
限制访问某些设备(通过设置设备的白名单)

  3. Chroot: 

    是容器的 “独立文件系统根目录”,通过分层挂载(UnionFS) 实现,核心作用是:

1. 隔离性:容器内的/目录与宿主机完全独立,修改容器内文件(如/etc/passwd)不会影响宿主机。
2. 轻量性:采用 “基础镜像层 + 容器层” 的分层结构,多个容器可共享基础镜像层。
3. 一致性:每个容器启动时都基于相同的基础镜像,确保运行环境一致(避免 “本地能跑,线上跑不了”)。

  关键技术: UnionFS(联合文件系统)

  常用的 UnionFS 实现包括overlay2(Docker 默认)、aufs、btrfs等,以overlay2为例,其分层结构如下:

lowerdir:基础镜像层(可多层,如 “操作系统层 + Nginx 层”),仅可读;
upperdir:容器层,容器运行时的所有写操作(如创建 / 修改文件)都在这一层;
merged:容器内看到的 “根目录”,是lowerdir和upperdir的联合挂载结果;
workdir:临时工作目录,用于 UnionFS 的内部操作(用户不可见)。

三. 容器隔离 vs 虚拟机隔离: 

对比维度容器虚拟机
隔离核心共享宿主机内核,通过 namespace/cgroup 隔离进程完全隔离操作系统(含内核),通过 hypervisor 虚拟化硬件
资源开销轻量(MB 级内存,秒级启动),共享宿主机资源重量级(GB 级内存,分钟级启动),每个 vm 需独立分配资源
安全性较弱(共享内核,存在 “内核漏洞突破隔离” 风险)较强(完全隔离内核,VM 内攻击难以影响宿主机)
兼容性依赖宿主机内核版本(如容器内无法运行与宿主机内核不兼容的程序)兼容性强(VM 内可运行任意操作系统,与宿主机内核无关)

四. 无法隔离的资源: 

  1. 内核版本:容器内的内核版本与宿主机完全一致,无法在容器内升级内核;
  2. 内核模块:容器无法加载 / 卸载宿主机内核模块(需宿主机提前加载);
  3. 系统时间:默认情况下,容器内修改系统时间会同步修改宿主机时间。
  4. 硬件资源:部分硬件资源(如 CPU 缓存、NUMA 节点)无法精细隔离,可能存在 “缓存侧信道攻击” 风险;
  5. 内核漏洞:若宿主机内核存在漏洞(如 Dirty COW),容器内的恶意进程可能利用漏洞突破隔离,获取宿主机权限。

-  --------------------------------------------------------------------------------------------------------------------------

                         深耕运维行业多年,擅长运维体系建设,方案落地。欢迎交流!

                                                     “V-x”: ywjw996

                                                     《 运维经纬 》


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值