本文介紹Docker架構
一、Docker系統架構
1.Docker基礎架構
1)Docker守護程序
負責容器的建立、運作和監控,以及鏡像的建構和存儲。
docker daemon
2)Docker用戶端
通過HTTP與Docker守護程序通信。
預設使用Unix域套接字(Unix domain socket)實作,但為了支援遠端用戶端也可以使用TCP socket。
Docker用戶端和守護程序是由同一個二進制檔案釋出的。
3)Docker寄存服務
負責存儲和釋出鏡像。(Docker Hub)
當Docker守護程序收到docker pull請求後,便會從寄存伺服器下載下傳鏡像;當遇到docker run請求或Dockerfile中的FROM指令時,若本地沒有所需的鏡像,Docker守護程序會自動從伺服器下載下傳鏡像。
2.底層技術
Docker守護程序通過執行驅動程式(execution driver)來建立容器,它的runc驅動程式與核心功能密不可分。
- cgroups:負責管理容器使用的資源,當機和解凍容器這兩個docker pause指令所需的功能;
- Namespaces:負責容器之間的隔離,確定系統的其他部分與容器的檔案系統、主機名、使用者、網絡和程序分開;
- 聯合檔案系統(Union File System,UFS):負責儲存容器的鏡像層;
3.周邊技術
Swarm:叢集方案
Compose:負責建構和運作由多個容器所組成的應用程式工具(用于開發和測試);
Machine:在本地或遠端資源上安裝和配置Docker主機,配置Docker用戶端,切換環境;
Kitematic:Mac OS和Windows上的GUI,用于運作和管理Dokcer;
Docker Trusted Registry:用于存儲和管理Docker鏡像,Docker Hub的本地版本,與企業的安全架構內建;
網絡連接配接:Weave、Project Calico、Overlay
網絡解決方案:Consul、Registrator、SkyDNS、etcd
服務編排及叢集管理:Kubernetes、Marathon、Fleet、Swarm
存儲系統內建:volume plugin、Flocker、GlusterFS
二、鏡像是如何生成的
1.建構環境的上下文
docker build指令需要Dockerfile和建構環境的上下文(build context)。
上下文是一組本地檔案和目錄,它被Dockerfile的ADD或COPY指令所引用,通常以目錄路徑的形式指定。
docker build -t test/cowsay-dockerfile .
其中“.”就是上下文,即目前目錄,該目錄下的所有檔案和目錄形成建構環境的上下文,并在生成鏡像的過程中傳遞給Docker守護程序。
若沒有指定上下文則被視為空。
注意:不要用“/”作為建構環境的上下文
說明:由于建構環境的上下文會被放進一個tar檔案,然後傳遞給Docker守護程序,是以不要使用一個含有大量檔案的目錄,因為用戶端需要把所有檔案歸檔,交給守護程序(/home/user、downloads),這将花費大量時間處理。
其他方式的上下文:
A.URL以http或https開頭
它會被假定為直接指向Dockerfile的連結,不會與任何上下文關聯
B.git倉庫
Docker用戶端會把倉庫和任何子模組(submodule)複制(clone)至另一個臨時目錄,并把它傳給Docker守護程序作為建構環境的上下文。
以github.com/、git@、git://開頭的路徑被視為git倉庫。
C.STDIN輸入
在提供上下文參數處使用“-”,可以不包含上下文的Dockerfile,或是一個包含上下文及Dockerfile的歸檔檔案。(tar.gz、xz、bzip2)
.dockerignore檔案
從建構環境的上下文中排出不必要的檔案,不支援完整的正則([A-Z]*)
.git (.git會被排除,但dir1/.git不會)
*/.git (dir1/.git會被排除,但.git和dir1/dir2/.git不會)
*/*/.git (dir1/dir2/.git會被排除,但.git和dir1/.git不會)
*.sw? (所有以sw後任一字元為字尾的檔案會被排除,但dir1/test.swp不會)
2.鏡像層
Dockerfile中的每個指令執行後都會産生一個新的鏡像層,這個鏡像層可以用來啟動容器,一個新的鏡像層的建立,是用上一層的鏡像啟動容器,然後執行Dockerfile的指令後,把它儲存為一個新的鏡像。
當Dockerfile指令成功執行後,中間使用過的容器将被删除,除非使用--rm=false參數。
注意:
雖然可以在RUN指令中執行持久的程序(SSH、MYSQL),但到下個指令或啟動容器時,就不再運作了,除非使用ENTRYPOINT或CMD指令啟動。
檢視所有鏡像層
當建構失敗時,可以将失敗前的那個層啟動起來
FROM busybox:latest
RUN echo "This should work"
RUN /bin/bash -c echo "This won't"
之後開始建構鏡像:
docker build -t echotest .
分析:
1)Docker為了執行指令而建立一個臨時容器,配置設定容器ID
2)配置設定該容器所建立的鏡像ID
3)将臨時容器删除
3.緩存
Docker為了加速鏡像建構速度,會将每一個鏡像層緩存下來。
但是想要使用緩存,指令必須滿足以下條件:
- 上一個指令能夠在緩存中找到
- 緩存中存在一個鏡像層,而它的指令和你的指令一模一樣,父層也完全相同
- 在使用COPY和ADD指令時,如果他們引用檔案的校驗和或中繼資料發生變化,緩存也将失效
緩存失效
docker build --no-cache
4.基礎鏡像
當建立自己的鏡像時,你需要決定從哪個基礎鏡像開始。
不同鏡像會共享相同的基礎鏡像層,比如你已經有了ubuntu:14:04鏡像,然後從Hub又下載下傳一個基于它的鏡像,那麼你隻會得到它在基礎鏡像之上改變過的部分,而非整個鏡像。
重建鏡像
當執行docker build時,Docker會檢視FROM指令所指定的鏡像,若本地沒有則下載下傳,若本地有則使用,而不會先檢查有沒有更新的版本。
這意味着必須對所有被依賴的父鏡像顯式地執行docker pull或删除,使build指令下載下傳最新版。
5.Dockerfile指令
Exec:需要一個JSON數組,如[“executable”,“param1”,“param2”]
Shell:自由形式的字元串,字元串會傳遞給/bin/sh -c執行
可用指令集:
ADD
從建構環境上下文或遠端URL複制檔案至鏡像。
CMD
當容器啟動時執行指定的指令。多個CMD隻有最後一個生效。
COPY
與ADD作用相同。不能指定上下文以外的src路徑
COPY src dest
COPY ["src","dest"]
ENTRYPOINT
設定一個容器啟動時運作的可執行檔案以及預設參數。
常用于提供“啟動”腳本,目的是在解析參數前,對變量和服務進行初始化。
ENV
設定鏡像内的環境變量。可被随後的指令引用。
EXPOSE
向Docker表示該容器将會有一個程序監聽所指定的端口。
FROM
設定Dockerfile使用的基礎鏡像。
MAINTAIER
把鏡像中的作者中繼資料設定為指定的字元串。
ONBUILD
指定當鏡像被用作另一個鏡像的基礎鏡像時會執行的指令。
例如:把代碼從一個已標明的目錄中複制出來,并在執行建構腳本時使用它。
RUN
在容器内執行指定的指令,并把結果儲存下來。
USER
設定任何後續的RUN、CMD或ENTRYPOINT指令執行時所用的使用者。
注意:UID在主機和容器中時相同的,但使用者名則可能被配置設定到不同的UID。
VOLUME
指定為資料卷的檔案或目錄。
WORKDIR
對任何後續的RUN、CMD、ENTRYPOINT、ADD或COPY指令設定工作目錄。