Docker 簡(jiǎn)介

Docker 兩個(gè)主要部件:
  • Docker: 開源的容器虛擬化平臺(tái)
  • Docker Hub: 用于分享、管理 Docker 容器的 Docker SaaS 平臺(tái) -- Docker Hub

Docker 使用客戶端-服務(wù)器 (C/S) 架構(gòu)模式。Docker 客戶端會(huì)與 Docker 守護(hù)進(jìn)程進(jìn)行通信。Docker 守護(hù)進(jìn)程會(huì)處理復(fù)雜繁重的任務(wù),例如建立、運(yùn)行、發(fā)布你的 Docker 容器。Docker 客戶端和守護(hù)進(jìn)程可以運(yùn)行在同一個(gè)系統(tǒng)上,當(dāng)然你也可以使用 Docker 客戶端去連接一個(gè)遠(yuǎn)程的 Docker 守護(hù)進(jìn)程。Docker 客戶端和守護(hù)進(jìn)程之間通過 socket 或者 RESTful API 進(jìn)行通信。

1.1 Docker 守護(hù)進(jìn)程

Docker 守護(hù)進(jìn)程運(yùn)行在一臺(tái)主機(jī)上。用戶并不直接和守護(hù)進(jìn)程進(jìn)行交互,而是通過 Docker 客戶端間接和其通信。

1.2 Docker 客戶端

Docker 客戶端,實(shí)際上是 docker 的二進(jìn)制程序,是主要的用戶與 Docker 交互方式。它接收用戶指令并且與背后的 Docker 守護(hù)進(jìn)程通信,如此來回往復(fù)。

1.3 Docker 內(nèi)部

要理解 Docker 內(nèi)部構(gòu)建,需要理解以下三種部件:

  • Docker 鏡像 - Docker images
  • Docker 倉(cāng)庫 - Docker registries
  • Docker 容器 - Docker containers

Docker 鏡像

Docker 鏡像是 Docker 容器運(yùn)行時(shí)的只讀模板,每一個(gè)鏡像由一系列的層 (layers) 組成。Docker 使用 UnionFS 來將這些層聯(lián)合到單獨(dú)的鏡像中。UnionFS 允許獨(dú)立文件系統(tǒng)中的文件和文件夾(稱之為分支)被透明覆蓋,形成一個(gè)單獨(dú)連貫的文件系統(tǒng)。正因?yàn)橛辛诉@些層的存在,Docker 是如此的輕量。當(dāng)你改變了一個(gè) Docker 鏡像,比如升級(jí)到某個(gè)程序到新的版本,一個(gè)新的層會(huì)被創(chuàng)建。因此,不用替換整個(gè)原先的鏡像或者重新建立(在使用虛擬機(jī)的時(shí)候你可能會(huì)這么做),只是一個(gè)新 的層被添加或升級(jí)了。現(xiàn)在你不用重新發(fā)布整個(gè)鏡像,只需要升級(jí),層使得分發(fā) Docker 鏡像變得簡(jiǎn)單和快速。

Docker 倉(cāng)庫

Docker 倉(cāng)庫用來保存鏡像,可以理解為代碼控制中的代碼倉(cāng)庫。同樣的,Docker 倉(cāng)庫也有公有和私有的概念。這些鏡像可以是自己創(chuàng)建,或者在別人的鏡像基礎(chǔ)上創(chuàng)建。Docker 倉(cāng)庫是 Docker 的分發(fā)部分。

Docker 容器

Docker 容器和文件夾很類似,一個(gè)Docker容器包含了所有的某個(gè)應(yīng)用運(yùn)行所需要的環(huán)境。每一個(gè) Docker 容器都是從 Docker 鏡像創(chuàng)建的。Docker 容器可以運(yùn)行、開始、停止、移動(dòng)和刪除。每一個(gè) Docker 容器都是獨(dú)立和安全的應(yīng)用平臺(tái),Docker 容器是 Docker 的運(yùn)行部分。

1.4 libcontainer

Docker 從 0.9 版本開始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系統(tǒng)的交互圖如下:


image.png
1.5 命名空間「Namespaces」

pid namespace

不同用戶的進(jìn)程就是通過 pid namespace 隔離開的,且不同 namespace 中可以有相同 PID。具有以下特征:

  • 每個(gè) namespace 中的 pid 是有自己的 pid=1 的進(jìn)程(類似 /sbin/init 進(jìn)程)
  • 每個(gè) namespace 中的進(jìn)程只能影響自己的同一個(gè) namespace 或子 namespace 中的進(jìn)程
  • 因?yàn)?/proc 包含正在運(yùn)行的進(jìn)程,因此在 container 中的 pseudo-filesystem 的 /proc 目錄只能看到自己 namespace 中的進(jìn)程
  • 因?yàn)?namespace 允許嵌套,父 namespace 可以影響子 namespace 的進(jìn)程,所以子 namespace 的進(jìn)程可以在父 namespace 中看到,但是具有不同的 pid

