Docker底层-IPC Namespace(进程间通信隔离)

IPC Namespace 详解

1. IPC Namespace 的作用

IPC = Inter-Process Communication(进程间通信)

作用:隔离进程间通信资源,让不同 Namespace 中的进程无法互相通信。

复制代码
┌─────────────────────────────────────────────────────────┐
│                     Linux 主机                           │
│                                                          │
│  ┌──────────────┐              ┌──────────────┐         │
│  │ IPC NS 1     │              │ IPC NS 2     │         │
│  │              │              │              │         │
│  │ 共享内存 1   │              │ 共享内存 2   │         │
│  │ 消息队列 1   │              │ 消息队列 2   │         │
│  │ 信号量 1     │              │ 信号量 2     │         │
│  │              │              │              │         │
│  │ 完全隔离     │              │ 完全隔离     │         │
│  └──────────────┘              └──────────────┘         │
│                                                          │
│  不同 Namespace 的进程无法互相通信!                     │
└─────────────────────────────────────────────────────────┘

2. IPC Namespace 隔离的资源

IPC Namespace 隔离三种进程间通信机制:

1. System V IPC
  • 共享内存(Shared Memory)
  • 消息队列(Message Queue)
  • 信号量(Semaphore)
2. POSIX IPC
  • POSIX 消息队列
  • POSIX 信号量
  • POSIX 共享内存

3. 实际用例演示

用例 1:创建共享内存(System V IPC)
复制代码
# 步骤 1:创建新的 IPC Namespace
sudo unshare --ipc /bin/bash

# 步骤 2:在 Namespace 中创建共享内存
ipcmk -M 1024
# 输出:shmid: 0

# 步骤 3:查看共享内存
ipcs -m
# 输出:
# ------ Shared Memory Segments --------
# key        shmid      owner      perms      bytes      nattch     status
# 0x00000000 0          root       644         1024       0

# 步骤 4:退出 Namespace
exit

# 步骤 5:在主机上查看
ipcs -m
# 输出:(看不到 Namespace 中创建的共享内存)

4. 详细演示:共享内存隔离

演示 1:在 Namespace 中创建共享内存
演示 2:多个 IPC Namespace 同时存在
复制代码
# 终端 1:IPC Namespace 1
sudo unshare --ipc bash
ipcmk -M 1024
ipcs -m
# 输出:shmid: 0

# 终端 2:IPC Namespace 2
sudo unshare --ipc bash
ipcmk -M 2048
ipcs -m
# 输出:shmid: 0(注意:也是 0,因为每个 Namespace 独立编号)

# 终端 3:主机
ipcs -m
# 输出:(看不到两个 Namespace 中的共享内存)

┌─────────────────────────────────────────────────────────┐
│  IPC Namespace 1                                        │
│                                                          │
│  共享内存:                                              │
│  shmid: 0 (1024 bytes)                                  │
│                                                          │
│  只能看到自己的共享内存                                  │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│  IPC Namespace 2                                        │
│                                                          │
│  共享内存:                                              │
│  shmid: 0 (2048 bytes)                                  │
│                                                          │
│  只能看到自己的共享内存                                  │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│  主机 IPC Namespace                                      │
│                                                          │
│  共享内存:                                              │
│  (看不到 Namespace 1 和 2 的)                         │
└─────────────────────────────────────────────────────────┘

验证命令总结

复制代码
# 1. 创建 IPC Namespace
sudo unshare --ipc /bin/bash

# 2. 创建共享内存
ipcmk -M <大小>

# 3. 创建消息队列
ipcmk -Q n

# 4. 创建信号量
ipcmk -S

# 5. 查看所有 IPC 资源
ipcs -a

# 6. 查看共享内存
ipcs -m

# 7. 查看消息队列
ipcs -q

# 8. 查看信号量
ipcs -s

# 9. 删除共享内存
ipcrm -m <shmid>

# 10. 删除消息队列
ipcrm -q <msqid>

# 11. 删除信号量
ipcrm -s <semid>

# 12. 查看 IPC Namespace
readlink /proc/self/ns/ipc
复制代码
root@LAPTOP-LU4HDAFV:~# sudo unshare --ipc /bin/bash
root@LAPTOP-LU4HDAFV:~# ipcmk -M 2048
Shared memory id: 0
root@LAPTOP-LU4HDAFV:~# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x6b97cbc6 0          root       644        2048       0                       

root@LAPTOP-LU4HDAFV:~# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x6b97cbc6 0          root       644        2048       0                
root@LAPTOP-LU4HDAFV:~# exit
exit
root@LAPTOP-LU4HDAFV:~# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      

