技術 Docker初體驗

1 Docker 是什麼?

說了這麼多, Docker 到底是個什麼東西呢?
我們在理解 Docker 之前,首先得先區分清楚兩個概念,容器和虛擬機。
可能很多讀者朋友都用過虛擬機,而對容器這個概念比較的陌生。我們用的傳統虛擬機如 VMware , VisualBox 之類的需要模擬整臺機器包括硬件。
每臺虛擬機都需要有自己的操作系統,虛擬機一旦被開啓,預分配給它的資源將全部被佔用。
每一臺虛擬機包括應用,必要的二進制和庫,以及一個完整的用戶操作系統。
而容器技術是和我們的宿主機共享硬件資源及操作系統,可以實現資源的動態分配。
容器包含應用和其所有的依賴包,但是與其他容器共享內核。
容器在宿主機操作系統中,在用戶空間以分離的進程運行。
容器技術是實現操作系統虛擬化的一種途徑,可以讓您在資源受到隔離的進程中運行應用程序及其依賴關係。
通過使用容器,我們可以輕鬆打包應用程序的代碼、配置和依賴關係,將其變成容易使用的構建塊,從而實現環境一致性、運營效率、開發人員生產力和版本控制等諸多目標。
容器可以幫助保證應用程序快速、可靠、一致地部署,其間不受部署環境的影響。
容器還賦予我們對資源更多的精細化控制能力,讓我們的基礎設施效率更高。

