Linux Namespace
Namespace = Linux 内核提供的「资源视图隔离机制」
同一台主机上:
- 同一个资源
- 不同进程
- 看到的是不同世界
📌 Namespace 不做资源限制(那是 cgroups 干的),只做 “看不看得到”。
| Namespace | 隔离内容 | 内核宏 |
|---|---|---|
| Mount | 挂载点 | CLONE_NEWNS |
| PID | 进程号 | CLONE_NEWPID |
| Network | 网络栈 | CLONE_NEWNET |
| IPC | 进程间通信 | CLONE_NEWIPC |
| UTS | 主机名/域名 | CLONE_NEWUTS |
| User | UID/GID | CLONE_NEWUSER |
| cgroups | cgroup 视图 | CLONE_NEWCGROUP |
| Time | 系统时间 | CLONE_NEWTIME |
Docker / Podman / containerd 全都在用这些。
- Namespace 不是系统级
- 是 进程属性
ls -l /proc/$$/ns
clone(CLONE_NEWNET | CLONE_NEWPID)
nsenter -t <pid> -n -m -p
- /
- mount
- bind mount
- overlayfs
容器内:
mount | grep overlay
容器外:
mount | grep overlay
➡️ 看到完全不同
| 模式 | 含义 |
|---|---|
| private | 默认,不传播 |
| shared | 传播 |
| slave | 单向 |
| unbindable | 不可绑定 |
mount --make-rprivate /
📌 容器启动前必做
- PID 从 1 开始
- 只能看到自己 namespace 的进程
unshare -p --fork bash
ps aux
- 不处理 SIGCHLD -> 僵尸进程
- 容器 init 必须存在
📌 Docker 用 tini
- 网卡
- IP
- 路由表
- 防火墙
- conntrack
ip netns add test
ip netns exec test ip a
只有:
- lo(DOWN)
ip link add veth0 type veth peer name veth1
ip link set veth1 netns test
container(netns)
|
veth
|
docker0 (bridge)
|
host NIC
unshare -u bash
hostname container01
- 不影响宿主机
- Kubernetes Pod 用它
隔离:
- SysV shm
- semaphore
- message queue
ipcs -m
容器间不会互相看到
容器内 root ≠ 宿主 root
unshare -U bash
id
cat /proc/$$/uid_map
0 100000 65536
- rootless container
- 减少提权风险
- 隔离 /proc/self/cgroup 视图
- 避免容器看到宿主完整层级
- CLOCK_MONOTONIC
- CLOCK_BOOTTIME
unshare -T bash
📌 用于测试、回放
Container =
Mount
+ PID
+ Net
+ IPC
+ UTS
+ User
+ cgroups
📌 Namespace 是容器的本体
- 随最后一个进程结束而销毁
- 或被 bind mount 到文件系统
mount --bind /proc/1234/ns/net /var/run/netns/demo
lsns -p <pid>
nsenter -t <pid> -n -m -p -u -i bash
✅ 推荐
- 明确 namespace 边界
- 使用 user namespace
- 容器 PID 1 要靠谱
- netns 内部最小化防火墙
❌ 雷区
- 在 host 上乱改 mount 传播
- 忽略 PID 1
- 误以为 namespace 能限资源
Namespace 是“你能看到什么”
cgroups 是“你能用多少”
两者一起,才是容器。