淺談Docker三兩事

Docker 究竟是個什麼東西呢?咱們在理解 Docker 以前,首先得先區分清楚兩個概念,容器和虛擬機。
可能不少人都用過虛擬機,而對容器這個概念比較的陌生。咱們用的傳統虛擬機如 VMware , VisualBox 之類的須要模擬整臺機器包括硬件。
每臺虛擬機都須要有本身的操做系統,虛擬機一旦被開啓,預分配給它的資源將所有被佔用。
每一臺虛擬機包括應用,必要的二進制和庫,以及一個完整的用戶操做系統。
而容器技術是和咱們的宿主機共享硬件資源及操做系統,能夠實現資源的動態分配。
容器包含應用和其全部的依賴包,可是與其餘容器共享內核。容器在宿主機操做系統中,在用戶空間以分離的進程運行。
容器技術是實現操做系統虛擬化的一種途徑,可讓您在資源受到隔離的進程中運行應用程序及其依賴關係。
經過使用容器,咱們能夠輕鬆打包應用程序的代碼、配置和依賴關係,將其變成容易使用的構建塊,從而實現環境一致性、運營效率、開發人員生產力和版本控制等諸多目標。
容器能夠幫助保證應用程序快速、可靠、一致地部署,其間不受部署環境的影響。
容器還賦予咱們對資源更多的精細化控制能力,讓咱們的基礎設施效率更高。
經過下面這幅圖,咱們能夠很直觀的反映出這二者的區別所在:
淺談Docker三兩事
Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用接口。它是目前最流行的 Linux 容器解決方案。
而 Linux 容器是 Linux 發展出的另外一種虛擬化技術,簡單來說, Linux 容器不是模擬一個完整的操做系統,而是對進程進行隔離,至關因而在正常進程的外面套了一個保護層。
對於容器裏面的進程來講,它接觸到的各類資源都是虛擬的,從而實現與底層系統的分離。
Docker 將應用程序與該程序的依賴,打包在一個文件裏面。運行這個文件,就會生成一個虛擬容器。
程序在這個虛擬容器裏運行,就好像在真實的物理機上運行同樣。有了 Docker,就不用擔憂環境問題。
整體來講,Docker 的接口至關簡單,用戶能夠方便地建立和使用容器,把本身的應用放入容器。容器還能夠進行版本管理、複製、分享、修改,就像管理普通的代碼同樣。
咱們能夠從下面這張表格很清楚地看到容器相比於傳統虛擬機的特性的優點所在:
淺談Docker三兩事
Docker 的三個基本概念:
淺談Docker三兩事
從上圖咱們能夠看到,Docker 中包括三個基本的概念:docker

Image(鏡像)
Container(容器)
Repository(倉庫)
服務器

鏡像是 Docker 運行容器的前提,倉庫是存放鏡像的場所,可見鏡像更是 Docker 的核心。網絡

Image(鏡像)
那麼鏡像究竟是什麼呢?Docker 鏡像能夠看做是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。
鏡像不包含任何動態數據,其內容在構建以後也不會被改變。鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下面的這張圖可以幫助讀者理解鏡像的定義:
淺談Docker三兩事
從左邊咱們看到了多個只讀層,它們重疊在一塊兒。除了最下面一層,其餘層都會有一個指針指向下一層。這些層是 Docker 內部的實現細節,而且可以在主機的文件系統上訪問到。
統一文件系統(Union File System)技術可以將不一樣的層整合成一個文件系統,爲這些層提供了一個統一的視角。
這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統。咱們能夠在圖片的右邊看到這個視角的形式。架構

Container(容器)tcp

容器(Container)的定義和鏡像(Image)幾乎如出一轍,也是一堆層的統一視角,惟一區別在於容器的最上面那一層是可讀可寫的。
淺談Docker三兩事
因爲容器的定義並無說起是否要運行容器,因此實際上,容器 = 鏡像 + 讀寫層。ide

Repository(倉庫)學習

Docker 倉庫是集中存放鏡像文件的場所。鏡像構建完成後,能夠很容易的在當前宿主上運行。
可是, 若是須要在其餘服務器上使用這個鏡像,咱們就須要一個集中的存儲、分發鏡像的服務,Docker Registry(倉庫註冊服務器)就是這樣的服務。
有時候會把倉庫(Repository)和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。ui

Docker 倉庫的概念跟 Git 相似,註冊服務器能夠理解爲 GitHub 這樣的託管服務。
實際上,一個 Docker Registry 中能夠包含多個倉庫(Repository),每一個倉庫能夠包含多個標籤(Tag),每一個標籤對應着一個鏡像。
因此說,鏡像倉庫是 Docker 用來集中存放鏡像文件的地方,相似於咱們以前經常使用的代碼倉庫。
一般,一個倉庫會包含同一個軟件不一樣版本的鏡像,而標籤就經常使用於對應該軟件的各個版本 。
咱們能夠經過<倉庫名>:<標籤>的格式來指定具體是這個軟件哪一個版本的鏡像。若是不給出標籤,將以 Latest 做爲默認標籤。
倉庫又能夠分爲兩種形式:操作系統

