天天5分鐘玩轉Docker容器技術(二)

容器核心知識

本篇經過 Docker 討論容器的核心知識。docker

概述

容器核心知識主要回答有關容器 What、Why 和 How 三個問題。其中 How 是重點,將從架構、鏡像、容器、網絡和存儲幾個方面進行講解。數據庫

What - 什麼是容器?

容器是一種輕量級、可移植、自包含的軟件打包技術,使應用程序能夠在幾乎任何地方以相同的方式運行。開發人員在本身筆記本上建立並測試好的容器,無需任何修改就可以在生產系統的虛擬機、物理服務器或公有云主機上運行。django

容器與虛擬機安全

談到容器,就不得不將它與虛擬機進行對比,由於二者都是爲應用提供封裝和隔離。服務器

容器由兩部分組成:網絡

  1. 應用程序自己
  2. 依賴:好比應用程序須要的庫或其餘軟件

容器在 Host 操做系統的用戶空間中運行,與操做系統的其餘進程隔離。這一點顯著區別於的虛擬機。架構

傳統的虛擬化技術,好比 VMWare, KVM, Xen,目標是建立完整的虛擬機。爲了運行應用,除了部署應用自己及其依賴(一般幾十 MB),還得安裝整個操做系統(幾十 GB)。負載均衡

下圖展現了兩者的區別。運維

如圖所示,因爲全部的容器共享同一個 Host OS,這使得容器在體積上要比虛擬機小不少。另外,啓動容器不須要啓動整個操做系統,因此容器部署和啓動速度更快,開銷更小,也更容易遷移。socket

Why - 爲何須要容器?

爲何須要容器?容器到底解決的是什麼問題?
簡要的答案是:容器使軟件具有了超強的可移植能力

容器解決的問題

咱們來看看今天的軟件開發面臨着怎樣的挑戰?

現在的系統在架構上較十年前已經變得很是複雜了。之前幾乎全部的應用都採用三層架構(Presentation/Application/Data),系統部署到有限的幾臺物理服務器上(Web Server/Application Server/Database Server)。

而今天,開發人員一般使用多種服務(好比 MQ,Cache,DB)構建和組裝應用,並且應用極可能會部署到不一樣的環境,好比虛擬服務器,私有云和公有云。

一方面應用包含多種服務,這些服務有本身所依賴的庫和軟件包;另外一方面存在多種部署環境,服務在運行時可能須要動態遷移到不一樣的環境中。這就產生了一個問題:

如何讓每種服務可以在全部的部署環境中順利運行?

因而咱們獲得了下面這個矩陣:

各類服務和環境經過排列組合產生了一個大矩陣。開發人員在編寫代碼時須要考慮不一樣的運行環境,運維人員則須要爲不一樣的服務和平臺配置環境。對他們雙方來講,這都是一項困難而艱鉅的任務。

如何解決這個問題呢?

聰明的技術人員從傳統的運輸行業找到了答案。

幾十年前,運輸業面臨着相似的問題。

每一次運輸,貨主與承運方都會擔憂因貨物類型的不一樣而致使損失,好比幾個鐵桶錯誤地壓在了一堆香蕉上。另外一方面,運輸過程當中須要使用不一樣的交通工具也讓整個過程痛苦不堪:貨物先裝上車運到碼頭,卸貨,而後裝上船,到岸後又卸下船,再裝上火車,到達目的地,最後卸貨。一半以上的時間花費在裝、卸貨上,並且搬上搬下還容易損壞貨物。

這一樣也是一個 NxM 的矩陣。

幸運的是,集裝箱的發明解決這個難題。

任何貨物,不管鋼琴仍是保時捷,都被放到各自的集裝箱中。集裝箱在整個運輸過程當中都是密封的,只有到達最終目的地才被打開。標準集裝箱能夠被高效地裝卸、重疊和長途運輸。現代化的起重機能夠自動在卡車、輪船和火車之間移動集裝箱。集裝箱被譽爲運輸業與世界貿易最重要的發明。

Docker 將集裝箱思想運用到軟件打包上,爲代碼提供了一個基於容器的標準化運輸系統。Docker 能夠將任何應用及其依賴打包成一個輕量級、可移植、自包含的容器。容器能夠運行在幾乎全部的操做系統上。