root@LAPTOP-LU4HDAFV:~# sudo unshare --ipc /bin/bash
root@LAPTOP-LU4HDAFV:~# ipcmk -M 1024
Shared memory id: 0
root@LAPTOP-LU4HDAFV:~# ipcmk -Q
Message queue id: 0
root@LAPTOP-LU4HDAFV:~# ipcmk -S
ipcmk: option requires an argument -- 'S'
Try 'ipcmk --help' for more information.
root@LAPTOP-LU4HDAFV:~# ipcmk -S 1
Semaphore id: 0
root@LAPTOP-LU4HDAFV:~# ipcmk -a
ipcmk: invalid option -- 'a'
Try 'ipcmk --help' for more information.
root@LAPTOP-LU4HDAFV:~# ipcs -a

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xf59890ae 0          root       644        0            0           

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0xa4e2c6d0 0          root       644        1024       0                       

------ Semaphore Arrays --------
key        semid      owner      perms      nsems     
0x0d4e54b8 0          root       644        1         

root@LAPTOP-LU4HDAFV:~# 

总结

机制 用途 类比 命令
共享内存 多个进程共享同一块内存 共享黑板 ipcmk -M
消息队列 进程间发送和接收消息 邮箱系统 ipcmk -Q
信号量 控制同时访问资源的进程数 停车场车位 ipcmk -S

这三种机制都被 IPC Namespace 隔离,不同 Namespace 的进程无法互相访问对方的 IPC 资源。

IPC Namespace 隔离的资源详解

2. IPC Namespace 隔离的资源(图示)

IPC Namespace 隔离三种进程间通信机制:

1. System V IPC
复制代码
┌─────────────────────────────────────────────────────────┐
│  System V IPC(三种机制)                                │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 1. 共享内存(Shared Memory)                  │      │
│  │                                              │      │
│  │  进程 A             进程 B                   │      │
│  │    │                  │                     │      │
│  │    └──────┐      ┌─────┘                     │      │
│  │           │      │                          │      │
│  │      ┌────▼──────▼────┐                     │      │
│  │      │  共享内存区域   │                     │      │
│  │      │  (Shared Memory)│                    │      │
│  │      └─────────────────┘                     │      │
│  │                                              │      │
│  │  多个进程可以同时访问同一块内存               │      │
│  └──────────────────────────────────────────────┘      │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 2. 消息队列(Message Queue)                  │      │
│  │                                              │      │
│  │  进程 A ──发送消息──> [消息队列] ──接收消息──> 进程 B│
│  │                                              │      │
│  │      ┌──────────────────────┐               │      │
│  │      │   消息队列            │               │      │
│  │      │  ┌────┐ ┌────┐ ┌────┐│               │      │
│  │      │  │消息1│ │消息2│ │消息3││               │      │
│  │      │  └────┘ └────┘ └────┘│               │      │
│  │      └──────────────────────┘               │      │
│  │                                              │      │
│  │  进程通过消息队列发送和接收消息               │      │
│  └──────────────────────────────────────────────┘      │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 3. 信号量(Semaphore)                         │      │
│  │                                              │      │
│  │  进程 A             进程 B                   │      │
│  │    │                  │                     │      │
│  │    │                  │                     │      │
│  │    └──────┐      ┌─────┘                     │      │
│  │           │      │                          │      │
│  │      ┌────▼──────▼────┐                     │      │
│  │      │    信号量       │                     │      │
│  │      │  (计数器)      │                     │      │
│  │      │  值: 3          │                     │      │
│  │      └─────────────────┘                     │      │
│  │                                              │      │
│  │  用于进程同步和互斥访问资源                   │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘

详细图示:IPC Namespace 隔离效果

场景:两个 IPC Namespace 的隔离
复制代码
┌─────────────────────────────────────────────────────────┐
│                     Linux 主机                           │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │ IPC Namespace 1                                  │   │
│  │                                                  │   │
│  │  进程 A             进程 B                       │   │
│  │    │                  │                          │   │
│  │    └──────┐      ┌─────┘                          │   │
│  │           │      │                               │   │
│  │      ┌────▼──────▼────┐                          │   │
│  │      │  共享内存 1     │                          │   │
│  │      │  shmid: 0       │                          │   │
│  │      └─────────────────┘                          │   │
│  │                                                  │   │
│  │  进程 C ──消息──> [消息队列 1] ──消息──> 进程 D   │   │
│  │              msqid: 0                            │   │
│  │                                                  │   │
│  │  进程 E ──等待──> [信号量 1] <──等待── 进程 F    │   │
│  │              semid: 0                             │   │
│  │                                                  │   │
│  │  只能看到自己的 IPC 资源!                       │   │
│  └──────────────────────────────────────────────────┘   │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │ IPC Namespace 2                                  │   │
│  │                                                  │   │
│  │  进程 G             进程 H                       │   │
│  │    │                  │                          │   │
│  │    └──────┐      ┌─────┘                          │   │
│  │           │      │                               │   │
│  │      ┌────▼──────▼────┐                          │   │
│  │      │  共享内存 2     │                          │   │
│  │      │  shmid: 0       │  ← 注意:也是 0!        │   │
│  │      └─────────────────┘                          │   │
│  │                                                  │   │
│  │  进程 I ──消息──> [消息队列 2] ──消息──> 进程 J   │   │
│  │              msqid: 0                             │   │
│  │                                                  │   │
│  │  进程 K ──等待──> [信号量 2] <──等待── 进程 L    │   │
│  │              semid: 0                             │   │
│  │                                                  │   │
│  │  只能看到自己的 IPC 资源!                       │   │
│  │  看不到 Namespace 1 的资源!                      │   │
│  └──────────────────────────────────────────────────┘   │
│                                                          │
│  完全隔离:两个 Namespace 的进程无法互相访问 IPC 资源!  │
└─────────────────────────────────────────────────────────┘

