docker是利用linux的namespace隔離技術為基礎,通過共享Linux內核實現的。
簡單說,docker容器是縮小型的linux。是在宿主機基礎上,把內核隔離出來的。因為不論什么發行版(ubuntu-apt ,,,centos-yum)內核都一樣,就是軟件安裝包管理方式不同,可定制的界面不同。
一、共享內核
首先需要區分Linux內核與Linux發行版
-
Linux內核是Linux操作系統的核心, 負責硬件管理, 比如管理內存、管理磁盤(文件系統)、管理CPU(進程)等等...
-
Linux發行版是在Linux內核的基礎上添加了一些工具軟件,比如圖形界面、函數庫、軟件包管理系統等等...
CentOS與Ubuntu是不同的Linux發行版, 它們都是基於Linux內核(內核是統一唯一的), 只是添加的工具軟件不同。比如, 他們的軟件包管理系統不同, CentOS使用yum命令安裝軟件, 而Ubuntu使用apt-get命令安裝軟件。
因此CentOS與Ubuntu的內核是相同的(版本可能不同), 只是所安裝的軟件不同, 即文件系統不同。
Docker容器技術是基於Linux內核實現的, 它主要用到了兩個內核模塊:
-
Namespace: 用於容器的隔離, 例如PID Namespace使得容器中的進程無法感知宿主機以及其他容器中的進程。
-
Cgroups: 用於容器的資源控制, 比如限制容器所使用的內存大小或者CPU個數。
在CentOS上運行基於Ubuntu鏡像的容器時, 容器使用了CentOS主機的內核以及Ubuntu鏡像, Ubuntu鏡像中安裝了Ubuntu的各種軟件(apt-get)。
二、隔離機制
簡單來說,Linux Namespace 是操作系統內核在不同進程間實現的一種「環境隔離機制」。
舉例來說:現在有兩個進程A,B。他們處於兩個不同的 PID Namespace 下:ns1, ns2。在ns1下,A 進程的 PID 可以被設置為1,在 ns2 下,B 進程的 PID 也可以設置為1。但是它們兩個並不會沖突,因為 Linux PID Namespace 對 PID 這個資源在進程 A,B 之間做了隔離。A 進程在 ns1下是不知道 B 進程在 ns2 下面的 PID 的。
這種環境隔離機制是實現容器技術的基礎。因為在整個操作系統的視角下,一個容器表現出來的就是一個進程。
Linux 一共構建了 6 種不同的 Namespace,用於不同場景下的隔離:
- Mount - isolate filesystem mount points
- UTS - isolate hostname and domainname
- IPC - isolate interprocess communication (IPC) resources
- PID - isolate the PID number space
- Network - isolate network interfaces
- User - isolate UID/GID number spaces