作者| 阿里巴巴高階開發工程師 傅偉
在介紹容器的具體概念之前,先簡單回顧一下作業系統是如何管理程序的。
首先,當我們登入到作業系統之後,可以通過 ps 等操作看到各式各樣的程序,這些程序包括系統自帶的服務和使用者的應用程序。那麼,這些程序都有什麼樣的特點?
這樣的三個特點會帶來什麼問題呢?
針對上述的三個問題,如何為程序提供乙個獨立的執行環境呢?
那麼,應該如何定義這樣的程序集合呢?
其實,容器就是乙個檢視隔離、資源可限制、獨立檔案系統的程序集合。所謂「檢視隔離」就是能夠看到部分程序以及具有獨立的主機名等;控制資源使用率則是可以對於記憶體大小以及 cpu 使用個數等進行限制。容器就是乙個程序集合,它將系統的其他資源隔離開來,具有自己獨立的資源檢視。
容器具有乙個獨立的檔案系統,因為使用的是系統的資源,所以在獨立的檔案系統內不需要具備核心相關的**或者工具,我們只需要提供容器所需的二進位制檔案、配置檔案以及依賴即可。只要容器執行時所需的檔案集合都能夠具備,那麼這個容器就能夠執行起來。
綜上所述,我們將這些容器執行時所需要的所有的檔案集合稱之為容器映象。
那麼,一般都是通過什麼樣的方式來構建映象的呢?通常情況下,我們會採用 dockerfile 來構建映象,這是因為 dockerfile 提供了非常便利的語法糖,能夠幫助我們很好地描述構建的每個步驟。當然,每個構建步驟都會對已有的檔案系統進行操作,這樣就會帶來檔案系統內容的變化,我們將這些變化稱之為 changeset。當我們把構建步驟所產生的變化依次作用到乙個空資料夾上,就能夠得到乙個完整的映象。
changeset 的分層以及復用特點能夠帶來幾點優勢:
第三,因為映象資料是共享的,因此可以節約大量的磁碟空間,簡單設想一下,當本地儲存具有了 alpine 映象和 golang 映象,在沒有復用的能力之前,alpine 映象具有 5m 大小,golang 映象有 300m 大小,因此就會占用 305m 空間;而當具有了復用能力之後,只需要 300m 空間即可。
如下圖所示的 dockerfile 適用於描述如何構建 golang 應用的。
如圖所示:
from 行表示以下的構建步驟基於什麼映象進行構建,正如前面所提到的,映象是可以復用的;
workdir 行表示會把接下來的構建步驟都在哪乙個相應的具體目錄下進行,其起到的作用類似於 shell 裡面的 cd;
copy 行表示的是可以將宿主機上的檔案拷貝到容器映象內;
run 行表示在具體的檔案系統內執行相應的動作。當我們執行完畢之後就可以得到乙個應用了;
cmd 行表示使用映象時的預設程式名字。
當有了 dockerfile 之後,就可以通過 docker build 命令構建出所需要的應用。構建出的結果儲存在本地,一般情況下,映象構建會在打包機或者其他的隔離環境下完成。
執行乙個容器一般情況下分為三步:
第三步:當選中映象之後,就可以通過 docker run 來執行這個映象得到想要的容器,當然可以通過多次執行得到多個容器。乙個映象就相當於是乙個模板,乙個容器就像是乙個具體的執行例項,因此映象就具有了一次構建、到處執行的特點。
簡單回顧一下,容器就是和系統其它部分隔離開來的程序集合,這裡的其他部分包括程序、網路資源以及檔案系統等。而映象就是容器所需要的所有檔案集合,其具備一次構建、到處執行的特點。
容器是一組具有隔離特性的程序集合,在使用 docker run 的時候會選擇乙個映象來提供獨立的檔案系統並指定相應的執行程式。這裡指定的執行程式稱之為 initial 程序,這個 initial 程序啟動的時候,容器也會隨之啟動,當 initial 程序退出的時候,容器也會隨之退出。
因此,可以認為容器的生命週期和 initial 程序的生命週期是一致的。當然,因為容器內不只有這樣的乙個 initial 程序,initial 程序本身也可以產生其他的子程序或者通過 docker exec 產生出來的運維操作,也屬於 initial 程序管理的範圍內。當 initial 程序退出的時候,所有的子程序也會隨之退出,這樣也是為了防止資源的洩漏。
但是這樣的做法也會存在一些問題,首先應用裡面的程式往往是有狀態的,其可能會產生一些重要的資料,當乙個容器退出被刪除之後,資料也就會丟失了,這對於應用方而言是不能接受的,所以需要將容器所產生出來的重要資料持久化下來。容器能夠直接將資料持久化到指定的目錄上,這個目錄就稱之為資料卷。
資料卷有一些特點,其中非常明顯的就是資料卷的生命週期是獨立於容器的生命週期的,也就是說容器的建立、執行、停止、刪除等操作都和資料卷沒有任何關係,因為它是乙個特殊的目錄,是用於幫助容器進行持久化的。簡單而言,我們會將資料卷掛載到容器內,這樣一來容器就能夠將資料寫入到相應的目錄裡面了,而且容器的退出並不會導致資料的丟失。
通常情況下,資料卷管理主要有兩種方式:
moby 是目前最流行的容器管理引擎,moby daemon 會對上提供有關於容器、映象、網路以及 volume的管理。moby daemon 所依賴的最重要的元件就是 containerd,containerd 是乙個容器執行時管理引擎,其獨立於 moby daemon ,可以對上提供容器、映象的相關管理。
containerd 底層有 containerd shim 模組,其類似於乙個守護程序,這樣設計的原因有幾點:
本節課程只是針對於 moby 進行乙個大致的介紹,在後續的課程也會詳細介紹。
vm 利用 hypervisor 虛擬化技術來模擬 cpu、記憶體等硬體資源,這樣就可以在宿主機上建立乙個 guest os,這是常說的安裝乙個虛擬機器。
每乙個 guest os 都有乙個獨立的核心,比如 ubuntu、centos 甚至是 windows 等,在這樣的 guest os 之下,每個應用都是相互獨立的,vm 可以提供乙個更好的隔離效果。但這樣的隔離效果需要付出一定的代價,因為需要把一部分的計算資源交給虛擬化,這樣就很難充分利用現有的計算資源,並且每個 guest os 都需要占用大量的磁碟空間,比如 windows 作業系統的安裝需要 10~30g 的磁碟空間,ubuntu 也需要 5~6g,同時這樣的方式啟動很慢。正是因為虛擬機器技術的缺點,催生出了容器技術。
容器是針對於程序而言的,因此無需 guest os,只需要乙個獨立的檔案系統提供其所需要檔案集合即可。所有的檔案隔離都是程序級別的,因此啟動時間快於 vm,並且所需的磁碟空間也小於 vm。當然了,程序級別的隔離並沒有想象中的那麼好,隔離效果相比 vm 要差很多。
總體而言,容器和 vm 相比,各有優劣,因此容器技術也在向著強隔離方向發展。
K8S容器編排YAML詳解
k8s 集群中對資源管理和資源物件編排部署都可以通過宣告樣式 yaml 檔案來解決,也就是可以把需要對資源物件操作編輯到yaml格式檔案中,一般使用 yaml 格式的檔案來建立符合我們預期期望的 pod 我們把這種檔案叫做資源清單檔案,通過 kubectl 命令直接使用資源清單檔案就可以實現對大量的...
k8s 容器鉤子
有兩個鉤子暴露在容器中 poststart 這個鉤子在建立容器之後立即執行。但是,不能保證鉤子會在容器入口點之前執行。沒有引數傳遞給處理程式。kind deployment metadata name testlifecycle labels spec replicas 1 selector mat...
k8s學習記錄1 docker概念,k8s概念
目錄 docker對比虛擬機器 容器的隔離技術 docker概念 為什麼需要k8s?k8s概念 docker更加輕量級 每個虛擬機器需要執行自己的一組系統程序 虛擬機器的主要好處 它們能提供完全隔離的環境,因為它們都執行在自己linux核心上。linux命名空間隔離 檔案,程序,網路介面,主機名等 ...