Docker 底層實現

2022-04-07 00:37:47 字數 2419 閱讀 7771

docker 採用了 c/s架構,包括客戶端和服務端。 docker daemon 作為服務端接受來自客戶的請求,並處理這些請求(建立、執行、分發容器)。 客戶端和服務端既可以執行在乙個機器上,也可通過 socket 或者 restful api 來進行通訊

docker daemon 一般在宿主主機後台執行,等待接收來自客戶端的訊息。 docker 客戶端則為使用者提供一系列可執行命令,使用者用這些命令實現跟 docker daemon 互動

名字空間是 linux 核心乙個強大的特性。每個容器都有自己單獨的名字空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名字空間保證了容器之間彼此互不影響。

不同使用者的程序就是通過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 lxc 程序在 docker 中的父程序為docker程序,每個 lxc 程序具有不同的名字空間。同時由於允許巢狀,因此可以很方便的實現巢狀的 docker 容器。

有了 pid 名字空間, 每個名字空間中的 pid 能夠相互隔離,但是網路埠還是共享 host 的埠。網路隔離是通過 net 名字空間實現的, 每個 net 名字空間有獨立的 網路裝置, ip 位址, 路由表, /proc/net 目錄。這樣每個容器的網路就能隔離開來。docker 預設採用 veth 的方式,將容器中的虛擬網絡卡同 host 上的一 個docker 網橋 docker0 連線在一起。

容器中程序互動還是採用了 linux 常見的程序間互動方法(interprocess communication - ipc), 包括訊號量、訊息佇列和共享記憶體等。然而同 vm 不同的是,容器的程序間互動實際上還是 host 上具有相同 pid 名字空間中的程序間互動,因此需要在 ipc 資源申請時加入名字空間資訊,每個 ipc 資源有乙個唯一的 32 位 id。

類似 chroot,將乙個程序放到乙個特定的目錄執行。mnt 名字空間允許不同名字空間的程序看到的檔案結構不同,這樣每個名字空間 中的程序所看到的檔案目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的資訊只包含所在名字空間的 mount point。

uts("unix time-sharing system") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網路上可以被視作乙個獨立的節點而非 主機上的乙個程序。

每個容器可以有不同的使用者和組 id, 也就是說可以在容器內用容器內部的使用者執行程式而非主機上的使用者

控制組(cgroups)是 linux 核心的乙個特性,主要用來對共享資源進行隔離、限制、審計等。只有能控制分配到容器的資源,才能避免當多個容器同時執行時的對系統資源的競爭。

控制組技術最早是由 google 的程式設計師 2006 年起提出,linux 核心自 2.6.24 開始支援。

控制組可以提供對容器的記憶體、cpu、磁碟 io 等資源的限制和審計管理

聯合檔案系統(unionfs)是一種分層、輕量級並且高效能的檔案系統,它支援對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同乙個虛擬檔案系統下(unite several directories into a single virtual filesystem)。

聯合檔案系統是 docker 映象的基礎。映象可以通過分層來進行繼承,基於基礎映象(沒有父映象),可以製作各種具體的應用映象。

另外,不同 docker 容器就可以共享一些基礎的檔案系統層,同時再加上自己獨有的改動層,大大提高了儲存的效率。

docker 中使用的 aufs(anotherunionfs)就是一種聯合檔案系統。 aufs 支援為每乙個成員目錄(類似 git 的分支)設定唯讀(readonly)、讀寫(readwrite)和寫出(whiteout-able)許可權, 同時 aufs 裡有乙個類似分層的概念, 對唯讀許可權的分支可以邏輯上進行增量地修改(不影響唯讀部分的)。

最初,docker 採用了 lxc 中的容器格式。自 1.20 版本開始,docker 也開始支援新的 libcontainer 格式,並作為預設選項

首先,要實現網路通訊,機器需要至少乙個網路介面(物理介面或虛擬介面)來收發資料報;此外,如果不同子網之間要進行通訊,需要路由機制。

docker 中的網路介面預設都是虛擬的介面。虛擬介面的優勢之一是**效率較高。 linux 通過在核心中進行資料複製來實現虛擬介面之間的資料**,傳送介面的傳送快取中的資料報被直接複製到接收介面的接收快取中。對於本地系統和容器內系統看來就像是乙個正常的乙太網卡,只是它不需要真正同外部網路裝置通訊,速度要快很多。

docker 容器網路就利用了這項技術。它在本地主機和容器內分別建立乙個虛擬介面,並讓它們彼此連通(這樣的一對介面叫做veth pair

docker 建立乙個容器的時候,會執行如下操作:

完成這些之後,容器就可以使用 eth0 虛擬網絡卡來連線其他容器和其他網路。

可以在docker run的時候通過--net引數來指定容器的網路配置,有4個可選值:

Docker 底層實現

docker 底層的核心技術包括 linux 上的命名空間 namespaces 控制組 control groups union 檔案系統 union file systems 和容器格式 container format 我們知道,傳統的虛擬機器通過在宿主主機中執行 hypervisor 來模擬...

Docker底層原理

docker底層原理 docker 是乙個client server結構的系統,docker守護程序執行在主機上 然後通過socket連線從客戶端訪問,守護程序從客戶端接受命令並管理執行在主機上的容器。後台守護程序docker daemon docker 為啥子比vm快 1.docker 有著比虛擬...

Docker底層原理

docker是乙個c s架構的系統,docker守護程序執行在主機上,然後通過socket連線從客戶端訪問,守護程序從客戶端接收命令並管理執行在主機上的容器。容器是乙個執行時環境。docker比vm快 docker有著比虛擬機器更少的抽象層。由於docker不需要hypervisor實現硬體資源虛擬...