哈喽,我是子牙老师。今天咱们聊聊Linux namespace
瓦特?你没听过namespace?那有必要科普一下了:namespace是Linux内核提供的一种软件性质的资源隔离机制。容器化技术,比如docker,就是基于这样的机制实现的。namespace,是docker依赖的最核心的技术。如果没有namespace,就没有容器化技术,也就没有云原生
甚至可以说,如果没有namespace,云计算都将不复存在
你现在应该知道namespace对今天这个科技世界的重要性了,那你想不想深入了解一下它:
- namespace资源隔离,听起来很抽象,有木有?如何具象理解namespace是如何实现资源隔离的?实现了哪些资源的隔离?
- 所有的进程有默认的namespace吗?还是不配置就没有?
- 如何给进程配置namespace
- 如何从用户态查看进程的namespace
- 如何从内核态查看进程的namespace
- docker exec与namespace的关系
正文开始,enjoy
如果现实中有namespace
比如你爸买了个大house,内部是这样的
过了N年,你生了好几个娃,娃都长大了,一个厕所、厨房不够用了,开始改造大house
Linux namespace差不多就是这种感觉,如果你没有给进程创建新的namespace的时候,所有的进程都在默认的namespace中
如果你给进程100设置了PID namespace,这时候就变成这样了
默认PID namespace中的进程100(100是进程的PID哦),在新的PID namespace中,就变成了PID为1的进程
你以为namespace的功能就只是这样了吗?那你就
它还支持套娃!啥意思呢?如图
什么意思呢?就是容器,是可以嵌套的!就问你牛不牛?
你是不是想问:那能嵌套多少层呢?答案是:无限层!
嗯,写这玩意的哥们一定是个渣男吧!不够专一!如果我来写,我肯定不支持嵌套,这样我肯定是万千女程序员的理想型!
进程默认namespace
现在我们已经知道进程有默认的namespace,如何查看呢?我们先从用户态查看
后面的数字是啥?inode number。底层是通过vfs inode将文件与namespace相关联的
再从内核态查看每个进程的namespace。了解Linux的都知道,Linux中的所有进程都是1号进程的子孙进程,言外之意就是所有进程都会继承1号进程的namespace,来看看是不是这么回事
先看1号进程的namespace信息
再看2号进程的namespace,你会发现是一样的
这时候再看我写的docker进程,因为它底层实现了namespace隔离,所以是不一样的
进程默认的namespace是怎么来的?init_task是0号进程,俗称Linux的始祖进程
对了,你是不是想问:如何从Linux内核态查看namespace?这个你得写内核驱动。这是我准备做的另外一件事:我在研究Linux内核的过程中,写了很多针对查看Linux内核、控制Linux内核的功能,等写到一定程度,我会分享给大家使用。
进程定制不一样的namespace
那如何为进程设置namespace呢?两种方式:
1、可以通过使用函数clone创建进程实现
2、如果是通过fork创建的子进程,通过使用函数unshare为进程配置新的namespace
这两种方式,在docker实现中,都会用到
docker exec底层本质
看到这里,你应该知道答案了吧,你进入对应进程的namespace,就相当于进入了进程
给你个没有答案的问题:如果进程A实现了所有namespace:UTC、IPC、PID、USER、NET、FS,进程B只进入其中的一直可不可以?会带来什么问题?