雲計算是一種資源的服務模式,該模式能夠實現隨時隨地、便捷按需地從可配置計算資源共享池中獲取所需資源(如網絡、服務器、存儲、應用及服務),資源可以快速供應並釋放,大大減小了資源管理工做開銷。linux
Docker是以Docker容器爲資源分割和調度的基本單位,封裝整個軟件運行時環境,爲開發者和系統管理員設計的,用於構建、發佈和運行分佈式應用的平臺。它是一個跨平臺、可移植而且簡單易用的容器解決方案。Docker的源代碼託管在GitHub上,基於Go語言開發並聽從Apache 2.0協議。Docker可在容器內部快速自動化地部署應用,並經過操做系統內核技術(namespace、cgroups等)爲容器提供資源隔離與安全保障。安全
持續部署與測試:開發人員使用鏡像鏡像實現標準開發環境的構建,開發完成後經過封裝着完整環境和應用的鏡像進行遷移。服務器
跨平臺支持網絡
環境標準化和版本控制架構
高資源利用率與隔離:容器沒有管理程序的額外開銷,與底層共享操做系統,系統負載更低app
容器跨平臺性與鏡像:構建一次,處處運行框架
易於理解且易用socket
應用鏡像倉庫分佈式
容器雲以容器爲資源分割和調度的基本單位,封裝整個軟件運行時環境,爲開發者和系統管理員提供用於構建、發佈和運行分佈式應用的平臺。當容器雲專一於資源共享與隔離、容器編排與部署時,它更接近傳統的IaaS;當容器雲滲透到應用支持與運行時環境使,它更接近傳統的PaaSide
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是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 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文件夾裏。