Docker基本原理與基礎概念
簡介
Docker是一個開放原始碼軟體專案,讓應用程式佈署在軟體容器下的工作可以自動化進行,藉此在Linux作業系統上,提供一個額外的軟體抽象層,以及作業系統層虛擬化的自動管理機制。
Docker利用Linux核心中的資源分離機制,例如cgroups,以及Linux核心名字空間(name space),來建立獨立的軟體容器(containers)。這可以在單一Linux實體下運作,避免啟動一個虛擬機器造成的額外負擔。Linux核心對名字空間的支援完全隔離了工作環境中應用程式的視野,包括程序樹、網路、使用者ID與掛載檔案系統,而核心的cgroup提供資源隔離,包括CPU、儲存器、block I/O與網路。從0.9版本起,Dockers在使用抽象虛擬是經由libvirt的LXC與systemd - nspawn提供介面的基礎上,開始包括libcontainer庫做為以自己的方式開始直接使用由Linux核心提供的虛擬化的設施,
Docker特點
- 靈活:即使是最複雜的應用也可以集裝箱化。
- 輕量級:容器利用並共享主機核心。
- 可互換:即時部署更新和升級。
- 行動式:在本地構建,部署到雲,並在任何地方執行。
- 可擴充套件:增加並自動分發容器副本。
- 可堆疊:垂直和即時堆疊服務。
容器和虛擬機器
容器和虛擬機器具有類似的資源隔離和分配優勢,但功能不同,因為容器虛擬化作業系統而不是硬體。容器更便攜,更高效。
容器是應用層的抽象,它將程式碼和依賴關係打包在一起。多個容器可以在同一臺機器上執行,並與其他容器共享作業系統核心,每個容器在使用者空間中作為獨立程序執行。容器佔用的空間比VM少(容器映像的大小通常為幾十MB),可以處理更多的應用程式,並且需要更少的VM和作業系統。
虛擬機器(VM)是物理硬體的抽象,將一臺伺服器轉變為多臺伺服器。虛擬機器管理程式允許多臺虛擬機器在一臺計算機上執行。每個VM都包含作業系統的完整副本,應用程式,必要的二進位制檔案和庫 - 佔用數十GB。虛擬機器也可能很慢啟動。
Docker的三大元件
映象(Image)
通過執行映象啟動容器。映象是一個可執行包,包含執行應用程式所需的所有內容 - 程式碼,執行時,庫,環境變數和配置檔案。Docker 執行容器前需要本地存在對應的映象,如果本地不存在該映象,Docker 會從映象倉庫
下載該映象
容器(container)
容器是影象的執行時例項,
倉庫(Repository)
存放映象的地方,一個容易混淆的概念是註冊伺服器(Registry ) 。實際上註冊伺服器是管理倉庫的具體服務
器,每個伺服器上可以有多個倉庫,而每個倉庫下面有多個映象。從這方面來說,倉庫可以
被認為是一個具體的專案或目錄。例如對於倉庫地址 dl.dockerpool.com/ubuntu 來說, dl.dockerpool.com 是註冊伺服器地址, ubuntu 是倉庫名。
我們來看一個圖簡單說明一下三者之間的關係
- 基於映象建立容器(run),也可以基於容器製作映象(commit)
- 從遠端倉庫拉取映象(pull),將本地映象推送到遠端(push)
Docker底層實現
基本架構
Docker 採用了 C/S 架構,包括客戶端和服務端。Docker 守護程序 (Daemon ) 作為服務端接受來自客戶端的請求,並處理這些請求(建立、執行、分發容器)
Docker 守護程序一般在宿主主機後臺執行,等待接收來自客戶端的訊息。
Docker 客戶端則為使用者提供一系列可執行命令,使用者用這些命令實現跟 Docker 守護程序交
互。
預設情況下,Docker守護程式偵聽UNIX套接字上的連線以接受來自本地客戶端的請求。通過將Docker配置為偵聽IP地址和埠以及UNIX套接字,可以允許Docker接受來自遠端主機的請求。
名稱空間(Namespace)
名稱空間是 Linux 核心一個強大的特性。每個容器都有自己單獨的名稱空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名稱空間保證了容器之間彼此互不影響。
- pid 名稱空間
pid名稱空間隔離程序id號,這意味著不同pid名稱空間中的程序可以具有相同的pid。允許巢狀,因此可以很方便的實現巢狀的 Docker 容器 - net 名稱空間
網路隔離是通過 net 名稱空間實現的, 每個 net 名稱空間有獨立的 網路裝置, IP 地址, 路由表, /proc/net 目錄。這樣每個容器的網路就能隔離開來。Docker 預設採用 veth 的方式,將容器中的虛擬網絡卡同 host 上的一 個Docker 網橋 docker0 連線在一起。 - ipc 名稱空間
容器中程序互動還是採用了 Linux 常見的程序間互動方法(interprocess communication - IPC),包括訊號量、訊息佇列和共享記憶體等。然而同 VM 不同的是,容器的程序間互動實際上還是host 上具有相同 pid 名稱空間中的程序間互動,因此需要在 IPC 資源申請時加入名稱空間資訊,每個 IPC 資源有一個唯一的 32 位 id。 - mnt 名稱空間
類似 chroot,將一個程序放到一個特定的目錄執行。mnt 名稱空間允許不同名稱空間的程序看到的檔案結構不同,這樣每個名稱空間 中的程序所看到的檔案目錄就被隔離開了。同chroot 不同,每個名稱空間中的容器在 /proc/mounts 的資訊只包含所在名稱空間的 mountpoint。 - uts 名稱空間
UTS(“UNIX Time-sharing System”) 名稱空間允許每個容器擁有獨立的 hostname 和 domainname, 使其在網路上可以被視作一個獨立的節點而非 主機上的一個程序。 - user 名稱空間
每個容器可以有不同的使用者和組 id, 也就是說可以在容器內用容器內部的使用者執行程式而非主機上的使用者
控制組(cgroups)
控制組(cgroups) 是 Linux 核心的一個特性,主要用來對共享資源進行隔離、限制、審計等。只有能控制分配到容器的資源,才能避免當多個容器同時執行時的對系統資源的競爭。控制組可以提供對容器的記憶體、CPU、磁碟 IO 等資源的限制和審計管理。名稱空間主要是實現了系統資源的隔離,而cgroups則是負責資源的分配
聯合檔案系統
Docker採用了分層構建的機制,最底層為bootfs,在此之上為rootfs
-
bootfs主要是用於系統引導的檔案系統,一旦引導完成就會將bootfs這一層解除安裝掉,它的存活時間非常短。
-
rootfs表現為Docker容器的根檔案系統,傳統模式中,系統啟動之時,核心掛載rootfs時會首先將其掛載為“只讀”模式,完整性自檢完成後將其重新掛載為讀寫模式;docker中,rootfs由核心掛載為“只讀”模式,而後通過“聯合掛載 ”技術額外掛載一個“可寫”層;
啟動一個容器的時候,Docker會在映象上附加一層可寫層,頂層以下都只是可讀,這時候使用者刪除底層檔案,並不是真正刪除而只是標記為不可見,但是實際上檔案在底層還是存在的。如果使用者需要修改底層檔案,Docker將底層檔案複製到頂層讓你進行修改,同時底層檔案也是存在的,只是當你讀修改後的檔案的時候指向的位置是頂層而不是原來的底層檔案了。
圖片全部來自網上,如有侵權,聯絡作者刪除
qq:835311324
參考連結