参考
《极客时间》深入剖析Kubernetes
namespace
所谓namespace,其实就是就是资源视图,典型的例子就是chroot以后,进程能看到的文件系统的视图就局限于某个目录了。namespace是资源隔离的最常用手段。为了保证docker进程看到的视图的一致性,docker镜像打包了自己的文件系统,但是操作系统的隔离需要docker daemon和内核提供。docker使用的namespace有
PID Mount、UTS、IPC、IPC、Network 和 User
cgroups
docker进程其实就是宿主机上的一个普通进程,宿主机器要对这个进程进行资源管理,包括cpu,内存等资源作相应的限制。
mount -t cgroup
cpuset on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cpu on /sys/fs/cgroup/cpu type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
cpuacct on /sys/fs/cgroup/cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct)
blkio on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
memory on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
…
结论
- 容器进程只是操作系统的一个普通进程,从操作系统的角度看并没有什么特殊的
- 所谓的运行环境一致只是从docker进程的角度看的,因为宿主机设置了namespace
- 并不是所有的资源都可以namespace,比如时间和设备驱动
- 容器的可执行文件受限于宿主机的内核,比如宿主机是linux,不可能运行一个mac程序的docker
- 因为宿主机只是在进程启动的时候设置了namespace和cgroup,docker进程启动后跟普通进程一样,所以效率很高,docker daemon只是做个旁路监控而已。所以网络上大部分docker运行原理的图其实是误导的