Docker 用 Go 編程語言編寫,並利用 Linux 內核的多個功能。Docker 的底層大約使用以下幾項技術組合而成:

  1. Namespace
  2. Control groups
  3. Union file systems
  4. Container format

Namespace

namespace 是 Linux Kernel 內的一種資源分隔技術,每個 container 都有自己單獨的 namespace ,執行在其中的應用都像是在獨立的作業系統中執行一樣。namespace 保證了 container 之間彼此互不影響。Docker 中使用 namespace 來隔離 container 之間的工作區,像是把 Process ID、User ID、Network 等的環境執行狀態隔離開來。

當建立並運行 (run) container 時,Docker 會先幫 container 創建一組 namespace,這些 namespace 為 container 之間的資源提供了一層隔離,每個 container 都在單獨的 namespace 中運行,並且限制只能訪問該 namespace。

Docker Engine 在 Linux 上使用以下 namespace:

pid namespace

不同使用者的程式就是透過 pid namespace隔離開的,且不同 namespace 中可以有相同 pid。所有的 LXC (Linux Container) 程式在 Docker 中的父程式為 Docker 程式,每個 LXC 程式具有不同的namespace。同時由於允許巢狀結構,因此可以很方便的實作巢狀結構的 Docker container。

舉個例子來說在一台實體機器上,有 2 個 Namespace,Namespace 1 和 Namepsace2。Namespace 1 裡面的 PID 有 1,Namespace 2 的 PID 也可以有 1 的 PID,這樣就做到執行環境上 PID 的隔離。如下圖:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9aebf883-54b9-4a1a-a0f4-72f74fc7beb7/3.png

net namespace

有了 pid namespace,每個 namespace 中的 pid 能夠相互隔離,但是網路連接埠還是共享 host 的連接埠。網路隔離是透過 net namespace 實作的, 每個 net namespace 有獨立的網路設備, IP 位址, 路由表, /proc/net 目錄。這樣每個 container 的網路就能隔離開來。Docker 預設採用 veth 的方式,將 container 中的虛擬網卡同 host 上的一個 Docker 橋接器 docker0 連接

ipc namespace