通過下面這幅圖,我們可以很直觀的反映出這兩者的區別所在:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zvq29HPU-1589985834510)(en-resource://database/4423:1)]

Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用接口。它是目前最流行的 Linux 容器解決方案。
而 Linux 容器是 Linux 發展出的另一種虛擬化技術,簡單來講, Linux 容器不是模擬一個完整的操作系統,而是對進程進行隔離,相當於是在正常進程的外面套了一個保護層。
對於容器裏面的進程來說,它接觸到的各種資源都是虛擬的,從而實現與底層系統的隔離。
Docker 將應用程序與該程序的依賴,打包在一個文件裏面。運行這個文件,就會生成一個虛擬容器。
程序在這個虛擬容器裏運行,就好像在真實的物理機上運行一樣。有了 Docker,就不用擔心環境問題。
總體來說 ,Docker 的接口相當簡單,用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的代碼一樣。

2 Docker 的優勢

Docker 相比於傳統虛擬化方式具有更多的優勢:

  • Docker 啓動快速屬於秒級別。 虛擬機通常需要幾分鐘去啓動。
  • Docker 需要的資源更少。 Docker 在操作系統級別進行虛擬化,Docker 容器和內核交互,幾乎沒有性能損耗,性能優於通過 Hypervisor 層與內核層的虛擬化。
  • Docker 更輕量。 Docker 的架構可以共用一個內核與共享應用程序庫,所佔內存極小。同樣的硬件環境,Docker 運行的鏡像數遠多於虛擬機數量,對系統的利用率非常高。
  • 與虛擬機相比,Docker 隔離性更弱。 Docker 屬於進程之間的隔離,虛擬機可實現系統級別隔離。
  • 安全性。 Docker 的安全性也更弱,Docker 的租戶 Root 和宿主機 Root 等同,一旦容器內的用戶從普通用戶權限提升爲 Root 權限,它就直接具備了宿主機的 Root 權限,進而可進行無限制的操作。虛擬機租戶 Root 權限和宿主機的 Root 虛擬機權限是分離的,並且虛擬機利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔離技術。這種隔離技術可以防止虛擬機突破和彼此交互,而容器至今還沒有任何形式的硬件隔離,這使得容器容易受到攻擊。
  • 可管理性。 Docker 的集中化管理工具還不算成熟。各種虛擬化技術都有成熟的管理工具,例如 VMware vCenter 提供完備的虛擬機管理能力。
  • 高可用和可恢復性。 Docker 對業務的高可用支持是通過快速重新部署實現的。虛擬化具備負載均衡,高可用,容錯,遷移和數據保護等經過生產實踐檢驗的成熟保障機制, VMware 可承諾虛擬機 99.999% 高可用,保證業務連續性。
  • 快速創建、刪除。 虛擬化創建是分鐘級別的,Docker 容器創建是秒級別的,Docker 的快速迭代性,決定了無論是開發、測試、部署都可以節約大量時間
  • 交付、部署。 虛擬機可以通過鏡像實現環境交付的一致性,但鏡像分發無法體系化。Docker 在 Dockerfile 中記錄了容器構建過程,可在集羣中實現快速分發和快速部署。

我們可以從下面這張表格很清楚地看到容器相比於傳統虛擬機的特性的優勢所在:

特性 容器 虛擬機
啓動 秒級 分鐘級
硬盤使用 一般爲MB 一般爲GB
性能 接近原生 弱於
系統支持量 單機支持上千個容器 一般是幾十個

3 Docker 的三個基本概念

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oKDSz5xr-1589985834512)(en-resource://database/4425:1)]

從上圖我們可以看到,Docker 中包括三個基本的概念:

  • Image(鏡像)
  • Container(容器)
  • Repository(倉庫)

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

Image(鏡像)

那麼鏡像到底是什麼呢?Docker 鏡像可以看作是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。
鏡像不包含任何動態數據,其內容在構建之後也不會被改變。鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下面的這張圖能夠幫助讀者理解鏡像的定義:

從左邊我們看到了多個只讀層,它們重疊在一起。除了最下面一層,其他層都會有一個指針指向下一層。這些層是 Docker 內部的實現細節,並且能夠在主機的文件系統上訪問到。
統一文件系統(Union File System)技術能夠將不同的層整合成一個文件系統,爲這些層提供了一個統一的視角。
這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統。我們可以在圖片的右邊看到這個視角的形式。

Container(容器)

容器(Container)的定義和鏡像(Image)幾乎一模一樣,也是一堆層的統一視角,唯一區別在於容器的最上面那一層是可讀可寫的。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Xv9Onl0v-1589985834518)(en-resource://database/4429:1)]

由於容器的定義並沒有提及是否要運行容器,所以實際上,容器 = 鏡像 + 讀寫層。

Repository(倉庫)

Docker 倉庫是集中存放鏡像文件的場所。鏡像構建完成後,可以很容易的在當前宿主上運行。
但是, 如果需要在其他服務器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,Docker Registry(倉庫註冊服務器)就是這樣的服務。
有時候會把倉庫(Repository)和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。
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 的架構:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7Hfb1fyX-1589985834520)(en-resource://database/4431:1)]

Docker 使用 C/S 結構,即客戶端/服務器體系結構。Docker 客戶端與 Docker 服務器進行交互,Docker服務端負責構建、運行和分發 Docker 鏡像。
Docker 客戶端和服務端可以運行在一臺機器上,也可以通過 RESTful 、 Stock 或網絡接口與遠程 Docker 服務端進行通信。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CBeE5fqf-1589985834522)(en-resource://database/4433:1)]

這張圖展示了 Docker 客戶端、服務端和 Docker 倉庫(即 Docker Hub 和 Docker Cloud ),默認情況下 Docker 會在 Docker 中央倉庫尋找鏡像文件。
這種利用倉庫管理鏡像的設計理念類似於 Git ,當然這個倉庫是可以通過修改配置來指定的,甚至我們可以創建我們自己的私有倉庫。

4 Docker 的安裝和使用

Docker 的安裝和使用有一些前提條件,主要體現在體系架構和內核的支持上。對於體系架構,除了 Docker 一開始就支持的 X86-64 ,其他體系架構的支持則一直在不斷地完善和推進中。
Docker 分爲 CE 和 EE 兩大版本。CE 即社區版,免費支持週期 7 個月;EE 即企業版,強調安全,付費使用,支持週期 24 個月。
我們在安裝前可以參看官方文檔獲取最新的 Docker 支持情況,官方文檔在這裏:https://docs.docker.com/install/。
Docker 對於內核支持的功能,即內核的配置選項也有一定的要求(比如必須開啓 Cgroup 和 Namespace 相關選項,以及其他的網絡和存儲驅動等)。
Docker 源碼中提供了一個檢測腳本來檢測和指導內核的配置,腳本鏈接在這裏:
https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh。

在滿足前提條件後,安裝就變得非常的簡單了。
Docker CE 的安裝請參考官方文檔:MacOS:

https://docs.docker.com/docker-for-mac/install/Windows:https://docs.docker.com/docker-for-windows/install/Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/Debian:https://docs.docker.com/install/linux/docker-ce/debian/CentOS:https://docs.docker.com/install/linux/docker-ce/centos/Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/其他 Linux 發行版:https://docs.docker.com/install/linux/docker-ce/binaries/

這裏我們以 CentOS 7 作爲演示。

環境準備:

  • 阿里雲服務器(1 核 2G,1M 帶寬)
  • CentOS 7.4 64 位
# 1、yum 包更新到最新 
yum update
# 2、安裝需要的軟件包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的 
yum install -y yum-utils device-mapper-persistent-data lvm2
# 3、 設置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4、 安裝docker,出現輸入的界面都按 y 
yum install -y docker-ce
# 5、 查看docker版本,驗證是否驗證成功
docker -v

安裝 Docker

Docker 軟件包已經包括在默認的 CentOS-Extras 軟件源裏。因此想要安裝 Docker,只需要運行下面的 yum 命令:
$ sudo yum install docker
當然在測試或開發環境中 Docker 官方爲了簡化安裝流程,提供了一套便捷的安裝腳本,CentOS 系統上可以使用這套腳本安裝:
curl -fsSL get.docker.com -o get-docker.shsh get-docker.sh
具體可以參看 docker-install 的腳本:https://github.com/docker/docker-install。
執行這個命令後,腳本就會自動的將一切準備工作做好,並且把 Docker CE 的 Edge 版本安裝在系統中。
安裝完成後,運行下面的命令,驗證是否安裝成功:docker versionordocker info
返回 Docker 的版本相關信息,證明 Docker 安裝成功:
 .png

啓動 Docker-CE:

$ sudo systemctl enable docker$ sudo systemctl start docker

Docker 的簡單運用 Hello World

由於服務器日常崩潰了, Docker 出了點問題,所以以下案例的演示是基於 Kali Linux 環境下進行的。
我們通過最簡單的 Image 文件 Hello World,感受一下 Docker 的魅力吧!
我們直接運行下面的命令,將名爲 hello-world 的 image 文件從倉庫抓取到本地:

docker pull library/hello-world

docker pull images 是抓取 image 文件,library/hello-world 是 image 文件在倉庫裏面的位置,其中 library 是 image 文件所在的組,hello-world 是 image 文件的名字。
 .png
抓取成功以後,就可以在本機看到這個 image 文件了:

docker images

我們可以看到如下結果: .png
現在,我們可以運行 hello-world 這個 image 文件:docker run hello-world我們可以看到如下結果: .png

輸出這段提示以後,hello world 就會停止運行,容器自動終止。有些容器不會自動終止,因爲提供的是服務,比如 MySQL 鏡像等。
是不是很 Easy 呢?我們從上面可以看出,Docker 的功能是十分強大的,除此之外,我們還可以拉取一些 Ubuntu,Apache 等鏡像,在未來的教程中我們將會一一提到。
Docker 提供了一套簡單實用的命令來創建和更新鏡像,我們可以通過網絡直接下載一個已經創建好了的應用鏡像,並通過 Docker RUN 命令就可以直接使用。
當鏡像通過 RUN 命令運行成功後,這個運行的鏡像就是一個 Docker 容器啦。
容器可以理解爲一個輕量級的沙箱,Docker 利用容器來運行和隔離應用,容器是可以被啓動、停止、刪除的,這並不會影響 Docker 鏡像。

我們可以看看下面這幅圖: .png
Docker 客戶端是 Docker 用戶與 Docker 交互的主要方式。當您使用 Docker 命令行運行命令時,Docker 客戶端將這些命令發送給服務器端,服務端將執行這些命令。
Docker 命令使用 Docker API 。Docker 客戶端可以與多個服務端進行通信。

我們將剖析一下 Docker 容器是如何工作的,學習好 Docker 容器工作的原理,我們就可以自己去管理我們的容器了。

5 Docker 架構

在上面的學習中,我們簡單地講解了 Docker 的基本架構。瞭解到了 Docker 使用的是 C/S 結構,即客戶端/服務器體系結構。
明白了 Docker 客戶端與 Docker 服務器進行交互時,Docker 服務端負責構建、運行和分發 Docker 鏡像。
知道了 Docker 客戶端和服務端可以運行在一臺機器上,我們可以通過 RESTful、Stock 或網絡接口與遠程 Docker 服務端進行通信。

我們從下圖可以很直觀的瞭解到 Docker 的架構:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZIbpYMxU-1589985834530)(en-resource://database/4435:1)]

Docker 的核心組件包括:

  • Docker Client
  • Docker Daemon
  • Docker Image
  • Docker Registry
  • Docker Container

Docker 採用的是 Client/Server 架構。客戶端向服務器發送請求,服務器負責構建、運行和分發容器。
客戶端和服務器可以運行在同一個 Host 上,客戶端也可以通過 Socket 或 REST API 與遠程的服務器通信。

Docker Client

Docker Client ,也稱 Docker 客戶端。它其實就是 Docker 提供命令行界面(CLI)工具,是許多 Docker 用戶與 Docker 進行交互的主要方式。
客戶端可以構建,運行和停止應用程序,還可以遠程與 Docker_Host 進行交互。
最常用的 Docker 客戶端就是 Docker 命令,我們可以通過 Docker 命令很方便地在 Host 上構建和運行 Docker 容器。 .png

Docker Daemon

Docker Daemon 是服務器組件,以 Linux 後臺服務的方式運行,是 Docker 最核心的後臺進程,我們也把它稱爲守護進程。
它負責響應來自 Docker Client 的請求,然後將這些請求翻譯成系統調用完成容器管理操作。
該進程會在後臺啓動一個 API Server ,負責接收由 Docker Client 發送的請求,接收到的請求將通過 Docker Daemon 內部的一個路由分發調度,由具體的函數來執行請求。 .png
我們大致可以將其分爲以下三部分:

  • Docker Server
  • Engine
  • Job

Docker Daemon 的架構如下所示:
 .png
Docker Daemon 可以認爲是通過 Docker Server 模塊接受 Docker Client 的請求,並在 Engine 中處理請求,然後根據請求類型,創建出指定的 Job 並運行。
Docker Daemon 運行在 Docker Host 上,負責創建、運行、監控容器,構建、存儲鏡像。
運行過程的作用有以下幾種可能:

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

由於 Docker Daemon 和 Docker Client 的啓動都是通過可執行文件 Docker 來完成的,因此兩者的啓動流程非常相似。
Docker 可執行文件運行時,運行代碼通過不同的命令行 Flag 參數,區分兩者,並最終運行兩者各自相應的部分。
啓動 Docker Daemon 時,一般可以使用以下命令來完成:

docker --daemon = truedocker –ddocker –d = true

再由 Docker 的 main() 函數來解析以上命令的相應 Flag 參數,並最終完成 Docker Daemon 的啓動。
下圖可以很直觀地看到 Docker Daemon 的啓動流程: .png
默認配置下,Docker Daemon 只能響應來自本地 Host 的客戶端請求。如果要允許遠程客戶端請求,需要在配置文件中打開 TCP 監聽。
我們可以照着如下步驟進行配置:

  1. 編輯配置文件/etc/systemd/system/multi-user.target.wants/docker.service,在環境變量 ExecStart 後面添加 -H tcp://0.0.0.0,允許來自任意 IP 的客戶端連接。 .png
  2. 重啓 Docker Daemon:

    systemctl daemon-reloadsystemctl restart docker.service

  3. 我們通過以下命令即可實現與遠程服務器通信:

    docker -H 服務器IP地址 info

    -H 是用來指定服務器主機,info 子命令用於查看 Docker 服務器的信息。

Docker Image

Docker 鏡像可以看作是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。
鏡像不包含任何動態數據,其內容在構建之後也不會被改變。我們可將 Docker 鏡像看成只讀模板,通過它可以創建 Docker 容器。
鏡像有多種生成方法:

  • 從無到有開始創建鏡像
  • 下載並使用別人創建好的現成的鏡像
  • 在現有鏡像上創建新的鏡像

我們可以將鏡像的內容和創建步驟描述在一個文本文件中,這個文件被稱作 Dockerfile ,通過執行 docker build命令可以構建出 Docker 鏡像。

Docker Registry

Docker Registry 是存儲 Docker Image 的倉庫,它在 Docker 生態環境中的位置如下圖所示: .png
運行 docker push、docker pull、docker search 時,實際上是通過 Docker Daemon 與 Docker Registry 通信。

Docker Container

Docker 容器就是 Docker 鏡像的運行實例,是真正運行項目程序、消耗系統資源、提供服務的地方。

Docker Container 提供了系統硬件環境,我們可以使用 Docker Images 這些製作好的系統盤,再加上我們所編寫好的項目代碼,Run 一下就可以提供服務啦。

6 Docker 組件是如何協作運行容器

看到這裏,我相信各位讀者朋友們應該已經對 Docker 基礎架構熟悉的差不多了,我們還記得運行的第一個容器嗎?
現在我們再通過 hello-world 這個例子來體會一下 Docker 各個組件是如何協作的。
容器啓動過程如下:

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

具體過程可以看如下這幅演示圖: .png
我們可以通過 Docker Images 可以查看到 hello-world 已經下載到本地: .png
我們可以通過 Docker Ps 或者 Docker Container ls 顯示正在運行的容器,我們可以看到,hello-world 在輸出提示信息以後就會停止運行,容器自動終止,所以我們在查看的時候沒有發現有容器在運行。 .png
我們把 Docker 容器的工作流程剖析的十分清楚了,我們大體可以知道 Docker 組件協作運行容器可以分爲以下幾個過程:

  • Docker 客戶端執行 docker run 命令。
  • Docker Daemon 發現本地沒有我們需要的鏡像。
  • Daemon 從 Docker Hub 下載鏡像。
  • 下載完成後,鏡像被保存到本地。
  • Docker Daemon 啓動容器。

瞭解了這些過程以後,我們再來理解這些命令就不會覺得很突兀了,下面我來給大家講講 Docker 常用的一些命令操作吧。

7 Docker 常用命令

我們可以通過 docker -h 去查看命令的詳細的幫助文檔。在這裏我只會講一些日常我們可能會用的比較多的一些命令。 .png
Docker進程相關命令

  • 啓動docker服務:
    systemctl start docker
  • 停止docker服務:
    systemctl stop docker
  • 重啓docker服務:
    systemctl restart docker
  • 查看docker服務狀態:
    systemctl status docker
  • 設置開機啓動docker服務:
    systemctl enable docker
    Docker 鏡像相關命令
  • 查看鏡像: 查看本地所有的鏡像

docker images
docker images –q # 查看所用鏡像的id

  • 搜索鏡像:從網絡中查找需要的鏡像

docker search 鏡像名稱

  • 拉取鏡像:從Docker倉庫下載鏡像到本地,鏡像名稱格式爲 名稱:版本號,如果版本號不指定則是最新的版本。
    如果不知道鏡像版本,可以去docker hub 搜索對應鏡像查看。

docker pull 鏡像名稱

  • 刪除鏡像: 刪除本地鏡像

docker rmi 鏡像id # 刪除指定本地鏡像
docker rmi docker images -q # 刪除所有本地鏡像
Docker容器相關命令

  • 查看容器

docker ps # 查看正在運行的容器
docker ps –a # 查看所有容器

  • 創建並啓動容器

docker run 參數

參數說明:
• -i:保持容器運行。通常與 -t 同時使用。加入it這兩個參數後,容器創建後自動進入容器中,退出容器後,容器自動關閉。
• -t:爲容器重新分配一個僞輸入終端,通常與 -i 同時使用。
• -d:以守護(後臺)模式運行容器。創建一個容器在後臺運行,需要使用docker exec 進入容器。退出後,容器不會關閉。
• -it 創建的容器一般稱爲交互式容器,-id 創建的容器一般稱爲守護式容器
• --name:爲創建的容器命名。

  • 進入容器

docker exec 數 參數 # 退出容器,容器不會關閉

  • 停止容器

docker stop 容器名稱

  • 啓動容器

docker start 容器名稱

  • 刪除容器:如果容器是運行狀態則刪除失敗,需要停止容器才能刪除

docker rm 容器名稱

  • 查看容器信息

docker inspect



例如,我們需要拉取一個 Docker 鏡像,我們可以用如下命令:

docker pull

image_nameimage_name 爲鏡像的名稱,而如果我們想從 Docker Hub 上去下載某個鏡像,我們可以使用以下命令:

docker pull centos:latest

cento:lastest 是鏡像的名稱,Docker Daemon 發現本地沒有我們需要的鏡像,會自動去 Docker Hub 上去下載鏡像,下載完成後,該鏡像被默認保存到 /var/lib/docker 目錄下。
接着我們如果想查看主機下存在多少鏡像,我們可以用如下命令:

docker images

我們要想知道當前有哪些容器在運行,我們可以用如下命令:

docker ps -a

-a 是查看當前所有的容器,包括未運行的。我們該如何去對一個容器進行啓動,重啓和停止呢?
我們可以用如下命令:

docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id

這個時候我們如果想進入到這個容器中,我們可以使用 attach 命令:

docker attach container_name/container_id

那如果我們想運行這個容器中的鏡像的話,並且調用鏡像裏面的 bash ,我們可以使用如下命令:

docker run -t -i container_name/container_id /bin/bash

那如果這個時候,我們想刪除指定鏡像的話,由於 Image 被某個 Container 引用(拿來運行),如果不將這個引用的 Container 銷燬(刪除),那 Image 肯定是不能被刪除。
我們首先得先去停止這個容器:

docker ps
docker stop container_name/container_id

然後我們用如下命令去刪除這個容器:

docker rm container_name/container_id

然後這個時候我們再去刪除這個鏡像:

docker rmi image_name

此時,常用的 Docker 相關的命令就講到這裏爲止了,我們在後續的文章中還會反覆地提到這些命令。

Docker容器的數據卷

概念

  • 數據卷是宿主機中的一個目錄或文件
  • 當容器目錄和數據卷目錄綁定後,對方的修改會立即同步
  • 一個數據卷可以被多個容器同時掛載
  • 一個容器也可以被掛載多個數據卷

作用

  • 容器數據持久化
  • 外部機器和容器間接通信
  • 容器之間數據交換

配置數據卷

  • 創建啓動容器時,使用 –v 參數 設置數據卷
    docker run … –v 宿主機目錄( 文件): 容器內目錄( 文件) …
  • 注意事項:
  1. 目錄必須是絕對路徑
  2. 如果目錄不存在,會自動創建
  3. 可以掛載多個數據卷
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YWasWMCg-1589985834540)(en-resource://database/4441:1)]

數據卷容器

多容器進行數據交換

  1. 多個容器掛載同一個數據卷
  2. 數據卷容器
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wA9DAtQY-1589985834541)(en-resource://database/4443:1)]

配置數據卷容器

  1. 創建啓動c3數據卷容器,使用 –v 參數 設置數據卷

docker run –it --name=c3 –v /volume centos:7 /bin/bash

  1. 創建啓動 c1 c2 容器,使用 –-volumes-from 參數 設置數據卷

docker run –it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run –it --name=c2 --volumes-from c3 centos:7 /bin/bash

數據卷小結

  1. 數據卷概念
    • 宿主機的一個目錄或文件
  2. 數據卷作用
    • 容器數據持久化
    • 客戶端和容器數據交換
    • 容器間數據交換
  3. 數據卷容器
    • 創建一個容器,掛載一個目錄,讓其他容器繼承自該容器( --volume-from )。
    • 通過簡單方式實現數據卷配置

Docker 應用部署

一、部署MySQL

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PkehUSZH-1589985834543)(en-resource://database/4445:1)]

  1. 搜索mysql鏡像
docker search mysql
  1. 拉取mysql鏡像
docker pull mysql:5.6
  1. 創建容器,設置端口映射、目錄映射
# 在/root目錄下創建mysql目錄用於存儲mysql數據信息
mkdir ~/mysql
cd ~/mysql
docker run -id \
-p 3306:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
  • 參數說明:
    • -p 3306:3306:將容器的 3306 端口映射到宿主機的 3306 端口。
    • -v $PWD/conf:/etc/mysql/conf.d:將主機當前目錄下的 conf/my.cnf 掛載到容器的 /etc/mysql/my.cnf。配置目錄
    • -v $PWD/logs:/logs:將主機當前目錄下的 logs 目錄掛載到容器的 /logs。日誌目錄
    • -v $PWD/data:/var/lib/mysql :將主機當前目錄下的data目錄掛載到容器的 /var/lib/mysql 。數據目錄
    • **-e MYSQL_ROOT_PASSWORD=123456:**初始化 root 用戶的密碼。
  1. 進入容器,操作mysql
docker exec –it c_mysql /bin/bash
  1. 使用外部機器連接容器中的mysql

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OPR6tavj-1589985834544)(en-resource://database/4447:1)]

二、部署Tomcat

  1. 搜索tomcat鏡像
docker search tomcat
  1. 拉取tomcat鏡像
docker pull tomcat
  1. 創建容器,設置端口映射、目錄映射
# 在/root目錄下創建tomcat目錄用於存儲tomcat數據信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat 
  • 參數說明:
    • **-p 8080:8080:**將容器的8080端口映射到主機的8080端口

      **-v $PWD:/usr/local/tomcat/webapps:**將主機中當前目錄掛載到容器的webapps

  1. 使用外部機器訪問tomcat

三、部署Nginx

  1. 搜索nginx鏡像
docker search nginx
  1. 拉取nginx鏡像
docker pull nginx
  1. 創建容器,設置端口映射、目錄映射
# 在/root目錄下創建nginx目錄用於存儲nginx數據信息
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在~/nginx/conf/下創建nginx.conf文件,粘貼下面內容
vim nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}


docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
  • 參數說明:
    • -p 80:80:將容器的 80端口映射到宿主機的 80 端口。
    • -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:將主機當前目錄下的 /conf/nginx.conf 掛載到容器的 :/etc/nginx/nginx.conf。配置目錄
    • -v $PWD/logs:/var/log/nginx:將主機當前目錄下的 logs 目錄掛載到容器的/var/log/nginx。日誌目錄
  1. 使用外部機器訪問nginx
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rJZLH2VX-1589985834545)(en-resource://database/4449:1)]

四、部署Redis

  1. 搜索redis鏡像
docker search redis
  1. 拉取redis鏡像
docker pull redis:5.0
  1. 創建容器,設置端口映射
docker run -id --name=c_redis -p 6379:6379 redis:5.0
  1. 使用外部機器連接redis
./redis-cli.exe -h 192.168.149.135 -p 6379

Dockerfile

Docker鏡像原理

Linux文件系統由bootfs和rootfs兩部分組成

  • bootfs:包含bootloader(引導加載程序)和 kernel(內核)
  • rootfs: root文件系統,包含的就是典型 Linux 系統中的/dev,/proc,/bin,/etc等標準目錄和文件
  • 不同的linux發行版,bootfs基本一樣,而rootfs不同,如ubuntu,centos等

  • Docker鏡像是由特殊的文件系統疊加而成
  • 最底端是 bootfs,並使用宿主機的bootfs
  • 第二層是 root文件系統rootfs,稱爲base image
  • 然後再往上可以疊加其他的鏡像文件
  • 統一文件系統(Union File System)技術能夠將不同的層整合成一個文件系統,爲這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在
    一個文件系統。
  • 一個鏡像可以放在另一個鏡像的上面。位於下面的鏡像稱
    爲父鏡像,最底部的鏡像成爲基礎鏡像。
  • 當從一個鏡像啓動容器時,Docker會在最頂層加載一個讀
    寫文件系統作爲容器

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FRtWHHmZ-1589985834545)(en-resource://database/4453:1)]
思考:

  1. Docker 鏡像本質是什麼?
    • 是一個分層文件系統
  2. Docker 中一個centos鏡像爲什麼只有200MB,而一個centos操作系統的iso文件要幾個個G?
    • Centos的iso鏡像文件包含bootfs和rootfs,而docker的centos鏡像複用操作系統的bootfs,只有rootfs和其他鏡像層
  3. Docker 中一個tomcat鏡像爲什麼有500MB,而一個tomcat安裝包只有70多MB?
    • 由於docker中鏡像是分層的,tomcat雖然只有70多MB,但他需要依賴於父鏡像和基礎鏡像,所有整個對外暴露的
    tomcat鏡像大小500多MB

鏡像製作

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gH7Y7XQ3-1589985834546)(en-resource://database/4455:1)]

  1. 容器轉爲鏡像

docker commit 容器id 鏡像名稱: 版本號
docker save -o 稱 壓縮文件名稱 鏡像名稱: 版本號
docker load –i 壓縮文件名稱

  1. dockerfile

dockerfile概念

  • Dockerfile 是一個文本文件
  • 包含了一條條的指令
  • 每一條指令構建一層,基於基礎鏡像,最終構建出一個新的鏡像
  • 對於開發人員:可以爲開發團隊提供一個完全一致的開發環境
  • 對於測試人員:可以直接拿開發時所構建的鏡像或者通過Dockerfile文件
    構建一個新的鏡像開始工作了
  • 對於運維人員:在部署時,可以實現應用的無縫移植
關鍵字 作用 備註
FROM 指定父鏡像 指定dockerfile基於那個image構建
MAINTAINER 作者信息 用來標明這個dockerfile誰寫的
LABEL 標籤 用來標明dockerfile的標籤 可以使用Label代替Maintainer 最終都是在docker image基本信息中可以查看
RUN 執行命令 執行一段命令 默認是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD 容器啓動命令 提供啓動容器時候的默認命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT 入口 一般在製作一些執行就關閉的容器中會使用
COPY 複製文件 build的時候複製文件到image中
ADD 添加文件 build的時候添加文件到image中 不僅僅侷限於當前build上下文 可以來源於遠程服務
ENV 環境變量 指定build時候的環境變量 可以在啓動的容器的時候 通過-e覆蓋 格式ENV name=value
ARG 構建參數 構建參數 只在構建的時候使用的參數 如果有ENV 那麼ENV的相同名字的值始終覆蓋arg的參數
VOLUME 定義外部可以掛載的數據卷 指定build的image那些目錄可以啓動的時候掛載到文件系統中 啓動容器的時候使用 -v 綁定 格式 VOLUME [“目錄”]
EXPOSE 暴露端口 定義容器運行的時候監聽的端口 啓動容器的使用-p來綁定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目錄 指定容器內部的工作目錄 如果沒有創建則自動創建 如果指定/ 使用的是絕對地址 如果不是/開頭那麼是在上一條workdir的路徑的相對路徑
USER 指定執行用戶 指定build或者啓動的時候 用戶 在RUN CMD ENTRYPONT執行的時候的用戶
HEALTHCHECK 健康檢查 指定監測當前容器的健康監測的命令 基本上沒用 因爲很多時候 應用本身有健康監測機制
ONBUILD 觸發器 當存在ONBUILD關鍵字的鏡像作爲基礎鏡像的時候 當執行FROM完成之後 會執行 ONBUILD的命令 但是不影響當前鏡像 用處也不怎麼大
STOPSIGNAL 發送信號量到宿主機 該STOPSIGNAL指令設置將發送到容器的系統調用信號以退出。
SHELL 指定執行腳本的shell 指定RUN CMD ENTRYPOINT 執行命令的時候 使用的shell

dockerfile案例

案例:需求
自定義centos7鏡像。要求:

  1. 默認登錄路徑爲 /usr
  2. 可以使用vim

案例:實現步驟
① 定義父鏡像:FROM centos:7
② 定義作者信息:MAINTAINER itheima [email protected]
③ 執行安裝vim命令: RUN yum install -y vim
④ 定義默認的工作目錄:WORKDIR /usr
⑤ 定義容器啓動執行的命令:CMD /bin/bash
⑥ 通過dockerfile構建鏡像:docker bulid –f dockerfile文件路徑 –t 鏡像名稱:版本


案例:需求
定義dockerfile,發佈springboot項目
案例:實現步驟
① 定義父鏡像:FROM java:8
② 定義作者信息:MAINTAINER itheima [email protected]
③ 將jar包添加到容器: ADD springboot.jar app.jar
④ 定義容器啓動執行的命令:CMD java–jar app.jar
⑤ 通過dockerfile構建鏡像:docker bulid –f dockerfile文件路徑 –t 鏡像名稱:版本

Docker服務編排

概念

微服務架構的應用系統中一般包含若干個微服務,每個微服務一般都會部署多個實例,如果每個微服務都要手動啓停,維護的工作量會很大。
• 要從Dockerfile build image 或者去dockerhub拉取image
• 要創建多個container
• 要管理這些container(啓動停止刪除)
服務編排: 按照一定的業務規則批量管理容器

Docker Compose

Docker Compose是一個編排多容器分佈式部署的工具,提供命令集管理容器化應用的完整開發週期,包括服務構建,啓動和停止。使用步驟:

  1. 利用 Dockerfile 定義運行環境鏡像
  2. 使用 docker-compose.yml 定義組成應用的各服務
  3. 運行 docker-compose up 啓動應用

一、安裝Docker Compose

# Compose目前已經完全支持Linux、Mac OS和Windows,在我們安裝Compose之前,需要先安裝Docker。下面我 們以編譯好的二進制包方式安裝在Linux系統中。 
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 設置文件可執行權限 
chmod +x /usr/local/bin/docker-compose
# 查看版本信息 
docker-compose -version

二、卸載Docker Compose

# 二進制包方式安裝的,刪除二進制文件即可
rm /usr/local/bin/docker-compose

三、 使用docker compose編排nginx+springboot項目

  1. 創建docker-compose目錄
mkdir ~/docker-compose
cd ~/docker-compose
  1. 編寫 docker-compose.yml 文件
version: '3'
services:
  nginx:
   image: nginx
   ports:
    - 80:80
   links:
    - app
   volumes:
    - ./nginx/conf.d:/etc/nginx/conf.d
  app:
    image: app
    expose:
      - "8080"
  1. 創建./nginx/conf.d目錄
mkdir -p ./nginx/conf.d
  1. 在./nginx/conf.d目錄下 編寫itheima.conf文件
server {
    listen 80;
    access_log off;

    location / {
        proxy_pass http://app:8080;
    }
   
}
  1. 在~/docker-compose 目錄下 使用docker-compose 啓動容器
docker-compose up
  1. 測試訪問
http://192.168.149.135/hello

Docker私有倉庫

概念

Docker官方的Docker hub(https://hub.docker.com)是一個用於管理公共鏡像的倉庫,我們可以從上面拉取鏡像到本地,也可以把我們自己的鏡像推送上去。但是,有時候我們的服務器無法訪問互聯網,或者你不希望將自己的鏡像放到公網當中,那麼我們就需要搭建自己的私有倉庫來存儲和管理自己的鏡像。

搭建私有倉庫

# 1、拉取私有倉庫鏡像 
docker pull registry
# 2、啓動私有倉庫容器 
docker run -id --name=registry -p 5000:5000 registry
# 3、打開瀏覽器 輸入地址http://私有倉庫服務器ip:5000/v2/_catalog,看到{"repositories":[]} 表示私有倉庫 搭建成功
# 4、修改daemon.json   
vim /etc/docker/daemon.json    
# 在上述文件中添加一個key,保存退出。此步用於讓 docker 信任私有倉庫地址;注意將私有倉庫服務器ip修改爲自己私有倉庫服務器真實ip 
{"insecure-registries":["私有倉庫服務器ip:5000"]} 
# 5、重啓docker 服務 
systemctl restart docker
docker start registry

上傳鏡像到私有倉庫

# 1、標記鏡像爲私有倉庫的鏡像     
docker tag centos:7 私有倉庫服務器IP:5000/centos:7
 
# 2、上傳標記的鏡像     
docker push 私有倉庫服務器IP:5000/centos:7

從私有倉庫拉取鏡像

#拉取鏡像 
docker pull 私有倉庫服務器ip:5000/centos:7

Docker 容器虛擬化與傳統虛擬機比較

容器就是將軟件打包成標準化單元,以用於開發、交付和部署。
• 容器鏡像是輕量的、可執行的獨立軟件包 ,包含軟件運行所需的所有內容:代碼、運行時環境、系統工具、系統庫和設置。
• 容器化軟件在任何環境中都能夠始終如一地運行。
• 容器賦予了軟件獨立性,使其免受外在環境差異的影響,從而有助於減少團隊間在相同基礎設施上運行不同軟件時的衝突。
在這裏插入圖片描述
相同:
• 容器和虛擬機具有相似的資源隔離和分配優勢
不同:
• 容器虛擬化的是操作系統,虛擬機虛擬化的是硬件。
• 傳統虛擬機可以運行不同的操作系統,容器只能運行同一類型操作系統


2020年5月20日更


大家覺得還可以可以點贊、收藏、關注一下吧!
也可以到我的個人博客參觀一下,估計近幾年都會一直更新!和我做個朋友吧!https://motongxue.cn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章