1.容器其實不是什麼新技術,說白了就是namespace對資源進行隔離,再加UFS實現分層鏡像,以及cgroup實現資源限制。這些技術,都是linux中已有的技術,並且有些技術很早以前就有了。html
2.上面說了,容器就是用了隔離+分層+限制技術,因此和虛擬機是徹底不一樣的東西,虛擬機那是真真正正的一個操做系統。linux
3.在/roc/pid/ns下,保存着每個進程對應的namespace,一共6種,分別是:① 進程通訊ns(ipc)、② 掛載ns(mnt)、③pid ns、④網絡ns(net)、⑤用戶ns(user)、⑥隔離hostname和NIS domain name的uts。nginx
一個進程屬於哪一個namespace,那麼就創建一個連接到該namespace。好比下面,我有一個容器,它裏面有兩個進程,7344和7327:docker
$ docker top nginx 1 ↵ UID PID PPID C STIME TTY TIME CMD root 7344 7327 0 22:07 pts/0 00:00:00 nginx: master process nginx -g daemon off; 101 7376 7344 0 22:07 pts/0 00:00:00 nginx: worker process
看一下這兩個在同一個容器中的進程他們的namespace以及cgroup:shell
sudo ls -l /proc/7344/ns 2 ↵ total 0 lrwxrwxrwx 1 root root 0 Jan 16 22:08 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 ipc -> 'ipc:[4026532496]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 mnt -> 'mnt:[4026532494]' lrwxrwxrwx 1 root root 0 Jan 16 22:07 net -> 'net:[4026532499]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 pid -> 'pid:[4026532497]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 pid_for_children -> 'pid:[4026532497]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 user -> 'user:[4026531837]' lrwxrwxrwx 1 root root 0 Jan 16 22:08 uts -> 'uts:[4026532495]'
udo ls -l /proc/7376/ns ✔ total 0 lrwxrwxrwx 1 101 101 0 Jan 16 22:10 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 ipc -> 'ipc:[4026532496]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 mnt -> 'mnt:[4026532494]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 net -> 'net:[4026532499]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 pid -> 'pid:[4026532497]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 pid_for_children -> 'pid:[4026532497]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 user -> 'user:[4026531837]' lrwxrwxrwx 1 101 101 0 Jan 16 22:10 uts -> 'uts:[4026532495]'
發現是相同的,說明他們是在同一個namespace中的。segmentfault
而後咱們來看看普通的進程(容器外的),zsh和systemd這連個進程:網絡
sudo ls -l /proc/1/ns 2 ↵ [sudo] password for xlinliu: total 0 lrwxrwxrwx 1 root root 0 Jan 16 22:06 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 ipc -> 'ipc:[4026531839]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 mnt -> 'mnt:[4026531840]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 net -> 'net:[4026532000]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 pid -> 'pid:[4026531836]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 pid_for_children -> 'pid:[4026531836]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 user -> 'user:[4026531837]' lrwxrwxrwx 1 root root 0 Jan 16 22:06 uts -> 'uts:[4026531838]'
ls -l /proc/$$/ns ✔ total 0 lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 cgroup -> 'cgroup:[4026531835]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 ipc -> 'ipc:[4026531839]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 mnt -> 'mnt:[4026531840]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 net -> 'net:[4026532000]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 pid -> 'pid:[4026531836]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 pid_for_children -> 'pid:[4026531836]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 user -> 'user:[4026531837]' lrwxrwxrwx 1 xlinliu xlinliu 0 Jan 16 22:05 uts -> 'uts:[4026531838]'
發現也是同樣的,說明他們也是在贊成namespace下。另外咱們還能夠看到有一個 pid_for_children ,這是什麼呢?這是由於pid namespace是能夠嵌套的,父級能夠看到子級的進程的pid,但子級看不到父集,正式由於這樣,因此咱們在宿主機中,是能夠看到全部容器的進程的,而且每一個進程都有pid。 好比上面的nginx容器,他的CMD進程在容器裏的pid是1,可是在宿主機中也能夠看到它,pid是7344。dom
參考:spa
1 DOCKER基礎技術:LINUX NAMESPACE(上) 以及 DOCKER基礎技術:LINUX NAMESPACE(下)操作系統