其實,「集裝箱」 和 「容器」 對應的英文單詞都是 「Container」。
「容器」 是國內約定俗成的叫法,多是由於容器比集裝箱更抽象,更適合軟件領域的原故吧。

我我的認爲:在老外的思惟中,「Container」 只用到了集裝箱這一個意思,Docker 的 Logo 不就是一堆集裝箱嗎?


Docker 的特性

咱們能夠看看集裝箱思想是如何與 Docker 各類特性相對應的。

容器的優點

對於開發人員 - Build Once, Run Anywhere

容器意味着環境隔離和可重複性。開發人員只需爲應用建立一次運行環境,而後打包成容器即可在其餘機器上運行。另外,容器環境與所在的 Host 環境是隔離的,就像虛擬機同樣,但更快更簡單。

對於運維人員 - Configure Once, Run Anything

只須要配置好標準的 runtime 環境,服務器就能夠運行任何容器。這使得運維人員的工做變得更高效,一致和可重複。容器消除了開發、測試、生產環境的不一致性。

How - 容器是如何工做的?

接下來學習容器核心知識的最主要部分。

咱們首先會介紹 Docker 的架構,而後分章節詳細討論 Docker 的鏡像、容器、網絡和存儲。

Docker 架構詳解

Docker 的核心組件包括:

  1. Docker 客戶端 - Client
  2. Docker 服務器 - Docker daemon
  3. Docker 鏡像 - Image
  4. Registry
  5. Docker 容器 - Container

Docker 架構以下圖所示:

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

Docker 客戶端

最經常使用的 Docker 客戶端是 docker 命令。經過 docker 咱們能夠方便地在 Host 上構建和運行容器。

docker 支持不少操做(子命令),後面會逐步用到。

除了 docker 命令行工具,用戶也能夠經過 REST API 與服務器通訊。

Docker 服務器

Docker daemon 是服務器組件,以 Linux 後臺服務的方式運行。

Docker daemon 運行在 Docker host 上,負責建立、運行、監控容器,構建、存儲鏡像。

默認配置下,Docker daemon 只能響應來自本地 Host 的客戶端請求。若是要容許遠程客戶端請求,須要在配置文件中打開 TCP 監聽,步驟以下:

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

若是使用的是其餘操做系統,配置文件的位置可能會不同。

2.重啓 Docker daemon。

3.服務器 IP 爲 192.168.56.102,客戶端在命令行里加上 -H 參數,便可與遠程服務器通訊。

info 子命令用於查看 Docker 服務器的信息。

Docker 鏡像

可將 Docker 鏡像當作只讀模板,經過它能夠建立 Docker 容器。

例如某個鏡像可能包含一個 Ubuntu 操做系統、一個 Apache HTTP Server 以及用戶開發的 Web 應用。

鏡像有多種生成方法:

  1. 能夠從無到有開始建立鏡像
  2. 也能夠下載並使用別人建立好的現成的鏡像
  3. 還能夠在現有鏡像上建立新的鏡像

咱們能夠將鏡像的內容和建立步驟描述在一個文本文件中,這個文件被稱做 Dockerfile,經過執行 docker build <docker-file> 命令能夠構建出 Docker 鏡像,後面咱們會討論。

Docker 容器

Docker 容器就是 Docker 鏡像的運行實例。

用戶能夠經過 CLI(docker)或是 API 啓動、中止、移動或刪除容器。能夠這麼認爲,對於應用軟件,鏡像是軟件生命週期的構建和打包階段,而容器則是啓動和運行階段。

Registry

Registry 是存放 Docker 鏡像的倉庫,Registry 分私有和公有兩種。