详细图示:共享内存(Shared Memory)

复制代码
┌─────────────────────────────────────────────────────────┐
│  IPC Namespace 1 - 共享内存示例                          │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 A (PID: 1001)                           │      │
│  │                                              │      │
│  │  写入数据到共享内存:                          │      │
│  │  shm_write(shmid: 0, "Hello")                │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  └───────────────────┼──────────────────────────┘      │
│                      │                                  │
│                      │                                  │
│  ┌───────────────────┼──────────────────────────┐      │
│  │ 进程 B (PID: 1002) │                          │      │
│  │                   │                          │      │
│  │  从共享内存读取:   │                          │      │
│  │  shm_read(shmid: 0)                           │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  └───────────────────┼──────────────────────────┘      │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────┐      │
│  │ 共享内存 (shmid: 0)                          │      │
│  │                                              │      │
│  │  ┌────────────────────────────────────┐     │      │
│  │  │ 地址: 0x7f8a5c000000               │     │      │
│  │  │ 大小: 1024 bytes                    │     │      │
│  │  │ 内容: "Hello"                      │     │      │
│  │  └────────────────────────────────────┘     │      │
│  │                                              │      │
│  │  进程 A 和 B 共享这块内存                     │      │
│  └──────────────────────────────────────────────┘      │
│                                                          │
│  在 IPC Namespace 2 中:                                 │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 C 尝试访问 shmid: 0                     │      │
│  │                                              │      │
│  │  结果:失败!                                 │      │
│  │  错误:No such file or directory             │      │
│  │                                              │      │
│  │  因为 Namespace 2 中的 shmid: 0               │      │
│  │  是另一个共享内存!                           │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘

详细图示:消息队列(Message Queue)

复制代码
┌─────────────────────────────────────────────────────────┐
│  IPC Namespace 1 - 消息队列示例                          │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 A (发送者)                              │      │
│  │                                              │      │
│  │  msgsnd(msqid: 0, "Message 1")              │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  └───────────────────┼──────────────────────────┘      │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────┐      │
│  │ 消息队列 (msqid: 0)                          │      │
│  │                                              │      │
│  │  ┌────────────────────────────────────┐     │      │
│  │  │ 队列头部                            │     │      │
│  │  │ ┌──────────┐                       │     │      │
│  │  │ │消息 1    │ ← 进程 A 发送          │     │      │
│  │  │ └──────────┘                       │     │      │
│  │  │ ┌──────────┐                       │     │      │
│  │  │ │消息 2    │                       │     │      │
│  │  │ └──────────┘                       │     │      │
│  │  │ ┌──────────┐                       │     │      │
│  │  │ │消息 3    │                       │     │      │
│  │  │ └──────────┘                       │     │      │
│  │  │ 队列尾部                            │     │      │
│  │  └────────────────────────────────────┘     │      │
│  └──────────────────────────────────────────────┘      │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 B (接收者)                              │      │
│  │                                              │      │
│  │  msgrcv(msqid: 0)                           │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  │  收到:"Message 1" │                          │      │
│  └──────────────────────────────────────────────┘      │
│                                                          │
│  在 IPC Namespace 2 中:                                 │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 C 尝试访问 msqid: 0                     │      │
│  │                                              │      │
│  │  结果:失败!                                 │      │
│  │  错误:No such file or directory             │      │
│  │                                              │      │
│  │  因为 Namespace 2 有自己的消息队列!           │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘

详细图示:信号量(Semaphore)

