Linux namespace 介绍

发布时间: 更新时间: 总字数:1552 阅读时间:4m 作者: 分享 复制网址
专栏文章
  1. Linux 基础知识
  2. chroot 技术简介
  3. Linux 中个目录说明
  4. 进程、线程、协程的作用和区别
  5. Linux 动态链接库和静态链接库
  6. Linux PAM 可插拔认证模块介绍
  7. Linux limits.conf 详解与配置
  8. Linux Signal 信号量介绍
  9. Linux GDB 调试
  10. Linux core dump 文件介绍
  11. Linux procfs 介绍
  12. Linux 进程 /proc/PID/status 深入分析
  13. Linux sysfs 介绍
  14. Linux nsswithch.conf 详解
  15. Linux Systemd 介绍
  16. Linux Interrupt 中断介绍
  17. Linux namespace 介绍(当前)
  18. Linux Cgroups 介绍
  19. Linux Capabilities 介绍

Linux namespaceLinux 提供的一种内核级别环境隔离的方法。本文结合 unshare、介绍 Linux namespaces,该技术是容器(如Docker等)技术的基础。

namespace 机制

 -------------------------------------------
| Process1 | Process2 | Process1 | Process2 |
 -------------------------------------------
|      Namespace1     |      Namespace2     |
 -------------------------------------------
|              Linux Kernel                 |
 -------------------------------------------
|                Hardware                   |
 -------------------------------------------

Linux namespace 机制提供一种资源隔离和虚拟化技术。如上图中 Namespace1Namespace2 中经常需要有单独的 pid 命名空间,他们分别有自己的 init 进程(PID 为1)。

namespace 分类

Linux 从 Kernel 2.6 版本开始,逐步添加 Namespace 技术支持,Namespace 的 6 大类型如下:

namespace 系统调用参数 Kernel Version 作用
MNT(Mount) Namespaces CLONE_NEWNS Linux 2.4.19 提供磁盘挂载点和文件系统的隔离能力
UTS(Unix Timesharing System) Namespaces CLONE_NEWUTS Linux 2.6.19 提供独立的 hostnamedomainname
IPC(Inter Process Communication) Namespaces CLONE_NEWIPC Linux 2.6.19 提供进程间通信的隔离能力,包括消息队列,共享内存和信号量
PID(Process ID) Namespaces CLONE_NEWPID Linux 2.6.19 提供进程隔离能力
Net(Network) Namespaces CLONE_NEWNET Linux 2.6.24 ~ 2.6.29 网络隔离能力,提供独立的网络栈
User Namespaces CLONE_NEWUSER Linux 2.6.23 ~ 3.8 提供用户和用户组隔离能力

cgroup(control group) 为进程有一个独立的 cgroup 控制组

示例

# 宿主机
$ uname -a
Linux ubuntu 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

# 获取当前进程PID
$ echo $$
2363

# 当前进程 namespace 信息
$ ls -lh /proc/$$/ns/
total 0
lrwxrwxrwx 1 root root 0 Jun  3 19:54 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 mnt -> 'mnt:[4026531840]'  # 不同 ns 的编号不同
lrwxrwxrwx 1 root root 0 Jun  3 19:54 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jun  3 19:54 uts -> 'uts:[4026531838]'

使用 lsns 命令查看当前系统有哪些 namespace,下面展示了系统默认的命令空间:

$ lsns
        NS TYPE   NPROCS   PID USER            COMMAND
4026531835 cgroup    330     1 root            /sbin/init splash
4026531836 pid       330     1 root            /sbin/init splash
4026531837 user      329     1 root            /sbin/init splash
4026531838 uts       327     1 root            /sbin/init splash
4026531839 ipc       330     1 root            /sbin/init splash
4026531840 mnt       317     1 root            /sbin/init splash
4026532000 net       329     1 root            /sbin/init splash

MNT Namespace

  • 无隔离时
# create tmp dir
mkdir /tmp/testdir

