天天看點

Docker容器技術-Docker架構

本文介紹Docker架構

一、Docker系統架構

1.Docker基礎架構

Docker容器技術-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指令啟動。

檢視所有鏡像層

Docker容器技術-Docker架構

當建構失敗時,可以将失敗前的那個層啟動起來

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指令設定工作目錄。