雲計算平台
雲計算是一種資源的服務模式,該模式可以實現隨時隨地、便捷按需地從可配置計算資源共享池中獲取所需資源(如網絡、服務器、存儲、應用及服務),資源能夠快速供應並釋放,大大減少了資源管理工作開銷。
Docker
Docker是以Docker容器為資源分割和調度的基本單位,封裝整個軟件運行時環境,為開發者和系統管理員設計的,用於構建、發布和運行分布式應用的平台。它是一個跨平台、可移植並且簡單易用的容器解決方案。Docker的源代碼托管在GitHub上,基於Go語言開發並遵從Apache 2.0協議。Docker可在容器內部快速自動化地部署應用,並通過操作系統內核技術(namespace、cgroups等)為容器提供資源隔離與安全保障。
-
持續部署與測試:開發人員使用鏡像鏡像實現標准開發環境的構建,開發完成后通過封裝着完整環境和應用的鏡像進行遷移。
-
跨平台支持
-
環境標准化和版本控制
-
高資源利用率與隔離:容器沒有管理程序的額外開銷,與底層共享操作系統,系統負載更低
-
容器跨平台性與鏡像:構建一次,到處運行
-
易於理解且易用
-
應用鏡像倉庫
容器雲
容器雲以容器為資源分割和調度的基本單位,封裝整個軟件運行時環境,為開發者和系統管理員提供用於構建、發布和運行分布式應用的平台。當容器雲專注於資源共享與隔離、容器編排與部署時,它更接近傳統的IaaS;當容器雲滲透到應用支持與運行時環境使,它更接近傳統的PaaS
namespace資源隔離
Docker容器本質上是宿主機上的進程。Docker通過namespace實現了資源隔離,通過cgroups實現了資源限制,通過寫時復制機制(copy-on-write)實現了高效的文件操作
Docker的namespace一般有以下幾種。如果兩個進程指向的namespace編號相同,就說明它們在同一個namespace下,否則便在不同的namespace里面
Linux內核實現namespace的一個主要目的就是實現輕量級虛擬化容器服務,在同一個namespace下的進程可以感知彼此的變化,而對外界的進程一無所知,以達到獨立和隔離的目的。
root@ht:~# ls -l /proc/$$/ns total 0 lrwxrwxrwx 1 root root 0 7月 9 20:00 cgroup -> cgroup:[4026531835] lrwxrwxrwx 1 root root 0 7月 9 20:00 ipc -> ipc:[4026531839] lrwxrwxrwx 1 root root 0 7月 9 20:00 mnt -> mnt:[4026531840] lrwxrwxrwx 1 root root 0 7月 9 20:00 net -> net:[4026531957] lrwxrwxrwx 1 root root 0 7月 9 20:00 pid -> pid:[4026531836] lrwxrwxrwx 1 root root 0 7月 9 20:00 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 7月 9 20:00 uts -> uts:[4026531838]
1)UTS namespace
UTS(UNIX Time-sharing System)namespace提供了主機名和域名的隔離,這樣每個Docker容器就可以擁有獨立的主機名和域名了,在網絡上可以被視為一個獨立的節點。
2)IPC namespace
進程間通信(Inte-process Communication,IPC)涉及的IPC資源包括常見的信號量、消息隊列和共享內存。申請IPC資源就申請了一個全局唯一的32位ID,所以IPC namespace中實際上包含了系統IPC標識符以及實現POSIX消息隊列的文件系統。在同一個IPC namespace下的進程彼此可見,不同IPC namespace下的進程則互相不可見。
Docker當前使用IPC namespace實現了容器與宿主機、容器與容器之間的IPC隔離
3)PID namespace
PID namespace對進程PID重新標號,即兩個不同namespace下的進程可以有相同的PID。每個PID namespace都有自己的計數程序。內核為所有的PID namespace維護了一個樹狀結構,最頂層的是系統初始時創建的,被稱為root namespace。它創建的新PID namespace被稱為child namespace,而原先的PID namespace就新創建的PID namespace的parent namespace。通過這種方式,不同的PID namespace會形成一個層次體系。所屬的父節點可以看到子節點的進程,並可以通過信號等方式對子節點中的進程產生影響,但子節點卻不能看到夫節點PID namespace中的任何內容。
4)mount namespace
mount namespace通過隔離文件系統掛載點對隔離文件系統提供支持。隔離后不同mount namespace中的文件結構發生變化也互不影響。進程在創建mount namespace時,會把當前的文件結構復制給新的namespace。新namespace中的所有mount操作都只影響自身的文件系統。
共享關系:如果兩個掛載對象具有共享關系,那么一個掛載對象中的掛載事件會傳播到另一個掛載對象,反之亦然
從屬關系:如果兩個掛載對象形成從屬關系,那么一個掛載對象中的掛載事件會傳播到另一個掛載對象,但是反之不行。從屬對象是事件的接收者。
5)network namespace
network namespace主要提供關於網絡資源的隔離,包括網絡設備、IPv4和IPv6協議棧、IP路由表、防火牆、、socket等。一個物理的網絡設備最多存在於一個network namespace中,可以通過創建veth pair(虛擬網絡設備對:有兩端,類似通道)在不同的network namespace間創建通道,以達到通信目的。
6)user namespace
user namespace主要隔離了安全相關的標志符(identifier)和屬性(attribute),包括用戶ID,用戶組ID,root目錄,密鑰及特殊權限。一個普通用戶的進程通過clone()創建的新進程在新user namespace中可以擁有不同的用戶和用戶組。這意味着一個進程在容器外屬於一個沒有特權的普通用戶,但是它創建的容器進程卻屬於擁有所有權限的超級用戶
cgroups資源限制
cgroups是linux內核提供的一種機制,這種機制可以根據需求把一系列系統任務及其子任務整合(或分隔)到按資源划分等級的不同組內,從而為系統資源管理提供一個統一的框架。通俗地說,cgroups可以限制、記錄任務組所使用的物理資源(包括CPU,Memory,IO等)。本質上來說,cgroups是內核附加在程序上的一系列鈎子(hook),通過程序運行時對資源的調度觸發相應的鈎子以達到資源追蹤和限制的目的。
cgroups有如下四個特點:
1)cgroups的API以一個偽文件系統的方式實現,用戶態的程序可以通過文件操作實現cgroups的組織管理
2)cgroups的組織管理操作單元可以細粒度到線程級別,另外用戶可以創建和銷毀cgroup,從而實現資源再分配和管理
3)所有資源管理的功能都以子系統的方式實現,接口統一
4)子任務創建之初與其父任務處於同一個cgroups的控制組
cgroups有以下四大功能:
1)資源限制:對任務使用的資源總額進行限制
2)優先級分配:控制分配的CPU時間片數及磁盤IO帶寬的大小
3)資源統計:統計系統的資源使用量
4)任務控制:對任務執行掛起、恢復等操作
cgroups術語
task(任務):表示系統的一個進程或線程
cgroup(控制組):表示按某種資源控制標准划分而成的任務組。包含一個或多個子系統。一個任務可以加入某個cgroup,也可以從某個cgroup遷移到另外一個cgroup.
subsystem(子系統):資源調度控制器
hierarchy(層級):層級由一系列cgroup以樹狀結構排列而成,每個層級通過綁定對應的子系統進行資源控制。層級中的cgroup節點可以包含零或多個子節點,子節點繼承夫節點掛載的子系統。整個操作系統可以有多個層級。
Docker總體架構
Docker daemond
從圖中可以看出Docker daemon是Docker最核心的后台進程,它負責響應來自Docker client的請求,然后將這些請求翻譯成系統調用完成容器管理操作。該進程會在后台啟動一個API Server,負責接收由Docker client發送的請求;接收到的請求將通過Docker daemon分發調度,再由具體的函數來執行請求。
execdriver是對Linux操作系統的namespace、cgroups、apparmor等容器運行所需的系統進行的一層二次封裝。execdriver的默認實現是Docker官方編寫的libcontainer庫
network由libnetwork庫獨立維護。libnetwork庫抽象出了一個容器網絡模型(Container Network Model, CNM),並給調用者提供一個統一的抽象接口,
graphdriver是所有與容器鏡像相關操作的最終執行者。graphdriver會在Docker工作目錄下維護一組與鏡像層對應的目錄,並記下鏡像層之間的關系以及與具體的graphdriver實現相關的元數據。這樣用戶對鏡像的操作最終會被映射成對這些目錄文件以及元數據的增刪查改,從而屏蔽掉不同文件存儲實現對於上層調用者的影響。
Docker client
Docker client是一個泛稱,用來向Docker daemon發起請求,執行相應的容器管理操作。它既可以是命令行工具Docker,也可以是任何遵循了Docker API的客戶端
鏡像管理
distribution負責與Docker registry交互,上傳下載鏡像以及存儲與v2 registry有關的元數據
registry模塊負責與Docker registry有關的身份驗證、鏡像查找、鏡像驗證以及管理registry mirror等交互操作
image模塊負責與鏡像元數據有關的存儲、查找,鏡像層的索引、查找以及鏡像tar包有關的導入導出等操作。
reference負責存儲本地所有鏡像的repository和tag名,並維護與鏡像ID之間的映射關系
layer模塊負責與鏡像層和容器元數據有關的增刪查改,並負責將鏡像層的增刪查改操作映射到實際存儲鏡像層文件系統的graphdriver模塊
volumedriver是volume數據卷存儲操作的最終執行者,負責volume的增刪查改,屏蔽不同的驅動實現的區別,為上層調用者提供一個統一的接口。Docker中作為默認實現的volumedriver是local,默認將文件存儲在Docker根目錄的volume文件夾里。