?? 關(guān)于作者
大家好,我是秋意零。
?? CSDN作者主頁
- ?? 博客主頁
?? 簡介
- ?? 普通本科生在讀
- 在校期間參與眾多計(jì)算機(jī)相關(guān)比賽,如:?? “省賽”、“國賽”,斬獲多項(xiàng)獎(jiǎng)項(xiàng)榮譽(yù)證書
- ?? 各個(gè)平臺(tái),秋意零/秋意臨 賬號(hào)創(chuàng)作者
- ?? 云社區(qū) 創(chuàng)建者
點(diǎn)贊、收藏+關(guān)注下次不迷路!
歡迎加入云社區(qū)
一、為什么會(huì)出現(xiàn)容器?
- 我們來假設(shè)一個(gè)場(chǎng)景,某個(gè)客戶向某個(gè)公司定制了一個(gè)產(chǎn)品,經(jīng)過2個(gè)月的使用這個(gè)產(chǎn)品終于完成了,并且在>自己公司中也是可以安全運(yùn)行的,這個(gè)時(shí)候就需要到客戶哪里交付,需要現(xiàn)場(chǎng)安裝部署。
- 在安裝部署過程中,需要在客戶哪里準(zhǔn)備好自己產(chǎn)品的運(yùn)行環(huán)境,由于產(chǎn)品比較大,配置環(huán)境是非常浪費(fèi)時(shí)間和精力的,而且這個(gè)過程中或許還會(huì)出現(xiàn)自己公司沒有遇到過的問題。
- 顯然這種傳統(tǒng)方式,是需要優(yōu)化改進(jìn)的。這個(gè)時(shí)候就出現(xiàn)了容器部署,
容器解決了應(yīng)用打包的這個(gè)根本難題
當(dāng)然還要其它應(yīng)用場(chǎng)景,這里只是說明一個(gè)舉例。
二、容器是什么?
緊跟上面的例子:
容器解決了應(yīng)用打包的這個(gè)根本難題
- 這個(gè)打包包含應(yīng)用環(huán)境和應(yīng)用本身,就是說可以打包自己應(yīng)用和環(huán)境,這就是一個(gè)鏡像,有了這個(gè)鏡像,我們只需要攜帶這個(gè)鏡像到客戶現(xiàn)場(chǎng)運(yùn)行這個(gè)鏡像就行了,這時(shí)運(yùn)行的鏡像就稱為容器。
- 容器其實(shí)是一種沙盒技術(shù)。顧名思義,沙盒就是能夠像一個(gè)集裝箱一樣,把你的應(yīng)用“裝”起來的技術(shù)。這樣,應(yīng)用與應(yīng)用之間,就因?yàn)?strong>有了邊界而不至于相互干擾;而被裝進(jìn)集裝箱的應(yīng)用,也可以被方便地搬來搬去。
專業(yè)名詞:
- image: 鏡像包含應(yīng)用和應(yīng)用環(huán)境
- contaienr: 容器是鏡像的運(yùn)行出來的狀態(tài)
- registry: 倉庫是存放鏡像的地方
容器本身沒有太大價(jià)值,有價(jià)值的是“容器編排” (相當(dāng)于是說,技術(shù)本身沒有價(jià)值,價(jià)值在于解決實(shí)際問題)
- 編排主要是容器之間的關(guān)系,也之所以 Kubernetes 項(xiàng)目和CNCF社區(qū) 火的原因之一
這里簡單提一嘴: Kubernetes 可以看作是操作系統(tǒng),而容器就是應(yīng)用程序進(jìn)程
三、容器“邊界”的實(shí)現(xiàn)手段
3.1、進(jìn)程如何運(yùn)行的?
- 假如,你要寫一個(gè)計(jì)算加減法的程序,這個(gè)程序需要的輸入來自一個(gè)文件,計(jì)算結(jié)果輸出到另一個(gè)文件
- 因?yàn)橛?jì)算機(jī)只認(rèn)識(shí)二進(jìn)制 0 和 1,不管用什么語言編寫,都需要將這段代碼編譯成二進(jìn)制文件,這樣計(jì)算機(jī)才能運(yùn)行。
- 我們知道我們的數(shù)據(jù)(程序)是存放在磁盤當(dāng)中的,運(yùn)行程序時(shí)需要將磁盤數(shù)據(jù)放入內(nèi)存中,這樣CPU、寄存器和內(nèi)存協(xié)作計(jì)算,還有被打開的文件,以及各種各樣的 I/O 設(shè)備在不斷地調(diào)用中修改自己的狀態(tài),這個(gè)程序就運(yùn)行起來了。
- 一旦“程序”被執(zhí)行起來,它就從磁盤上的二進(jìn)制文件,變成了內(nèi)存中的數(shù)據(jù)、寄存器里的值、堆棧中的指令、被打開的文件,以及各種設(shè)備的狀態(tài)信息的一個(gè)集合。這樣的一個(gè)程序運(yùn)行集合就是我們的今天的主角:進(jìn)程
- 所以,對(duì)于進(jìn)程來說,它的靜態(tài)表現(xiàn)是程序,存放在磁盤中;動(dòng)態(tài)表現(xiàn)是進(jìn)程,數(shù)據(jù)和狀態(tài)的集合。
3.2、Namespace 與 Docker 邊界
- 而容器技術(shù)的核心功能,就是通過約束和修改進(jìn)程的動(dòng)態(tài)表現(xiàn),從而為其創(chuàng)造出一個(gè)“邊界”。
- 對(duì)于 Docker 等大多數(shù) Linux 容器,Cgroups 技術(shù)是用來制造約束的主要手段,而 Namespace 技術(shù)則是用來修改進(jìn)程視圖的主要方法。
可能覺得 Cgroups 和 Namespace 這兩個(gè)概念很抽象,我們一起動(dòng)手實(shí)踐一下,就很容易理解這兩項(xiàng)技術(shù)了。
我們使用 docker run
運(yùn)行一個(gè)鏡像容器,-it
參數(shù)是分配一個(gè)文本輸入/輸出環(huán)境,TTY
[root@master01 ~]# docker run -it busybox /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps
可以看到,我們第一個(gè)進(jìn)程號(hào)是
PID=1
,并且運(yùn)行的是/bin/sh
命令,還有一個(gè)就是我們剛才執(zhí)行的ps
命令
可以看到,我們已經(jīng)被 Docker 隔離在一個(gè)跟宿主機(jī)完全不同的環(huán)境當(dāng)中。
容器的本質(zhì)是一個(gè)進(jìn)程
宿主機(jī)上我們執(zhí)行 ps 命令可以看到,宿主機(jī)上有個(gè)進(jìn)程,這個(gè)進(jìn)程是我們運(yùn)行容器時(shí)所使用的命令,也代表了我們?nèi)萜饕彩且粋€(gè)進(jìn)程表現(xiàn)出來的,所以
容器的本質(zhì)是一個(gè)進(jìn)程
。
[root@master01 ~]# ps -aux | grep "/bin/sh"
...
root 97285 0.3 0.2 933264 21796 pts/0 Sl+ 11:33 0:00 docker run -it busybox /bin/sh
...
為了表現(xiàn)這個(gè)容器是進(jìn)程我們做一個(gè)實(shí)驗(yàn)
- 首先連接工具開兩個(gè)窗口
- 一個(gè)運(yùn)行的是
docker run -it busybox /bin/sh
這樣一條命令- 另一個(gè)執(zhí)行
ps -aux | grep "/bin/sh"
找到這里的docker run -it busybox /bin/sh
進(jìn)程,執(zhí)行kill -9 97285
(這里通過 ps 命令可以看到我的容器 PID 是97285)殺掉這個(gè)進(jìn)程,如圖可以看到docker run -it busybox /bin/sh
進(jìn)程退出了,說明了容器的本質(zhì)是一個(gè)進(jìn)程
。
這是怎么做到的呢?
- 本來,每當(dāng)我們?cè)谒拗鳈C(jī)上運(yùn)行了一個(gè)
/bin/sh
程序時(shí),操作系統(tǒng)都會(huì)給它分配一個(gè)進(jìn)程編號(hào),比如 PID=1000。 進(jìn)程編號(hào)具有唯一標(biāo)識(shí),就像員工的工號(hào),所以我們可以看作 /bin/sh 是公司里的第 1000 名員工,而 1 號(hào)員工就是老板,管理全局的人。- 現(xiàn)在,我們通過 Docker 把這個(gè)
/bin/sh
程序運(yùn)行在一個(gè)容器中。這時(shí),Docker 就會(huì)在這個(gè) 1000 號(hào)員工入職時(shí)給他一個(gè)“障眼法”,讓他永遠(yuǎn)看不到前面的其他 999 個(gè)員工,更看不到老板。這樣,他就會(huì)以為自己第 1 號(hào)員工。
這種機(jī)制,其實(shí)就是對(duì)被隔離應(yīng)用的進(jìn)程空間做了手腳,也就是使用了 Linxu 中的 Namespace 技術(shù)。
這種 Namespace 使用方式,其實(shí)是 Linux 創(chuàng)建新進(jìn)程的一個(gè)可選參數(shù),比如:
# 創(chuàng)建一個(gè)新的進(jìn)程,并且返回它的進(jìn)程號(hào) pid
int pid = clone(main_function, stack_size, SIGCHLD, NULL);
而當(dāng)我們用 clone() 系統(tǒng)調(diào)用創(chuàng)建一個(gè)新進(jìn)程時(shí),就可以在參數(shù)中指定 CLONE_NEWPID 參數(shù)(新PID),比如:
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
這時(shí),新創(chuàng)建的這個(gè)進(jìn)程將會(huì)“看到”一個(gè)全新的進(jìn)程空間,在這個(gè)進(jìn)程空間里,它的 PID 是 1。之所以說“看到”,是因?yàn)檫@只是一個(gè)“障眼法”,在宿主機(jī)真實(shí)的進(jìn)程空間里,這個(gè)進(jìn)程的 PID 還是真實(shí)的數(shù)值,比如 100。
- 我們還可以多次執(zhí)行上面的 clone() 調(diào)用,這樣就會(huì)創(chuàng)建多個(gè) PID Namespace,而每個(gè) Namespace 里的應(yīng)用進(jìn)程,都會(huì)認(rèn)為自己是當(dāng)前容器里的第 1 號(hào)進(jìn)程
- 除了我們剛剛用到的 PID Namespace,Linux 操作系統(tǒng)還提供了 Mount、UTS、IPC、Network 和 User 這些 Namespace,用來對(duì)各種不同的進(jìn)程上下文進(jìn)行“障眼法”操作。
- 比如,Mount Namespace,用于讓被隔離進(jìn)程只看到當(dāng)前 Namespace 里的掛載點(diǎn)信息;Network Namespace,用于讓被隔離進(jìn)程看到當(dāng)前 Namespace 里的網(wǎng)絡(luò)設(shè)備和配置。
這,就是 Linux 容器最基本的實(shí)現(xiàn)原理了
Docker 容器這個(gè)聽起來玄而又玄的概念,實(shí)際上是在創(chuàng)建容器進(jìn)程時(shí),指定了這個(gè)進(jìn)程所需要啟用的一組 Namespace 參數(shù)。這樣,容器就只能“看”到當(dāng)前 Namespace 所限定的資源、文件、設(shè)備、狀態(tài),或者配置。而對(duì)于宿主機(jī)以及其他不相關(guān)的程序,它就完全看不到了。
所以說,容器,其實(shí)是一種特殊的進(jìn)程而已。
總結(jié)
相信大家學(xué)容器時(shí)都看過這個(gè)虛擬機(jī)和容器的對(duì)比圖。
-
左邊是虛擬機(jī)的工作原理,其中 Hypervisor 軟件是虛擬機(jī)最重要的部分,它可以實(shí)現(xiàn)模擬出各種硬件,比如:CPU、內(nèi)存、磁盤等,在 Hypervisor 軟件層之上創(chuàng)建 Guest OS 也就是客戶機(jī)操作系統(tǒng),Guest OS 和 Hypervisor 模擬出來的硬件交互 ,這樣用戶應(yīng)用程序就可以運(yùn)行在這個(gè)虛擬機(jī)中,用戶自然看到的就是這個(gè)新的操作系統(tǒng)的文件系統(tǒng)結(jié)構(gòu),這也是虛擬機(jī)也能起到將不同應(yīng)用程序相互隔離的原因。
-
右邊,則用一個(gè)名為 Docker Engine 的軟件替換了 Hypervisor。這也是為什么,很多人會(huì)把 Docker 項(xiàng)目稱為“輕量級(jí)”虛擬化技術(shù)的原因,實(shí)際上就是把虛擬機(jī)的概念套在了容器上。這樣的說明并不嚴(yán)謹(jǐn),因?yàn)?容器本質(zhì)是運(yùn)行在宿主機(jī)上的進(jìn)程,使用的是 Namespace 技術(shù),通過 Namespace 技術(shù)實(shí)現(xiàn)網(wǎng)絡(luò)、磁盤、PID、用戶等隔離。
相信你此刻已經(jīng)會(huì)心一笑:容器隔離不過都是“障眼法”罷了。
? 最后
?? 我是秋意臨,歡迎大家一鍵三連、加入云社區(qū)
?? 我們下期再見(⊙o⊙)!?。?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-433137.html
參考
參考《深入剖析Kubernetes》作者 張磊文章來源地址http://www.zghlxwxcb.cn/news/detail-433137.html
到了這里,關(guān)于【云原生-深入理解Kubernetes-1】容器的本質(zhì)是進(jìn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!