复制代码
┌─────────────────────────────────────────────────────────┐
│  IPC Namespace 1 - 信号量示例                            │
│                                                          │
│  场景:多个进程竞争访问共享资源                           │
│                                                          │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 A                                       │      │
│  │                                              │      │
│  │  sem_wait(semid: 0)  ← 等待信号量            │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  └───────────────────┼──────────────────────────┘      │
│                      │                                  │
│  ┌───────────────────┼──────────────────────────┐      │
│  │ 进程 B           │                          │      │
│  │                  │                          │      │
│  │  sem_wait(semid: 0)                          │      │
│  │         │                                     │      │
│  │         └─────────┐                          │      │
│  └───────────────────┼──────────────────────────┘      │
│                      │                                  │
│                      ↓                                  │
│  ┌──────────────────────────────────────────────┐      │
│  │ 信号量 (semid: 0)                             │      │
│  │                                              │      │
│  │  ┌────────────────────────────────────┐     │      │
│  │  │ 计数器值: 3                        │     │      │
│  │  │                                  │     │      │
│  │  │  进程 A: sem_wait()               │     │      │
│  │  │    ↓                              │     │      │
│  │  │  计数器: 3 → 2                     │     │      │
│  │  │                                  │     │      │
│  │  │  进程 B: sem_wait()               │     │      │
│  │  │    ↓                              │     │      │
│  │  │  计数器: 2 → 1                     │     │      │
│  │  │                                  │     │      │
│  │  │  进程 C: sem_wait()               │     │      │
│  │  │    ↓                              │     │      │
│  │  │  计数器: 1 → 0                     │     │      │
│  │  │                                  │     │      │
│  │  │  进程 D: sem_wait()               │     │      │
│  │  │    ↓                              │     │      │
│  │  │  计数器: 0 → 阻塞等待              │     │      │
│  │  └────────────────────────────────────┘     │      │
│  │                                              │      │
│  │  用于控制同时访问资源的进程数量               │      │
│  └──────────────────────────────────────────────┘      │
│                                                          │
│  在 IPC Namespace 2 中:                                 │
│  ┌──────────────────────────────────────────────┐      │
│  │ 进程 E 尝试访问 semid: 0                     │      │
│  │                                              │      │
│  │  结果:失败!                                 │      │
│  │  错误:No such file or directory             │      │
│  │                                              │      │
│  │  因为 Namespace 2 有自己的信号量!             │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘

整对比图:隔离效果

复制代码
┌─────────────────────────────────────────────────────────┐
│  主机 IPC Namespace                                      │
│                                                          │
│  ipcs -a                                                 │
│  ┌──────────────────────────────────────────────┐      │
│  │ (可能有一些主机的 IPC 资源)                  │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘
                    │
                    │ 创建 IPC Namespace
                    │
        ┌───────────┴───────────┐
        │                       │
        ↓                       ↓
┌───────────────────┐  ┌───────────────────┐
│ IPC Namespace 1   │  │ IPC Namespace 2   │
│                   │  │                   │
│ ipcs -a           │  │ ipcs -a           │
│ ┌───────────────┐ │  │ ┌───────────────┐ │
│ │ 共享内存 1     │ │  │ │ 共享内存 2     │ │
│ │ shmid: 0      │ │  │ │ shmid: 0      │ │
│ └───────────────┘ │  │ └───────────────┘ │
│ ┌───────────────┐ │  │ ┌───────────────┐ │
│ │ 消息队列 1     │ │  │ │ 消息队列 2     │ │
│ │ msqid: 0      │ │  │ │ msqid: 0      │ │
│ └───────────────┘ │  │ └───────────────┘ │
│ ┌───────────────┐ │  │ ┌───────────────┐ │
│ │ 信号量 1       │ │  │ │ 信号量 2       │ │
│ │ semid: 0      │ │  │ │ semid: 0      │ │
│ └───────────────┘ │  │ └───────────────┘ │
│                   │  │                   │
│ 看不到 Namespace 2│  │ 看不到 Namespace 1│
│ 的资源!           │  │ 的资源!           │
└───────────────────┘  └───────────────────┘

总结图:三种 IPC 机制

复制代码
┌─────────────────────────────────────────────────────────┐
│  System V IPC 三种机制                                   │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │ 1. 共享内存   │  │ 2. 消息队列   │  │ 3. 信号量     │  │
│  │              │  │              │  │              │  │
│  │ 多个进程      │  │ 进程间发送    │  │ 进程同步      │  │
│  │ 共享同一块    │  │ 和接收消息    │  │ 和互斥访问    │  │
│  │ 内存区域      │  │              │  │              │  │
│  │              │  │              │  │              │  │
│  │ 命令:        │  │ 命令:        │  │ 命令:        │  │
│  │ ipcmk -M     │  │ ipcmk -Q     │  │ ipcmk -S     │  │
│  │ ipcs -m      │  │ ipcs -q      │  │ ipcs -s      │  │
│  │ ipcrm -m     │  │ ipcrm -q     │  │ ipcrm -s     │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
│                                                          │
│  所有这些资源都被 IPC Namespace 隔离!                    │
└─────────────────────────────────────────────────────────┘
相关推荐
用户03284722207017 小时前
如何搭建本地yum源(上)
运维
武子康18 小时前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn864 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉4 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造