【原理】Linux Namespace与Cgroups:容器隔离技术揭秘


阿里云特惠 - 新用户专享

容器隔离技术揭秘

Docker容器并非虚拟机,而是Linux内核特性的巧妙运用.本文深入解析Namespace和Cgroups原理.

Namespace:资源隔离

Namespace让进程拥有独立的系统资源视图,就像拥有独立的操作系统.

6种Namespace类型

Namespace 隔离资源 用途
PID 进程ID 容器内PID从1开始
NET 网络设备,端口 容器拥有独立IP
MNT 文件系统挂载点 容器有自己的根目录
UTS 主机名/域名 容器可设独立hostname
IPC 进程间通信 隔离共享内存,信号量
USER 用户/组ID 容器内root映射到宿主机普通用户

动手实验:创建隔离的Shell

# 使用unshare命令创建新的Namespace
# -u: UTS namespace (hostname)
# -i: IPC namespace
# -n: NET namespace
# -p: PID namespace
# -m: MNT namespace
# --fork: 创建新的进程
# --mount-proc: 挂载新的proc文件系统

$ sudo unshare --uts --ipc --net --pid --fork --mount-proc /bin/bash

# 在新Namespace中
[root@new-namespace]# hostname container1
[root@new-namespace]# hostname
container1

# 查看进程,只能看到自己Namespace的进程
[root@new-namespace]# ps aux
PID   USER     COMMAND
    1 root     /bin/bash
   15 root     ps aux

# 退出后回到宿主机,hostname不变
[root@new-namespace]# exit
$ hostname
original-hostname

Cgroups:资源限制

Cgroups(Control Groups)限制进程能使用的资源量.

Cgroups子系统

# 查看Cgroups挂载点
$ mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs...
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup...
cgroup on /sys/fs/cgroup/memory type cgroup...
cgroup on /sys/fs/cgroup/blkio type cgroup...

# 主要子系统:
# cpu - CPU时间分配
# memory - 内存限制
# blkio - 块设备IO限制
# pids - 进程数量限制

动手实验:限制进程CPU

# 创建cgroup并设置CPU限制
cd /sys/fs/cgroup/cpu

# 创建新的cgroup
sudo mkdir mygroup
cd mygroup

# 设置CPU使用限制(相对权重)
echo 512 | sudo tee cpu.shares
# 默认1024,512表示最多使用50% CPU

# 设置CPU使用率硬限制(cfs_quota)
echo 100000 | sudo tee cpu.cfs_quota_us  # 100ms
echo 100000 | sudo tee cpu.cfs_period_us # 每100ms周期
echo 50000 | sudo tee cpu.cfs_quota_us   # 限制为50%

# 将进程加入cgroup
echo $$ | sudo tee cgroup.procs

# 现在当前shell及其子进程都被限制了CPU

动手实验:限制内存

# 创建内存cgroup
cd /sys/fs/cgroup/memory
sudo mkdir memlimit
cd memlimit

# 设置内存限制为100MB
echo 104857600 | sudo tee memory.limit_in_bytes

# 设置swap限制(防止用swap绕过限制)
echo 104857600 | sudo tee memory.memsw.limit_in_bytes

# 测试:运行一个吃内存的程序
echo $$ | sudo tee cgroup.procs
python3 -c "a = 'x' * 200 * 1024 * 1024"  # 申请200MB
# 结果:进程被OOM Killer杀死

Docker如何使用这些技术

# 查看容器的Namespace
$ docker inspect nginx | grep -A20 Namespace

# 查看容器在宿主机上的进程
$ docker top nginx
PID                 USER                COMMAND
12345               root                nginx: master process

# 查看该进程的Namespace
$ ls -la /proc/12345/ns/
lrwxrwxrwx 1 root root 0 Jan  1 00:00 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 root root 0 Jan  1 00:00 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 root root 0 Jan  1 00:00 net -> net:[4026532281]
lrwxrwxrwx 1 root root 0 Jan  1 00:00 pid -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Jan  1 00:00 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jan  1 00:00 uts -> uts:[4026532277]

# 查看容器的Cgroups限制
$ cat /proc/12345/cgroup
12:memory:/docker/nginx-container-id
11:cpu,cpuacct:/docker/nginx-container-id
...

容器 vs 虚拟机架构对比

[虚拟机]                    [容器]
┌─────────────┐              ┌─────────────┐
│   App       │              │   App       │
├─────────────┤              ├─────────────┤
│   Libs      │              │   Libs      │
├─────────────┤              ├─────────────┤
│ Guest OS    │              │ Namespace   │
│ (完整内核)   │              │ (隔离视图)   │
├─────────────┤              ├─────────────┤
│ Hypervisor  │              │ Cgroups     │
├─────────────┤              │ (资源限制)   │
│ Host OS     │              ├─────────────┤
├─────────────┤              │ Host OS     │
│ Hardware    │              │ (共享内核)   │
└─────────────┘              ├─────────────┤
                             │ Hardware    │
                             └─────────────┘

总结

容器技术本质是Namespace提供隔离视图,Cgroups提供资源限制.理解这些原理,能帮助你更好地排查容器问题和优化资源使用.

发表评论