Docker Hub(https://hub.docker.com/) 是默認的 Registry,由 Docker 公司維護,上面有數以萬計的鏡像,用戶能夠自由下載和使用。

出於對速度或安全的考慮,用戶也能夠建立本身的私有 Registry。後面咱們會學習如何搭建私有 Registry。

docker pull 命令能夠從 Registry 下載鏡像。 docker run 命令則是先下載鏡像(若是本地沒有),而後再啓動容器。

Docker 組件如何協做?

一個完整的例子

還記得咱們運行的第一個容器嗎?如今經過它來體會一下 Docker 各個組件是如何協做的。

容器啓動過程以下:

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

docker images 能夠查看到 httpd 已經下載到本地。

docker ps 或者 docker container ls 顯示容器正在運行。

小結

Docker 借鑑了集裝箱的概念。標準集裝箱將貨物運往世界各地,Docker 將這個模型運用到本身的設計哲學中,惟一不一樣的是:集裝箱運輸貨物,而 Docker 運輸軟件。

每一個容器都有一個軟件鏡像,至關於集裝箱中的貨物。容器能夠被建立、啓動、關閉和銷燬。和集裝箱同樣,Docker 在執行這些操做時,並不關心容器裏到底裝的什麼,它無論裏面是 Web Server,仍是 Database。

用戶不須要關心容器最終會在哪裏運行,由於哪裏均可以運行。

開發人員能夠在筆記本上構建鏡像並上傳到 Registry,而後 QA 人員將鏡像下載到物理或虛擬機作測試,最終容器會部署到生產環境。

使用 Docker 以及容器技術,咱們能夠快速構建一個應用服務器、一個消息中間件、一個數據庫、一個持續集成環境。由於 Docker Hub 上有咱們能想到的幾乎全部的鏡像。

不知你們是否意識到,潘多拉盒子已經被打開。容器不但下降了咱們學習新技術的門檻,更提升了效率。

若是你是一個運維人員,想研究負載均衡軟件 HAProxy,只須要執行 docker run haproxy,無需繁瑣的手工安裝和配置既能夠直接進入實戰。

若是你是一個開發人員,想學習怎麼用 django 開發 Python Web 應用,執行 docker run django,在容器裏隨便折騰吧,不用擔憂會搞亂 Host 的環境。

不誇張的說:容器大大提高了 IT 人員的幸福指數。

最小的鏡像

鏡像是 Docker 容器的基石,容器是鏡像的運行實例,有了鏡像才能啓動容器。

本章內容安排以下:

  1. 首先經過研究幾個典型的鏡像,分析鏡像的內部結構。
  2. 而後學習如何構建本身的鏡像。
  3. 最後介紹怎樣管理和分發鏡像。

鏡像的內部結構

爲何咱們要討論鏡像的內部結構?

若是隻是使用鏡像,固然不須要了解,直接經過 docker 命令下載和運行就能夠了。

但若是咱們想建立本身的鏡像,或者想理解 Docker 爲何是輕量級的,就很是有必要學習這部分知識了。

咱們從一個最小的鏡像開始吧。

hello-world - 最小的鏡像

hello-world 是 Docker 官方提供的一個鏡像,一般用來驗證 Docker 是否安裝成功。

咱們先經過 docker pull 從 Docker Hub 下載它。

docker images 命令查看鏡像的信息。

hello-world 鏡像居然還不到 2KB!

經過 docker run 運行。

其實咱們更關心 hello-world 鏡像包含哪些內容。

Dockerfile 是鏡像的描述文件,定義瞭如何構建 Docker 鏡像。Dockerfile 的語法簡潔且可讀性強,後面咱們會專門討論如何編寫 Dockerfile。

hello-world 的 Dockerfile 內容以下:

只有短短三條指令。

  1. FROM scratch
    此鏡像是從白手起家,從 0 開始構建。
  2. COPY hello /
    將文件「hello」複製到鏡像的根目錄。
  3. CMD ["/hello"]
    容器啓動時,執行 /hello

鏡像 hello-world 中就只有一個可執行文件 「hello」,其功能就是打印出 「Hello from Docker ......」 等信息。

/hello 就是文件系統的所有內容,連最基本的 /bin,/usr, /lib, /dev 都沒有。

hello-world 雖然是一個完整的鏡像,但它並無什麼實際用途。一般來講,咱們但願鏡像能提供一個基本的操做系統環境,用戶能夠根據須要安裝和配置軟件。

這樣的鏡像咱們稱做 base 鏡像。

做者:cloudman6

原文

相關文章
相關標籤/搜索