Public(公有倉庫)
Private(私有倉庫)
命令行

Docker Registry 公有倉庫是開放給用戶使用、容許用戶管理鏡像的 Registry 服務。
通常這類公開服務容許用戶免費上傳、下載公開的鏡像,並可能提供收費服務供用戶管理私有鏡像。
除了使用公開服務外,用戶還能夠在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 鏡像,能夠直接使用作爲私有 Registry 服務。
當用戶建立了本身的鏡像以後就可使用 Push 命令將它上傳到公有或者私有倉庫,這樣下次在另一臺機器上使用這個鏡像時候,只須要從倉庫上 Pull 下來就能夠了。
咱們主要把 Docker 的一些常見概念如 Image,Container,Repository 作了詳細的闡述,也從傳統虛擬化方式的角度闡述了 Docker 的優點。
咱們從下圖能夠直觀地看到 Docker 的架構:
淺談Docker三兩事
Docker 使用 C/S 結構,即客戶端/服務器體系結構。Docker 客戶端與 Docker 服務器進行交互,Docker服務端負責構建、運行和分發 Docker 鏡像。
Docker 客戶端和服務端能夠運行在一臺機器上,也能夠經過 RESTful 、 Stock 或網絡接口與遠程 Docker 服務端進行通訊。
淺談Docker三兩事
Docker 的核心組件包括:
Docker Client
Docker Daemon
Docker Image
Docker Registry
Docker Container

這張圖展現了 Docker 客戶端、服務端和 Docker 倉庫(即 Docker Hub 和 Docker Cloud ),默認狀況下 Docker 會在 Docker 中央倉庫尋找鏡像文件。
這種利用倉庫管理鏡像的設計理念相似於 Git ,固然這個倉庫是能夠經過修改配置來指定的,甚至咱們能夠建立咱們本身的私有倉庫。
Docker 提供了一套簡單實用的命令來建立和更新鏡像,咱們能夠經過網絡直接下載一個已經建立好了的應用鏡像,並經過 Docker RUN 命令就能夠直接使用。
當鏡像經過 RUN 命令運行成功後,這個運行的鏡像就是一個 Docker 容器啦。
容器能夠理解爲一個輕量級的沙箱,Docker 利用容器來運行和隔離應用,容器是能夠被啓動、中止、刪除的,這並不會影響 Docker 鏡像。
咱們能夠看看下面這幅圖:
淺談Docker三兩事
Docker 客戶端是 Docker 用戶與 Docker 交互的主要方式。當您使用 Docker 命令行運行命令時,Docker 客戶端將這些命令發送給服務器端,服務端將執行這些命令。
Docker 命令使用 Docker API 。Docker 客戶端能夠與多個服務端進行通訊。
咱們將剖析一下 Docker 容器是如何工做的,學習好 Docker 容器工做的原理,咱們就能夠本身去管理咱們的容器了。
Docker Daemon 的架構以下所示:
淺談Docker三兩事
Docker Daemon 能夠認爲是經過 Docker Server 模塊接受 Docker Client 的請求,並在 Engine 中處理請求,而後根據請求類型,建立出指定的 Job 並運行。
Docker Daemon 運行在 Docker Host 上,負責建立、運行、監控容器,構建、存儲鏡像。
運行過程的做用有如下幾種可能:

向 Docker Registry 獲取鏡像。
經過 GraphDriver 執行容器鏡像的本地化操做。
經過 NetworkDriver 執行容器網絡環境的配置。
經過 ExecDriver 執行容器內部運行的執行工做。

下圖能夠很直觀地看到 Docker Daemon 的啓動流程:
淺談Docker三兩事
默認配置下,Docker Daemon 只能響應來自本地 Host 的客戶端請求。若是要容許遠程客戶端請求,須要在配置文件中打開 TCP 監聽。
咱們能夠照着以下步驟進行配置:
一、編輯配置文件/etc/systemd/system/multi-user.target.wants/docker.service,在環境變量 ExecStart 後面添加 -H tcp://0.0.0.0,容許來自任意 IP 的客戶端鏈接。
淺談Docker三兩事
二、重啓 Docker Daemon:
systemctl daemon-reload
systemctl restart docker.service
三、咱們經過如下命令便可實現與遠程服務器通訊:
docker -H 服務器IP地址 info

Docker Image

Docker 鏡像能夠看做是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。
鏡像不包含任何動態數據,其內容在構建以後也不會被改變。咱們可將 Docker 鏡像當作只讀模板,經過它能夠建立 Docker 容器。
鏡像有多種生成方法:
A、從無到有開始建立鏡像
B、下載並使用別人建立好的現成的鏡像
C、在現有鏡像上建立新的鏡像
咱們能夠將鏡像的內容和建立步驟描述在一個文本文件中,這個文件被稱做 Dockerfile ,經過執行 docker build命令能夠構建出 Docker 鏡像。

