说说linux容器的隔离
- 2020 年 2 月 13 日
- 笔记
前言:
说到docker,大家都懂。但是LXC可能就比较陌生。Docker的起源于LXC。LXC的英文全称是Linux Container,相比较其他虚拟机而言,是一种轻量级虚拟化技术,它介于Chroot(linux的一个改变根目录挂载点的机制)和完整开发的虚拟机之间。LXC不使用单独的内核资源,但是可以创建一个类似的Linux操作系统环境。
Linux Daemon(LXD)是一个轻量级容器管理程序,他是凌驾于LXC之上而衍生的一套外部管理工具。Docker也使用类似技术。LXD使用了LXC API来管理LXC,而且新增RESTful API。
这边文章通过研究LXC的隔离特征来说明容器的一些原理。
一、独立的命名空间
每个容器都有一套独立的Linux环境命名空间。命名空间的作用是对每一个环境做隔离,使用环境的用户来看,好像是一个新的机器环境。命名空间是linux内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。
一套独立的环境需要做到有用户id独立、进程id独立、root根目录独立、网络独立、UTS(UNIX Time-sharing System 的缩写,主机名和NIS域名)独立。
二、用户和用户组ID独立
每个Linux系统要求的uid可选范围都不一样,但是uid通常是由32位,也就是最大值可以是2^31-2(范围:1~4294967295)。路径/etc/login.defs文件的UID_MIN、UID_MAX限定了用户useradd新用户自己设置uid的最小值和最大值,2^31-1是个无效id,实验测试以下命令不能成功。
useradd -u 4294967296 test
Uid的取值区间范围作了划分,不同发行商的Linux系统有不一样的划分,但是一般是这么约定:
- 0-99系统用户uid:
- 100-500:系统管理管理员程序或者安装脚本产生的用户
- 1000-x:用户uid,系统登录uid限制于了登录uid的最小值和最大值
- 网络uid:更偏向于高值
- 6553x:nobody
三、进程ID独立
每个Linux系统要求的pid可选范围都不一样,最大值可以设置到 4194304 (= 222) 。
在64位可以设置到222差不多400w左右。Linux代码设计者认为这个数已经足够了。如果是32位,pid最大值是32768.进程id一旦赋予就不会改变。

每个系统的设置查看cat /proc/sys/kernel/pid_max。
我在ubuntu 16和centos 7分别得到了131072(= 217)和32768(= 215)。
3.1 那如果到达了最大值,会怎么样?
Pid是顺序产生的。当pid到达最大值,它会从0继续开始找最近可用的pid,如果都没有pid,会报错。
四、UTS(hostname独立)
以下测试了hostname在每个命名空间是独立存在的。
unshare --uts --fork bash hostname//查看继承的原来hostname hostname modified //修改成新的hostname hostname //确认修改成功 eixt //退出 hostname //此时hostname还是原来的hostname

五、网络隔离
在每个容器所需要的最少网卡接口包括默认的lo回环link(这个有什么用):
除开lo,一般隔离的网络还有一对veth-pair。除了veth-pair,linux网卡方式还有其他
这个可以使用ip link help查看到。这里提一下,ip是个很强大的命令,包含但不止于ifconfig和route的功能,是个很强大的工具,link这里指的是链路层。对应的ip addr是网络层。
