『現學現忘』Docker基礎 — 16、Docker中的基本概念和底層原理

Docker架構圖:

我們依照Docker架構圖進行Docker基礎概念的說明。

image

1、Docker的底層原理

Docker是一個Client-Server結構的系統,Docker守護進程運行在主機上,然後通過Socket連接從客戶端訪問,守護進程從客戶端接受命令並管理運行在主機上的容器。容器是一個運行時環境,就好比是我們前面說到的集裝箱。

例如架構圖中的客戶端(Client)和服務端(DOCKER_HOST):

發送命令docker run hello-world

  • Docker客戶端轉發命令給宿主機上的Docker守護進程(Docker daemon),
  • Docker守護進程接收執行命令,返回命令執行結果,
  • Docker服務端(守護進程)負責管理宿主機上的各個容器。

如下圖所示:

image

Docker客戶端和守護進程通過Socket連接,可以遠程或本地連接

Socket說明:

網路上的兩個程式通過一個雙向的通訊連接實現數據的交換,這個連接的一端稱為一個Socket。建立網路通訊連接至少要一對埠號(Socket)。Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是用來組織數據的一組介面。

2、Docker中常用的基本概念

  • 鏡像(image:Docker鏡像類似於虛擬機的鏡像,就好比是一個模板,一個面向Docker引擎的只讀模板,包含了文件系統,可以通過這個模板來創建容器服務。
    例如:一個鏡像可以完全包含了Ubuntu作業系統環境,可以把它稱作一個Ubuntu鏡像。鏡像也可以安裝了Apache應用程式(或其他軟體),可以把它稱為一個Apache鏡像。通過這個鏡像可以創建多個容器(最終服務的運行或者項目的運行就是在容器中)。
    鏡像是創建Docker容器的基礎,通過版本管理和增量的文件系統,Docker提供了一套十分簡單的機制來創建和更新現有的鏡像。用戶可以從網上下載一個已經做好的應用鏡像,並通過命令直接使用。總之,應用運行是需要環境的,而鏡像就是來提供這種環境。
    (不同的類可以創建不同的對象,同一個類也可以創建多個相同類型的對象)
    (不同的鏡像可以創建不同的容器,同一個鏡像也可以創建多個相同類型的容器)
  • 容器(Container:Docker利用容器技術,獨立運行一個或者一組應用,通過鏡像來創建的。
    Docker容器類似於一個輕量級的沙箱子(因為Docker是基於Linux內核的虛擬技術,所以消耗資源十分少),Docker利用容器來運行和隔離應用。
    容器是從鏡像創建運行實例,可以將其啟動、開始、停止、刪除,而這些容器都是相互隔離、互不可見的。
    鏡像自身是只讀的,容器從鏡像啟動的時候,Docker會在鏡像的最上層創建一個可寫層,鏡像本身將保持不變。
    (目前就可以把這容器解為就是一個簡易的Linuх系統)
  • 倉庫(Repository:倉庫就是存放鏡像的地方。
    Docker倉庫類似與程式碼倉庫,就是Docker集中存放鏡像文件的場所。
    根據存儲的鏡像公開與否,Docker倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。
    目前最大的公開倉庫是Docker Hub(Docker官方鏡像倉庫),存放了數量龐大的鏡像供用戶下載。中國的公開倉庫包括阿里雲,網易雲等鏡像倉庫,可以提供穩定的中國訪問(鏡像加速)。
    Docker也支援用戶在本地網路內創建一個只能自己訪問的私有倉庫。
    當用戶創建了自己的鏡像之後,就可以使用push命令,將它上傳到指定的公有或則私有倉庫。這樣用戶下次在另一台機器上使用該鏡像時,只需將該鏡像從倉庫pull(拉取)下來就可以了。

鏡像和容器的關係:

image

3、run命令的運行流程

我們以之前運行hello-world鏡像為例進行說明。

執行docker run hello-world命令,運行結果如下:

$ sudo docker run hello-world

# 出現下面顯示,證明運行鏡像成功

Unable to find image 'hello-world:latest' locally #(本地沒有找到hello-world鏡像)
latest: Pulling(拉取) from library/hello-world #(去遠程拉取library/hello-world鏡像)
1b930d010525: Pull complete #(拉取完成) 
Digest: sha256:d1668a9a1f5b42ed3f46b70b9cb7c88fd8bdc8a2d73509bb0041cf436018fbf5
Status: Downloaded newer image for hello-world:latest
#(上面三行是拉取鏡像的簽名資訊)
# 總結:由於本地沒有hello-world這個鏡像,所以會從遠程倉庫下載一個hello-world的鏡像到本地,並創建容器運行。

Hello from Docker!#(鏡像運行起來了)
This message shows that your installation appears to be working correctly.
#(此消息表明您的安裝似乎可以正常工作。為了生成此消息,Docker採取了以下步驟:)
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 //hub.docker.com/

For more examples and ideas, visit:
 //docs.docker.com/get-started/

提示:輸出這段提示以後,hello-world鏡像就會停止運行,容器自動終止。

run命令的執行的流程圖

image

4、為什麼Docker比VM快

  • (1)Docker有著比虛擬機更少的抽象層。
    由於Docker不需要Hypervisor實現硬體資源虛擬化(就相當於使用VMware創建一個虛擬機的操作),運行在Docker容器上的程式,直接使用的都是實際物理機的硬體資源。因此在CPU、記憶體利用率上,Docker將會在效率上有明顯優勢。
  • (2)Docker利用的是宿主機的內核,而不需要Guest OS
    因此當新建一個容器時,Docker不需要和虛擬機一樣重新載入一個作業系統內核。從而避免引尋、載入作業系統內核等,這些比較費時費資源的操作過程。
    當新建一個虛擬機時,虛擬機軟體需要載入Guest OS,這個新建過程是分鐘級別的。而Docker由於直接利用宿主機的作業系統,則省略了這個過程,因此新建一個Docker容器只需要幾秒鐘。

如下圖所示:

image

Docker與VM對比表:

image