cgroup和namespace是实现容器底层的重要技术
cgroup:实现资源限制
namespace:实现资源隔离
1.cgroup:control group
Linux操作系统通过cgroup可以设置进程使用CPU,内存和IO资源使用的限额。我们之前学习的通过-m,--memory-swap,-c,--blkio-weight就是通过cgroup实现的。那么cgroup到底是什么样子的呢?
可以在/sys/fs/cgroup里面找到,例如:
我们运行一个容器,我们设置的cpu的权重是700
我们进入/sys/fs/cgroup/cpu/docker目录下的相应的容器的ID的目录里面,看cpu.shares,可以看到我们设置的权重是700
同样的我们进入/sys/fs/cgroup/memory/docker/中大概是memory.limit_in_bytes这个文件是容器内存的大小
同样的我们进入/sys/fs/cgroup/blkio/docker/中,blkio.weight这个文件是Block IO的权重文件
我们可以在以上的文件中,查看或者更改容器资源的大小
2.namespace
我们运行的每一个容器,都像是一个新的操作系统一样,都有文件系统,网卡等资源;那网卡来说,每个容器都会认为自己有一块独立的网卡,即使Host主机实际只有一块网卡资源,这样的方式使容器更像是一个独立的计算机。
namespace管着Host中全局唯一的资源,并让每个容器都觉得只有自己在使用它,namespace实现了容器间的资源隔离
Linux使用了6种namespace:Mount,UTS,IPC,PID,Network
一。Mount namspace:让容器看上去拥有整个文件系统
容器有自己的 / 目录,可执行mount和umount命令。这些操作只对当前的容器生效,不会影响到host和其他容器
对于mount namespace的实验可以参考:https://segmentfault.com/a/1190000006912742
二。UTS namespace:让容器有自己的hostname
默认情况下容器的hostname是他的 短ID ,可以通过 -h或者--hostname来设置容器的主机名
三。IPC namespace:让容器有自己的共享内存和信号量(semaphore)
让容器有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与host以及其他容器的ipc混在一起
四。PID namespace:让容器有自己独立的PID进程
我们知道,容器在host中以进程的形式运行,例如:
docker ps可以看到运行了几个容器
我们通过 ps axf可以看到容器的进程:第一列为容器的PID号
可以看到所有容器的进程都挂在了dockerd进程下,同事可以看到容器的自己的子进程,但是如果我们进入到某个容器里面,ps后只能看到自己的进程了
从这里可以看到容器的PID不同于Host上面对应的PID,容器中PID=1的进程当然也不是host的init进程。这也就证明了容器有自己的一套独立的PID进程
五:Network namespace:让容器有自己独立 的网络资源
Network namespace让容器有自己独立的网卡 ,IP,路由等资源。
六。User namespace :让容器能够管理自己的用户,Host不能看到容器中创建的用户
当我们返回到Hostname上面的时候,切换到同样的用户,可以看到
在容器中创建的用户在host中并不存在