Docker Registry

Docker Registry 是存儲 Docker Image 的倉庫,它在 Docker 生態環境中的位置以下圖所示:
淺談Docker三兩事
運行 docker push、docker pull、docker search 時,其實是經過 Docker Daemon 與 Docker Registry 通訊。

Docker Container

Docker 容器就是 Docker 鏡像的運行實例,是真正運行項目程序、消耗系統資源、提供服務的地方。
Docker Container 提供了系統硬件環境,咱們可使用 Docker Images 這些製做好的系統盤,再加上咱們所編寫好的項目代碼,Run 一下就能夠提供服務啦。
如今咱們再經過 hello-world 這個例子來體會一下 Docker 各個組件是如何協做的。
容器啓動過程以下:

1、Docker 客戶端執行 docker run 命令。
2、Docker Daemon 發現本地沒有 hello-world 鏡像。
3、Daemon 從 Docker Hub 下載鏡像。
4、下載完成,鏡像 hello-world 被保存到本地。
5、Docker Daemon 啓動容器

具體過程能夠看以下這幅演示圖:
淺談Docker三兩事
咱們能夠經過 Docker Images 能夠查看到 hello-world 已經下載到本地:
淺談Docker三兩事
咱們能夠經過 Docker Ps 或者 Docker Container ls 顯示正在運行的容器,咱們能夠看到,hello-world 在輸出提示信息之後就會中止運行,容器自動終止,因此咱們在查看的時候沒有發現有容器在運行。
淺談Docker三兩事

**Dockerfile 是什麼???**

Dockerfile 是自動構建 Docker 鏡像的配置文件,用戶可使用 Dockerfile 快速建立自定義的鏡像。Dockerfile 中的命令很是相似於 Linux 下的 Shell 命令。
咱們能夠經過下面這幅圖來直觀地感覺下 Docker 鏡像、容器和 Dockerfile 三者之間的關係:
淺談Docker三兩事
Dockerfile 能夠自定義鏡像,經過 Docker 命令去運行鏡像,從而達到啓動容器的目的。Dockerfile 是由一行行命令語句組成,而且支持已 # 開頭的註釋行。
咱們能夠將 Dockerfile 分爲四個部分:

基礎鏡像(父鏡像)信息指令 FROM。
維護者信息指令 MAINTAINER。
鏡像操做指令 RUN 、EVN 、ADD 和 WORKDIR 等。
容器啓動指令 CMD 、ENTRYPOINT 和 USER 等。

Dockerfile經常使用命令:
FROM
FROM 是用於指定基礎的 images ,通常格式爲 FROM or FORM :。

全部的 Dockerfile 都應該以 FROM 開頭,FROM 命令指明 Dockerfile 所建立的鏡像文件以什麼鏡像爲基礎,FROM 之後的全部指令都會在 FROM 的基礎上進行建立鏡像。能夠在同一個 Dockerfile 中屢次使用 FROM 命令用於建立多個鏡像。
MAINTAINER
MAINTAINER 是用於指定鏡像建立者和聯繫方式,通常格式爲 MAINTAINER。
COPY
COPY 是用於複製本地主機的(爲 Dockerfile 所在目錄的相對路徑)到容器中的。當使用本地目錄爲源目錄時,推薦使用 COPY 。通常格式爲 COPY。
RUN
RUN 用於容器內部執行命令。每一個 RUN 命令至關於在原有的鏡像基礎上添加了一個改動層,原有的鏡像不會有變化。通常格式爲 RUN。
EXPOSE
EXPOSE 命令用來指定對外開放的端口。通常格式爲 EXPOSE[...]。
ENTRYPOINT
ENTRYPOINT 可讓你的容器表現得像一個可執行程序同樣。一個 Dockerfile 中只能有一個 ENTRYPOINT,若是有多個,則最後一個生效。
ENTRYPOINT 命令也有兩種格式:
一、ENTRYPOINT ["executable", "param1", "param2"] :推薦使用的 Exec 形式。
二、ENTRYPOINT command param1 param2 :Shell 形式。
CMD
CMD 命令用於啓動容器時默認執行的命令,CMD 命令能夠包含可執行文件,也能夠不包含可執行文件。
不包含可執行文件的狀況下就要用 ENTRYPOINT 指定一個,而後 CMD 命令的參數就會做爲 ENTRYPOINT 的參數。
CMD 命令有三種格式:
一、CMD ["executable","param1","param2"]:推薦使用的 exec 形式。二、CMD ["param1","param2"]:無可執行程序形式。三、CMD command param1 param2:Shell 形式。一個 Dockerfile 中只能有一個 CMD,若是有多個,則最後一個生效。而 CMD 的 Shell 形式默認調用 /bin/sh -c 執行命令。

相關文章
相關標籤/搜索