怎麼理解docker的本質是程式
剛開始學習docker的時候,在ppt中看到,docker本質就是程式,雲裡霧裡,就稀裡糊塗,過了一段時間不用docker,連docker長啥樣都記不起來了。這就是知其然而不知其所然。
而真正能理解docker的本質是程式,必須具備的是linux的基礎知識,從基礎知識角度來進行理解,否則就是霧裡看花,糊里糊塗。
資料上大多介紹,docker的兩大關鍵技術是Namespace和cgroup,以及docker的關鍵創新映象。所以讓我們從linux基礎知識上剖析一下。
Namespace
做個試驗,依次執行如下命令:
sudo docker pull busybox
sudo docker run -it busybox /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps
解釋一下:
setp1: 命令docker pull download下來busybox,busybox是個基礎映象。
setp2: 使用docker run,加上-it引數,執行/bin/sh,建立一個互動式命令視窗(注意如果退出用Ctrl + P + Q,退出互動式視窗,這樣不會關閉容器)
setp3: 執行ps命令
魔力就在這裡了,為何我們看到這裡有兩個程式,一個是剛剛執行的PS,一個是/bin/sh,而且程式號是1,而退出到容器外,使用
ps aux | grep /bin/sh
root 18531 0.0 0.0 1296 4 ? Ss+ 17:19 0:00 /bin/sh
ubuntu 21065 0.0 0.0 13228 928 pts/4 S+ 17:48 0:00 grep --color=auto /bin/sh
只能看到18531這個程式有/bin/sh,這是怎麼實現的呢?
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
注意增加了一個CLONE_NEWPID引數,實施了一個障眼法,在這個程式裡,程式看不到所有它前面的程式,認為自己是1號程式。這就是PID namespace.
而Namespace機制還有 PID, UTS, network, user, mount, IPC,這些Namespace技術改變了容器的檢視,讓容器以為自己在一個房間裡,起到了隔離作用。
Linux Control Group
這個是什麼作用了,就是限制,容器的本質是程式,如上namespace實施了障眼法,對資源進行了隔離,但是如果這個程式把資源都消耗光了,容器就沒有什麼價值了。
在 Linux 中,Cgroups 給使用者暴露出來的操作介面是檔案系統,即它以檔案和目錄的方式組織在作業系統的 /sys/fs/cgroup 路徑下。
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
memory on /run/lxcfs/controllers/memory type cgroup (rw,relatime,memory)
cpuset on /run/lxcfs/controllers/cpuset type cgroup (rw,relatime,cpuset)
freezer on /run/lxcfs/controllers/freezer type cgroup (rw,relatime,freezer)
blkio on /run/lxcfs/controllers/blkio type cgroup (rw,relatime,blkio)
hugetlb on /run/lxcfs/controllers/hugetlb type cgroup (rw,relatime,hugetlb)
pids on /run/lxcfs/controllers/pids type cgroup (rw,relatime,pids)
devices on /run/lxcfs/controllers/devices type cgroup (rw,relatime,devices)
cpu,cpuacct on /run/lxcfs/controllers/cpu,cpuacct type cgroup (rw,relatime,cpu,cpuacct)
net_cls,net_prio on /run/lxcfs/controllers/net_cls,net_prio type cgroup (rw,relatime,net_cls,net_prio)
perf_event on /run/lxcfs/controllers/perf_event type cgroup (rw,relatime,perf_event)
name=systemd on /run/lxcfs/controllers/name=systemd type cgroup (rw,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
可以看到可以限制cpu、記憶體等各類資源。
如果執行
docker run -it --cpu-period=100000 --cpu-quota=20000 busybox /bin/sh
如果檢視 /sys/fs/cgroup/cpu/cpu.cfs_quota_us,會看到20000被寫入到了檔案中,這樣20000/100000,說明寫入到tasks中的程式智慧佔用20%的CPU。這就是限制作用的原理。
namespace和cgroup共同為創造了一個容器沙盒。
容器映象
容器映象不同於虛擬機器映象,虛擬機器映象一般是硬碟的拷貝,非常大,但是容器映象就沒有那麼大,怎麼做的呢?
容器是使用層結構的映象,至少有三層,從上到下依次為:
- 讀寫層
- init層
- 只讀層
(1) 只讀層
是什麼東西呢,只讀層就是基礎映象,做個試驗:
/ # ls
bin dev etc home proc root sys tmp usr var
在namespace試驗中busybox映象中執行ls,可以看到就是一個linux作業系統的系統檔案,而且是精簡版的。這些檔案從哪裡來,從busybox中,按照namespace技術,被mount到容器根目錄下,檢查這裡面的檔案,和容器外的檔案中的內容還是有很大區別。
只讀層的這個映象我們可以在/var/lib/docker/overlay2下可以找到,可以證明上述mount namespace。
(2) init層
初始化的環境變數
(3) 讀寫層
讀寫層就是我們編寫的程式,這些程式會覆蓋下層的檔案
這就是容器映象的方式,由於容器映象可以打包作業系統的檔案,相當於大了原生的系統檔案,所以具備了一致效能力,即打包後隨處下載,都是一樣的。
小結
通過深入linux基礎知識的學習後,我們看到了容器是怎樣的一個存在,是個程式,通過namespace作為障眼法進行遮蔽,通過cgroup進行資源限制,通過容器映象的方式打包的一個沙盒。因此容器的本質就是映象。
對比一下虛擬機器,虛擬機器是虛擬出硬體來,安裝上獨立的作業系統,因此本質上和docker有絕對的不同。
相關文章
- Rollup的本質是什麼?
- 反向代理的本質是什麼?
- 來感性的理解docker,看看docker是什麼吧Docker
- 加密貨幣的本質是什麼?加密
- 敏捷SAFe的本質是什麼?-shalloway敏捷
- 乾淨整潔程式碼(Clean Code)的本質是什麼? - mariocervera
- 領域模型的核心本質是什麼?模型
- 技術實力的本質是什麼?
- iOS-block本質是什麼?iOSBloC
- 深入理解原子操作的本質
- 什麼是物件?什麼是抽象?怎麼理解物件導向的程式設計思想?物件抽象程式設計
- 什麼叫PMP?專案管理的本質是什麼?專案管理
- Java中equals與==的本質區別是什麼?Java
- 淺談人才信用資本探索,大家信夫的本質是什麼
- 防火牆是什麼?怎麼理解?防火牆
- 連載 7 - 測試的本質 - 測什麼、怎麼測
- 程式的本質是數的運算--謝斌分裂起源圖
- 電話營銷機器人的本質是什麼?機器人
- AI智慧與大資料的本質區別是什麼?AI大資料
- STM32暫存器的本質到底是什麼???
- 精益生產流程最佳化的本質是什麼
- 多租戶是什麼意思?怎麼理解?
- JSP 的本質原理解析:"編寫的時候是JSP,心裡想解讀的是 java 原始碼"JSJava原始碼
- Redis系列:深刻理解高效能Redis的本質Redis
- 探尋軟體架構的本質,到底什麼是架構架構
- 探尋軟體架構的本質,到底什麼是架構?架構
- 大家是怎麼程式設計的程式設計
- 程式碼是怎麼執行的?
- DDD本質是分而治之的分析方法 - James Hickey
- 迴歸架構本質,重新理解微服務架構微服務
- 災備是什麼意思?怎麼簡單理解?
- 關於《深入理解計算機系統》 程式碼是怎麼執行的計算機
- 徹底理解遞迴,從遞迴的本質說起!遞迴
- 瞭解紅黑樹的起源,理解紅黑樹的本質
- 型別的本質:對變數、型別、指標的理解型別變數指標
- 三個因素是軟體本質?
- 多執行緒的出現是要解決什麼問題的? 本質什麼?執行緒
- Linux從頭學07:中斷那麼重要,它的本質到底是什麼?Linux