您好,登錄后才能下訂單哦!
本篇內容介紹了“docker容器底層技術怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在沒有探討是否包含操作系統之前,大家一起來看兩張圖片,如下所示:
很容易可以辨別出,圖一docker引擎畫在了應用底部,類似于虛擬機的位置,docker虛擬化技術替代了虛擬機,更輕量級,看上去更容易理解和接受;
圖二docker引擎畫在了應用的側邊欄,從圖片上看,進程則是直接運行在虛擬機上,docker容器更多的是進行旁路式的輔助和管理;其它沒什么區別,其中圖一也是PPT和網上常見的作圖方式,這種方式真的正確嗎?下文揭曉。
docker底層主要是通過cgroup和namespace兩種技術實現,cgroup實現資源限額, namespace實現資源隔離。
這兩個概念看起來非常抽象,其實一起來看個例子,一切就明白了,執行docker exec -it 5080b69f08c4 /bin/bash
[root@tomcat-7c5857b68f-fzrbr /]# ps aux|grep tomcat
root 1 79.1 23.4 10168216 3788616 ? Ssl Oct22 8559:52 /usr/java/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 109 0.0 0.0 9052 668 pts/0 S+ 19:24 0:00 grep --color=auto tomcat
在容器內部執行ps之后出現兩個進程在運行,一個是我的服務,另外一個是我剛剛執行的ps,已經看到容器內部進程已經跟我們的宿主機中的服務完全隔離開了。這其實就是對被隔離應用的進程空間做了隔離,使得這些進程空間下的進程只能看到重新計算之后的進程編號,這就是linux的namespace機制,linux底層是通過clone()函數實現,而當在docker中創建進程時就可以通過指定參數返回一個全新的進程空間,這樣的話的就做到了pid為1的目的,其實你到宿主機上查看下,這個docker中運行的服務,在宿主機上存在著同樣的進程,只不過這個進程的pid是真實的pid。
除了剛才我們提到的pid namespace隔離技術,Linux還為我們提供了Mount、UTS、IPC、Network、User等隔離機制,其效果都是為進程上下文起到隔離作用,使我們只能看到指定的內容。
上面剛剛說了,namespace只是對進程做了隔離,使其在容器內部看不到宿主機的進程,但是對于宿主機來說,還是能夠看到這些被隔離的進程。換句話說,這些被隔離的進程跟宿主機上的其它進程完全沒什么區別。所以說上述例子中的tomcat依然可以隨意占用宿主機的資源?其實docker利用了linux底層的Cgroup進行了資源限制。
Linux Cgroups 的全稱是 Linux Control Group。它最主要的作用,就是限制一個進程組能夠使用的資源上限,包括 CPU、內存、磁盤、網絡帶寬等.
進入容器內部/sys/fs/cgroup/文件夾下面,里面包含了很多子目錄,通過這些目錄中的文件內容就可以實現對各種資源的限制。
看到這里,再品一下,容器就是一個進程而已。
什么叫一個進程?你剛才上面舉的例子,不是在tomcat容器中執行了一個ps,這明明是兩個進程,在說了,我也可以在這個容器中運行其它服務,這些也都是正常運行的進程,這怎么能說是一個進程呢?不信的話,你進到看看nginx容器中ps看下,它的進程更多。
root 1 0.0 0.0 54952 4416 ? Ss Oct29 0:00 nginx: master process /usr/xshj/openresty/nginx/sbin/nginx -g daemon off;
xshj 6 0.0 0.1 76164 23380 ? S Oct29 0:00 nginx: worker process
xshj 7 0.0 0.1 76164 23380 ? S Oct29 0:00 nginx: worker process
xshj 8 0.0 0.1 76164 23392 ? S Oct29 0:00 nginx: worker process
xshj 9 0.0 0.1 76300 23392 ? S Oct29 0:00 nginx: worker process
root 25 0.0 0.0 12484 992 pts/0 S+ 18:47 0:00 grep --color=auto nginx
其實我說的一個進程指的是只有一個進程是受docker控制的,其它進程雖然也在運行,但是他們不受docker的控制,它們都是野進程,如果主的掛了,其它的都得跟著玩完。這也是為什么在編寫Dockerfile的時候,CMD中的命令不能后臺運行的原因,簡單來說,docker僅在它的1號進程(PID為1)運行時,會保持運行。如果1號進程退出了,Docker容器也就退出了。這個問題也是新手或者沒有從事過docker相關開發的同學經常碰到的問題,我的容器剛剛啟動,怎么就exit了呢?因為它需要一個前臺進程把它hang住。比如在執行nginx命令的時候,我們會使用ENTRYPOINT [ "/usr/sbin/nginx", "-g", "daemon off;" ]
容器單進程并不是指容器里只能運行"一個"進程而是指容器沒有管理多進程的能力。這是因為容器里PID=1的進程就是應用本身,其他的進程都是PID=1進程的子進程。
再說了,Pod是k8s調度的最小單位,為什么不能是容器,而需要搞出一個Pod的概念?因為容器單進程模式,而Pod則是進程組。通過進程組的概念,Pod能夠把容器 "有原則的" 組織到一起運行,從而能夠進行每個容器的管理。而k8s需要做的工作就是將 "進程組" 的概念映射到容器技術中。
其實docker的核心技術可以總結為:為待創建進程的容器開啟namespace配置、指定Cgroup參數、切換容器根目錄。本質上來說也就是運行在宿主機上的普通進程而已。
表示不服,容器技術從誕生至今一直反復強調的特性就是一致性,你這說的和普通進程沒什么區別,如何保證一致性?答案很簡單,docker鏡像不僅能夠打包應用,還能打包整個操作系統的文件和目錄,記住是操作系統的文件和目錄。通過這種方式docker就把一個應用所有的依賴庫包括操作系統中的文件和目錄都被打包到鏡像中。docker正是通過打包操作系統級別的方式,解決了開發到線上環境的一致性。
搞明白容器的本質之后,你就可以解決很多現實問題,比如:我有一個老項目,兩個服務之間是緊密耦合的,如果按照k8s中Pod的編排思想,改動成本非常高。這個時候,就可以考慮把這個兩個服務打包到一個鏡像中,并且其中一個進程作為主進程啟動,另外一個后臺運行。但后臺運行的進程就需要你自己管理了,說白了,服務掛了也沒人知道。這也是為什么說k8s Pod能夠把多個緊密關聯的進程有組織的管理在一起的原因。
說了半天,容器就是運行在宿主機上的一個資源被限制、視圖被隔離的進程;那一個宿主機操作系統只有一個內核,也就是說,所有的容器都依賴這一個內核了?比如我現在有一個需求,我的兩個容器運行在同一臺宿主機上,但是依賴的內核版本不一樣,或者需要配置的內核參數不一樣,怎么解決呢?解決不了,這也是容器化技術相比于虛擬機的主要缺陷之一。
網上搜索下,到處充斥著docker能夠打包操作系統的言論,這句話其實是不準確的,而且容易讓人誤解docker的能力。下面先來看一組概念內核,操作系統和發行版之間的區別。
Linux內核是Linux操作系統的核心部分。這就是Linus最初寫的。
Linux操作系統是內核和用戶域(庫,GNU實用程序,配置文件等)的組合。
Linux發行版是Linux操作系統的特定版本,例如Debian,CentOS或Alpine。
大多數在編寫Dockerfile時都會顯式或隱式地依賴于運行在容器中的某種Linux操作系統的特定發行版本,比如:
$ cat <<EOF > Dockerfile
FROM alpine:3.7
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]
EOF
$ docker build -t mysql-alpine .
$ docker run mysql-alpine
對于剛剛開始學習容器技術的同學來說,這可能導致一種錯誤的印象,docker是操作系統級別的隔離,而且總是基于眾所周知的和廣泛分布的Linux發行版本debian,centos或alpine等。結合上面所說的docker容器啟動后,只是運行在宿主機上的一個進程,理所當然依賴于宿主機的內核。這里又打包了一個完整的操作系統,怎么回事呢?
其實linux操作系統中代碼包含兩部分,一部分是文件目錄和配置,另外一部分是內核,這兩部分是分開存放的,系統只有在宿主機開機啟動時才會加載內核模塊。說白了,即使鏡像中包含了內核也不會被加載。說到最后,原來鏡像只是包含了操作系統的軀干(文件系統),并沒有包含操作系統的靈魂(內核)。
“docker容器底層技術怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。