mnt namespace

類似 chroot,將一個(gè)進(jìn)程放到一個(gè)特定的目錄執(zhí)行。mnt namespace 允許不同 namespace 的進(jìn)程看到的文件結(jié)構(gòu)不同,這樣每個(gè) namespace 中的進(jìn)程所看到的文件目錄就被隔離開了。同 chroot 不同,每個(gè) namespace 中的 container 在 /proc/mounts 的信息只包含所在 namespace 的 mount point。

net namespace

網(wǎng)絡(luò)隔離是通過 net namespace 實(shí)現(xiàn)的, 每個(gè) net namespace 有獨(dú)立的 network devices, IP addresses, IP routing tables, /proc/net 目錄。這樣每個(gè) container 的網(wǎng)絡(luò)就能隔離開來。 docker 默認(rèn)采用 veth 的方式將 container 中的虛擬網(wǎng)卡同 host 上的一個(gè) docker bridge 連接在一起。

uts namespace

UTS ("UNIX Time-sharing System") namespace 允許每個(gè) container 擁有獨(dú)立的 hostname 和 domain name, 使其在網(wǎng)絡(luò)上可以被視作一個(gè)獨(dú)立的節(jié)點(diǎn)而非 Host 上的一個(gè)進(jìn)程。

ipc namespace

container 中進(jìn)程交互還是采用 Linux 常見的進(jìn)程間交互方法 (interprocess communication - IPC), 包括常見的信號(hào)量、消息隊(duì)列和共享內(nèi)存。然而同 VM 不同,container 的進(jìn)程間交互實(shí)際上還是 host 上具有相同 pid namespace 中的進(jìn)程間交互,因此需要在IPC資源申請(qǐng)時(shí)加入 namespace 信息 - 每個(gè) IPC 資源有一個(gè)唯一的 32bit ID。

user namespace

每個(gè) container 可以有不同的 user 和 group id, 也就是說可以以 container 內(nèi)部的用戶在 container 內(nèi)部執(zhí)行程序而非 Host 上的用戶。

有了以上 6 種 namespace 從進(jìn)程、網(wǎng)絡(luò)、IPC、文件系統(tǒng)、UTS 和用戶角度的隔離,一個(gè) container 就可以對(duì)外展現(xiàn)出一個(gè)獨(dú)立計(jì)算機(jī)的能力,并且不同 container 從 OS 層面實(shí)現(xiàn)了隔離。 然而不同 namespace 之間資源還是相互競(jìng)爭(zhēng)的,仍然需要類似 ulimit 來管理每個(gè) container 所能使用的資源 - cgroup。

1.6 資源配額「cgroups」

cgroups 實(shí)現(xiàn)了對(duì)資源的配額和度量。 cgroups 的使用非常簡(jiǎn)單,提供類似文件的接口,在 /cgroup 目錄下新建一個(gè)文件夾即可新建一個(gè) group,在此文件夾中新建 task 文件,并將 pid 寫入該文件,即可實(shí)現(xiàn)對(duì)該進(jìn)程的資源控制。
具體的資源配置選項(xiàng)可以在該文件夾中新建子 subsystem ,

{子系統(tǒng)前綴}.{資源項(xiàng)} 

是典型的配置方法, 如 memory.usageinbytes 就定義了該 group 在 subsystem memory 中的一個(gè)內(nèi)存限制選項(xiàng)。 另外,cgroups 中的 subsystem 可以隨意組合,一個(gè) subsystem 可以在不同的 group 中,也可以一個(gè) group 包含多個(gè) subsystem - 也就是說一個(gè) subsystem。

  • memory
    內(nèi)存相關(guān)的限制

  • cpu
    在 cgroup 中,并不能像硬件虛擬化方案一樣能夠定義 CPU 能力,但是能夠定義 CPU 輪轉(zhuǎn)的優(yōu)先級(jí),因此具有較高 CPU 優(yōu)先級(jí)的進(jìn)程會(huì)更可能得到 CPU 運(yùn)算。 通過將參數(shù)寫入 cpu.shares ,即可定義改 cgroup 的 CPU 優(yōu)先級(jí) - 這里是一個(gè)相對(duì)權(quán)重,而非絕對(duì)值

  • blkio
    block IO 相關(guān)的統(tǒng)計(jì)和限制,byte/operation 統(tǒng)計(jì)和限制 (IOPS 等),讀寫速度限制等,但是這里主要統(tǒng)計(jì)的都是同步 IO

  • devices
    設(shè)備權(quán)限限制

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容