linux 虚拟多个容器,Linux 虚拟容器系列

本文介绍了Linux容器技术中的核心概念——Namespace,通过实例解析了如何使用lsns命令查看系统中的Namespace,详细阐述了不同类型的Namespace(如cgroup、pid、user等)及其作用。此外,还讲解了clone、setns、unshare等系统调用在Namespace管理中的应用,展示了如何在不创建新进程的情况下实现资源隔离。
摘要由CSDN通过智能技术生成

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前言

本文从浅显的角度讲解 Linux container 技术,配合一些命令、代码执行的步骤来帮助人直观的理解 namespace 在 Linux 的存在意义与作用,教会人如何去使用它。

以下命令与代码的执行环境:Arch Linux 4.19.16

认识 Linux 下的 namespace

认识新事物,首先要学会观察它,第一步,执行 lsns命令,查看 Linux 下的 namespace

Example,我电脑上的 namespace

➜ ~ sudo lsns

NS TYPE NPROCS PID USER COMMAND

4026531835 cgroup 216 1 root /sbin/init

4026531836 pid 194 1 root /sbin/init

4026531837 user 216 1 root /sbin/init

4026531838 uts 216 1 root /sbin/init

4026531839 ipc 216 1 root /sbin/init

4026531840 mnt 209 1 root /sbin/init

4026531860 mnt 1 40 root kdevtmpfs

4026532008 net 193 1 root /sbin/init

4026532202 mnt 1 246 root /usr/lib/systemd/systemd-udevd

4026532259 mnt 1 539 root /usr/bin/NetworkManager --no-daemon

4026532261 pid 22 1625 lightfish /usr/lib/chromium/chromium --type=zygote

...

如上所示,lsns 打印出我电脑上的namespace,以及访问这些 namespace 的进程信息。仔细数数,可以发现,Linux 的祖先进程 init 使用了 6 种 namespace,它们分别是: cgroup, pid, user, uts, ipc, mnt, 这6个 namespace 也代表了 Linux 系统下的大多数资源。以 Linux 内核下定义的宏定义说明,在 Linux 中可通过 man clone 命令参阅,以下摘抄部分:

名称 宏定义 隔离内容

Cgroup CLONE_NEWCGROUP Cgroup root directory (since Linux 4.6)

IPC CLONE_NEWIPC 信号量、消息队列和共享内存 (since Linux 2.6.19)

Network CLONE_NEWNET 网络设备、网络栈、端口等等 (since Linux 2.6.24)

Mount CLONE_NEWNS 挂载点(文档系统) (since Linux 2.4.19)

PID CLONE_NEWPID 进程编号 (since Linux 2.6.24)

User CLONE_NEWUSER U用户和用户组 (started in Linux 2.6.23 and completed in Linux 3.8)

UTS CLONE_NEWUTS 主机名与域名 (since Linux 2.6.19)

Tip: 在 Linux “一切皆文档”的哲学下,除了用 lsns -p $pid 命令来查看某一个进程的 namespace 外,还可以查看 /proc/$pid/ns 特殊目录下的文档,proc 目录是 Linux 内核资源映射到文档系统的,都分配有 inode 节点号。

➜ ~ sudo ls -l /proc/1/ns

total 0

lrwxrwxrwx 1 root root 0 2月 4 23:25 cgroup -> 'cgroup:[4026531835]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 ipc -> 'ipc:[4026531839]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 mnt -> 'mnt:[4026531840]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 net -> 'net:[4026532008]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 pid -> 'pid:[4026531836]'

lrwxrwxrwx 1 root root 0 2月 6 15:18 pid_for_children -> 'pid:[4026531836]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 user -> 'user:[4026531837]'

lrwxrwxrwx 1 root root 0 2月 4 23:25 uts -> 'uts:[4026531838]'

namespace 的存活

一般来说当一个namespace中的所有进程都退出时,该namespace将会被销毁。也有例外,比如 ip netns add net0 命令创建一个名为 net0 的 net namespace 之后,没有进程去使用这个 net0,它也不会被销毁。因为从根本上来说,因为它的 inode 节点映射的文档存在。

哈,Linux “一切皆文档”的哲学,只有当 indoe 节点映射的文档都被删除、且没有进程使用这个 inode,inode 对应的资源才会被回收。

于是,如果要保存某一个进程下的 namespace,处理使用新进程继承这些 namespace,还可以通过 mount 方法来挂载这些 namespace 到另外一个文档,例如 mount --bind /proc/$pid/ns/net netFile,这个命令使某一个进程的 net namespace 的 inode 的链接数 +1。那么,即便$pid进程被销毁,只要 netFile 没有被 unlink 删除,该 net namespace 便一直存在。其他进程可以通过 setns 系统调用加入这个 net namespace 。

namespace 相关API

cloneclone, 创建一个新进程,与 fork 类似,但是功能更多,fork 创建的子进程会共享或者复制父进程的资源,而 clone 可以选择性的继承父进程的 namespace 资源,且可以创建并使用新的 namespace。

clone 的 C 语言函数定义:

#define _GNU_SOURCE #include

int clone(int (*fn)(void *), void *child_stack,

int flags, void *arg, ...

/* pid_t *ptid, void *newtls, pid_t *ctid */ );参数child_func传入子进程运行的进程主函数

参数child_stack传入子进程使用的栈空间

参数flags表示使用哪些CLONE_*标志位

参数args则可用于传入用户参数

setnssetns,将当前进程加入到已有的namespace中

setns 的 C 语言函数定义:

#define _GNU_SOURCE/* See feature_test_macros(7) */ #include

int setns(int fd, int nstype);参数 fd 表示我们要加入的namespace的文档描述符。上文已经提到,它是一个指向/proc/[pid]/ns目录的文档描述符,可以通过直接打开该目录下的链接或者打开一个挂载了该目录下链接的文档得到。

参数 nstype, 指定一个或者多个上面的CLONE_NEW*,选择类型

unshare

unshare 使当前进程退出指定类型的namespace,并加入到新创建的namespace

unshare 的 C 语言函数定义:

#define _GNU_SOURCE #include

int unshare(int flags);参数flags表示使用哪些CLONE_*标志位

调用unshare()的主要作用就是不启动一个新进程就可以起到隔离的效果,相当于跳出原先的namespace进行操作。这样,你就可以在原进程进行一些需要隔离的操作。Linux中自带的unshare命令,就是通过unshare()系统调用实现的

Reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值