# mount tmpfs
mount -t tmpfs tmpfs /tmp/testdir

# touch file
cd /tmp/testdir
touch 1 2 3
  • 隔离时
$ unshare --mount /bin/bash
$ echo $$
27290  # 新的进程
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jun  3 20:00 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 mnt -> 'mnt:[4026532695]'  # 与没有隔离的 4026531840 不同
lrwxrwxrwx 1 root root 0 Jun  3 20:00 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jun  3 20:00 uts -> 'uts:[4026531838]'

# 进程隶属关系 2363 是 27290 的父进程
$ ps -ef |grep 27290 |grep -v grep
root       27290    2363  0 20:00 pts/0    00:00:00 /bin/bash
root       27336   27290  0 20:02 pts/0    00:00:00 ps -ef

$ pstree 2363
bash───bash───pstree
$ pstree 27290
bash───pstree

# mount tmpfs
mount -t tmpfs tmpfs /tmp/testdir

# 查看文件
$ ls -lh
total 0

结论:使用 unshare -m 或者 unshare –mnt 创建了隔离的 namespace。

IPC namespace

  • 无隔离时
$ ipcs

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

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

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
  • 隔离时
# 创建隔离的ipc namespace
unshare --ipc /bin/bash

# 查看
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jun  3 20:11 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 ipc -> 'ipc:[4026532695]'  # id 变化
lrwxrwxrwx 1 root root 0 Jun  3 20:11 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jun  3 20:11 uts -> 'uts:[4026531838]'

# 创建消息队列
$ ipcmk --queue

# 查看
$ ipcs

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x22b527a3 0          root       644        0            0         # 新建

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

------ Semaphore Arrays --------
key        semid      owner      perms      nsems

退出,在原有中查看不到新建的 queue

$ exit
$ echo $$
2363
$ ipcs

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

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

------ Semaphore Arrays --------
key        semid      owner      perms      nsems

UTS namespace

  • 隔离前
$ hostname
vm
  • 隔离后
$ echo $$
27458
$ ls -lh /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jun  3 20:15 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jun  3 20:15 uts -> 'uts:[4026532695]'  # 与之前 id 不同

# 修改 hostname
$ hostname
vm
$ hostname abc
$ hostname
abc

退出,在原有中查看不到新建的 queue

$ exit
$ echo $$
2363
$ hostname

PID namespace

  • 隔离后
# 隔离
$ unshare --fork --pid /bin/bash

# 进程信息为 1,证明时新的 pid
$ echo $$
1
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jun  3 20:03 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:24 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jun  3 20:03 uts -> 'uts:[4026531838]'

USER namespace

  • 隔离前
$ id
uid=0(root) gid=0(root) groups=0(root)
  • 隔离后
$ unshare --user /bin/bash

$ echo $$
27684
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 net -> 'net:[4026531992]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 user -> 'user:[4026532695]'  # 与之前 id 不同
lrwxrwxrwx 1 nobody nogroup 0 Jun  3 20:21 uts -> 'uts:[4026531838]'

# 通过 id 证明在不同的 user ns 中
$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
专栏文章
  1. Linux 基础知识
  2. chroot 技术简介
  3. Linux 中个目录说明
  4. 进程、线程、协程的作用和区别
  5. Linux 动态链接库和静态链接库
  6. Linux PAM 可插拔认证模块介绍
  7. Linux limits.conf 详解与配置
  8. Linux Signal 信号量介绍
  9. Linux GDB 调试
  10. Linux core dump 文件介绍
  11. Linux procfs 介绍
  12. Linux 进程 /proc/PID/status 深入分析
  13. Linux sysfs 介绍
  14. Linux nsswithch.conf 详解
  15. Linux Systemd 介绍
  16. Linux Interrupt 中断介绍
  17. Linux namespace 介绍(当前)
  18. Linux Cgroups 介绍
  19. Linux Capabilities 介绍
最新评论
加载中...
Home Archives Categories Tags Statistics