1.容器其实不是什么新技术,说白了就是namespace对资源进行隔离,再加UFS实现分层镜像,以及cgroup实现资源限制。这些技术,都是linux中已有的技术,而且有些技术很早之前就有了。
2.上面说了,容器就是用了隔离+分层+限制技术,所以和虚拟机是完全不同的东西,虚拟机那是真真正正的一个操作系统。
3.在/roc/pid/ns下,保存着每一个进程对应的namespace,一共6种,分别是:① 进程通信ns(ipc)、② 挂载ns(mnt)、③pid ns、④网络ns(net)、⑤用户ns(user)、⑥隔离hostname和NIS domain name的uts。
一个进程属于哪个namespace,那么就建立一个链接到该namespace。比如下面,我有一个容器,它里面有两个进程,7344和7327:
$ docker top nginx ↵
UID PID PPID C STIME TTY TIME CMD
root : pts/ :: nginx: master process nginx -g daemon off;
: pts/ :: nginx: worker process
看一下这两个在同一个容器中的进程他们的namespace以及cgroup:
sudo ls -l /proc//ns ↵
total
lrwxrwxrwx root root Jan : cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx root root Jan : ipc -> 'ipc:[4026532496]'
lrwxrwxrwx root root Jan : mnt -> 'mnt:[4026532494]'
lrwxrwxrwx root root Jan : net -> 'net:[4026532499]'
lrwxrwxrwx root root Jan : pid -> 'pid:[4026532497]'
lrwxrwxrwx root root Jan : pid_for_children -> 'pid:[4026532497]'
lrwxrwxrwx root root Jan : user -> 'user:[4026531837]'
lrwxrwxrwx root root Jan : uts -> 'uts:[4026532495]'
udo ls -l /proc//ns ✔
total
lrwxrwxrwx Jan : cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx Jan : ipc -> 'ipc:[4026532496]'
lrwxrwxrwx Jan : mnt -> 'mnt:[4026532494]'
lrwxrwxrwx Jan : net -> 'net:[4026532499]'
lrwxrwxrwx Jan : pid -> 'pid:[4026532497]'
lrwxrwxrwx Jan : pid_for_children -> 'pid:[4026532497]'
lrwxrwxrwx Jan : user -> 'user:[4026531837]'
lrwxrwxrwx Jan : uts -> 'uts:[4026532495]'
发现是相同的,说明他们是在同一个namespace中的。
然后我们来看看普通的进程(容器外的),zsh和systemd这连个进程:
sudo ls -l /proc//ns ↵
[sudo] password for xlinliu:
total
lrwxrwxrwx root root Jan : cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx root root Jan : ipc -> 'ipc:[4026531839]'
lrwxrwxrwx root root Jan : mnt -> 'mnt:[4026531840]'
lrwxrwxrwx root root Jan : net -> 'net:[4026532000]'
lrwxrwxrwx root root Jan : pid -> 'pid:[4026531836]'
lrwxrwxrwx root root Jan : pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx root root Jan : user -> 'user:[4026531837]'
lrwxrwxrwx root root Jan : uts -> 'uts:[4026531838]'
ls -l /proc/$$/ns ✔
total
lrwxrwxrwx xlinliu xlinliu Jan : cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx xlinliu xlinliu Jan : ipc -> 'ipc:[4026531839]'
lrwxrwxrwx xlinliu xlinliu Jan : mnt -> 'mnt:[4026531840]'
lrwxrwxrwx xlinliu xlinliu Jan : net -> 'net:[4026532000]'
lrwxrwxrwx xlinliu xlinliu Jan : pid -> 'pid:[4026531836]'
lrwxrwxrwx xlinliu xlinliu Jan : pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx xlinliu xlinliu Jan : user -> 'user:[4026531837]'
lrwxrwxrwx xlinliu xlinliu Jan : uts -> 'uts:[4026531838]'
发现也是一样的,说明他们也是在同意namespace下。另外我们还可以看到有一个 pid_for_children ,这是什么呢?这是因为pid namespace是可以嵌套的,父级可以看到子级的进程的pid,但子级看不到父集,正式因为这样,所以我们在宿主机中,是可以看到所有容器的进程的,并且每个进程都有pid。 比如上面的nginx容器,他的CMD进程在容器里的pid是1,但是在宿主机中也可以看到它,pid是7344。
参考:
1 DOCKER基础技术:LINUX NAMESPACE(上) 以及 DOCKER基础技术:LINUX NAMESPACE(下)