Docker 技術(shù):Docker 容器技術(shù)基礎(chǔ)詳解

容器化的概念很早就有了。2013 年 Docker 引擎 的出現(xiàn)使應(yīng)用程序容器化變得更加容易。

根據(jù) Stack Overflow 開發(fā)者調(diào)查-2020,Docker 是開發(fā)者 #1 最想要的平臺#2 最喜歡的平臺,以及 #3 最流行的平臺

盡管 Docker 功能強大,但上手確并不容易。因此,本文將介紹從基礎(chǔ)知識到更高層次容器化的的所有內(nèi)容。讀完本文之后,你應(yīng)該能夠:

  • 容器化(幾乎)任何應(yīng)用程序
  • 將自定義 Docker 鏡像上傳到在線倉庫
  • 使用 Docker Compose 處理多個容器

前提

  • 熟悉 Linux 終端操作
  • 熟悉 JavaScript(稍后的的演示項目用到了 JavaScript)

容器化和 Docker 簡介

摘自 IBM,

容器化意味著封裝或打包軟件代碼及其所有依賴項,以便它可以在任何基礎(chǔ)架構(gòu)上統(tǒng)一且一致地運行。

換句話說,容器化可以將軟件及其所有依賴項打包在一個自包含的軟件包中,這樣就可以省略麻煩的配置,直接運行。

舉一個現(xiàn)實生活的場景。假設(shè)你已經(jīng)開發(fā)了一個很棒的圖書管理應(yīng)用程序,該應(yīng)用程序可以存儲所有圖書的信息,還可以為別人提供圖書借閱服務(wù)。

如果列出依賴項,如下所示:

  • Node.js
  • Express.js
  • SQLite3

理論上應(yīng)該是這樣。但是實際上還要搞定其他一些事情。 Node.js 使用了 node-gyp 構(gòu)建工具來構(gòu)建原生加載項。根據(jù) 官方存儲庫 中的 安裝說明,此構(gòu)建工具需要 Python 2 或 3 和相應(yīng)的的 C/C ++ 編譯器工具鏈。

考慮到所有這些因素,最終的依賴關(guān)系列表如下:

  • Node.js
  • Express.js
  • SQLite3
  • Python 2 or 3
  • C/C++ tool-chain

無論使用什么平臺,安裝 Python 2 或 3 都非常簡單。在 Linux 上,設(shè)置 C/C ++ 工具鏈也非常容易,但是在 Windows 和 Mac 上,這是一項繁重的工作。

在 Windows 上,C++ 構(gòu)建工具包有數(shù) GB 之大,安裝需要花費相當長的時間。在 Mac 上,可以安裝龐大的 Xcode 應(yīng)用程序,也可以安裝小巧的 Xcode 命令行工具 包。

不管安裝了哪一種,它都可能會在 OS 更新時中斷。實際上,該問題非常普遍,甚至連官方倉庫都專門提供了 macOS Catalina 的安裝說明。

這里假設(shè)你已經(jīng)解決了設(shè)置依賴項的所有麻煩,并且已經(jīng)準備好開始。這是否意味著現(xiàn)在開始就一帆風順了?當然不是。

如果你使用 Linux 而同事使用 Windows 該怎么辦?現(xiàn)在,必須考慮如何處理這兩個不同的操作系統(tǒng)不一致的路徑,或諸如 nginx 之類的流行技術(shù)在 Windows 上未得到很好的優(yōu)化的事實,以及諸如 Redis 之類的某些技術(shù)甚至都不是針對 Windows 預(yù)先構(gòu)建的。

即使你完成了整個開發(fā),如果負責管理服務(wù)器的人員部署流程搞錯了,該怎么辦?

所有這些問題都可以通過以下方式解決:

  • 在與最終部署環(huán)境匹配的隔離環(huán)境(稱為容器)中開發(fā)和運行應(yīng)用程序。
  • 將你的應(yīng)用程序及其所有依賴項和必要的部署配置放入一個文件(稱為鏡像)中。
  • 并通過具有適當授權(quán)的任何人都可以訪問的中央服務(wù)器(稱為倉庫)共享該鏡像。

然后,你的同事就可以從倉庫中下載鏡像,可以在沒有平臺沖突的隔離環(huán)境中運行應(yīng)用,甚至可以直接在服務(wù)器上進行部署,因為該鏡像也可以進行生產(chǎn)環(huán)境配置。

這就是容器化背后的想法:將應(yīng)用程序放在一個獨立的程序包中,使其在各種環(huán)境中都可移植且可回溯。

現(xiàn)在的問題是:Docker 在這里扮演什么角色?

正如我之前講的,容器化是一種將一切統(tǒng)一放入盒子中來解決軟件開發(fā)過程中的問題的思想。

這個想法有很多實現(xiàn)。Docker 就是這樣的實現(xiàn)。這是一個開放源代碼的容器化平臺,可讓你對應(yīng)用程序進行容器化,使用公共或私有倉庫共享它們,也可以編排它們。

目前,Docker 并不是市場上唯一的容器化工具,卻是最受歡迎的容器化工具。我喜歡的另一個容器化引擎是 Red Hat 開發(fā)的 Podman。其他工具,例如 Google 的 Kaniko,CoreOS 的 rkt 都很棒,但和 Docker 還是有差距。

此外,如果你想了解容器的歷史,可以閱讀 A Brief History of Containers: From the 1970s Till Now,它描述了該技術(shù)的很多重要節(jié)點。

怎樣安裝 Docker

Docker 的安裝因使用的操作系統(tǒng)而異。但這整個過程都非常簡單。

Docker可在 Mac、Windows 和 Linux 這三個主要平臺上完美運行。在這三者中,在 Mac 上的安裝過程是最簡單的,因此我們從這里開始。

怎樣在 macOS 里安裝 Docker

在 Mac 上,要做的就是跳轉(zhuǎn)到官方的下載頁面,然后單擊Download for Mac(stable)按鈕。

你會看到一個常規(guī)的 Apple Disk Image 文件,在該文件的內(nèi)有 Docker 應(yīng)用程序。所要做的就是將文件拖放到 Applications 目錄中。

image.png

只需雙擊應(yīng)用程序圖標即可啟動 Docker。應(yīng)用程序啟動后,將看到 Docker 圖標出現(xiàn)在菜單欄上。


image.png

現(xiàn)在,打開終端并執(zhí)行 docker --versiondocker-compose --version 以驗證是否安裝成功。

怎樣在 Windows 上安裝 Docker

在 Windows 上,步驟幾乎相同,當然還需要執(zhí)行一些額外的操作。安裝步驟如下:

  1. 跳轉(zhuǎn)到此站點,然后按照說明在 Windows 10 上安裝 WSL2。
  2. 然后跳轉(zhuǎn)到官方下載頁面 并單擊 Download for Windows(stable) 按鈕。
  3. 雙擊下載的安裝程序,然后使用默認設(shè)置進行安裝。

安裝完成后,從開始菜單或桌面啟動 Docker Desktop。Docker 圖標應(yīng)顯示在任務(wù)欄上。

image.png

現(xiàn)在,打開 Ubuntu 或從 Microsoft Store 安裝的任何發(fā)行版。執(zhí)行 docker --versiondocker-compose --version 命令以確保安裝成功。

image.png

也可以從常規(guī)命令提示符或 PowerShell 訪問 Docker,只是我更喜歡使用 WSL2。

怎樣在 Linux 上安裝 Docker

在 Linux 上安裝 Docker 的過程有所不同,具體操作取決于你所使用的發(fā)行版,它們之間差異可能更大。但老實說,安裝與其他兩個平臺一樣容易(如果不能算更容易的話)。

Windows 或 Mac 上的 Docker Desktop 軟件包是一系列工具的集合,例如Docker Engine、Docker ComposeDocker Dashboard、Kubernetes 和其他一些好東西。

但是,在 Linux 上,沒有得到這樣的捆綁包??梢允謩影惭b所需的所有必要工具。 不同發(fā)行版的安裝過程如下:

安裝完成后,打開終端并執(zhí)行 docker --versiondocker-compose --version 以確保安裝成功。

image.png

盡管無論使用哪個平臺,Docker 的性能都很好,但與其他平臺相比,我更喜歡 Linux。在本文中,我將使用Ubuntu 20.10 或者 Fedora 33

一開始就需要闡明的另一件事是,在本文中,我不會使用任何 GUI 工具操作 Docker。

我在各個平臺用過很多不錯的 GUI 工具,但是介紹常見的 docker 命令是本文的主要目標之一。

初識 Docker - 介紹 Docker 基本知識

已經(jīng)在計算機上啟動并運行了 Docker,現(xiàn)在該運行第一個容器了。打開終端并執(zhí)行以下命令:

docker run hello-world

# Unable to find image 'hello-world:latest' locally
# latest: Pulling from library/hello-world
# 0e03bdcc26d7: Pull complete 
# Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
# Status: Downloaded newer image for hello-world:latest
# 
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
# 
# 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:
#  https://hub.docker.com/
#
# For more examples and ideas, visit:
#  https://docs.docker.com/get-started/

hello-world 鏡像是使用 Docker 進行最小化容器化的一個示例。它有一個從 hello.c 文件編譯的程序,負責打印出終端看到的消息。

現(xiàn)在,在終端中,可以使用 docker ps -a 命令查看當前正在運行或過去運行的所有容器:

docker ps -a

# CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
# 128ec8ceab71        hello-world         "/hello"            14 seconds ago      Exited (0) 13 seconds ago                      exciting_chebyshev

在輸出中,使用 hello-world 鏡像運行了名為 exciting_chebyshev 的容器,其容器標識為 128ec8ceab71。它已經(jīng)在 Exited (0) 13 seconds ago,其中 (0) 退出代碼表示在容器運行時未發(fā)生任何錯誤。

現(xiàn)在,為了了解背后發(fā)生的事情,必須熟悉 Docker 體系結(jié)構(gòu)和三個非?;镜娜萜骰拍睿缦滤荆?/p>

  • 容器
  • 鏡像
  • 倉庫

我已經(jīng)按字母順序列出了這三個概念,并且將從列表中的第一個開始介紹。

什么是容器?

在容器化世界中,沒有什么比容器的概念更基礎(chǔ)的了。

官方 Docker resources 網(wǎng)站說 -

容器是應(yīng)用程序?qū)拥某橄螅梢詫⒋a和依賴項打包在一起。容器不虛擬化整個物理機,僅虛擬化主機操作系統(tǒng)。

可以認為容器是下一代虛擬機。

就像虛擬機一樣,容器是與主機系統(tǒng)是彼此之間完全隔離的環(huán)境。它也比傳統(tǒng)虛擬機輕量得多,因此可以同時運行大量容器,而不會影響主機系統(tǒng)的性能。

容器和虛擬機實際上是虛擬化物理硬件的不同方法。兩者之間的主要區(qū)別是虛擬化方式。

虛擬機通常由稱為虛擬機監(jiān)控器的程序創(chuàng)建和管理,例如 Oracle VM VirtualBox,VMware Workstation,KVM,Microsoft Hyper-V 等等。 該虛擬機監(jiān)控程序通常位于主機操作系統(tǒng)和虛擬機之間,充當通信介質(zhì)。

image.png

每個虛擬機都有自己的 guest 操作系統(tǒng),該操作系統(tǒng)與主機操作系統(tǒng)一樣消耗資源。

在虛擬機內(nèi)部運行的應(yīng)用程序與 guest 操作系統(tǒng)進行通信,該 guest 操作系統(tǒng)在與虛擬機監(jiān)控器進行通信,后者隨后又與主機操作系統(tǒng)進行通信,以將必要的資源從物理基礎(chǔ)設(shè)施分配給正在運行的應(yīng)用程序。

虛擬機內(nèi)部運行的應(yīng)用程序與物理基礎(chǔ)設(shè)施之間存在很長的通信鏈。在虛擬機內(nèi)部運行的應(yīng)用程序可能只擁有少量資源,因為 guest 操作系統(tǒng)會占用很大的開銷。

與虛擬機不同,容器以更智能的方式完成虛擬化工作。在容器內(nèi)部沒有完整的 guest 操作系統(tǒng),它只是通過容器運行時使用主機操作系統(tǒng),同時保持隔離 – 就像傳統(tǒng)的虛擬機一樣。

image.png

容器運行時(即 Docker)位于容器和主機操作系統(tǒng)之間,而不是虛擬機監(jiān)控器中。容器與容器運行時進行通信,容器運行時再與主機操作系統(tǒng)進行通信,以從物理基礎(chǔ)設(shè)施中獲取必要的資源。

由于消除了整個主機操作系統(tǒng)層,因此與傳統(tǒng)的虛擬機相比,容器的更輕量,資源占用更少。

為了說明這一點,請看下面的代碼片段:

uname -a
# Linux alpha-centauri 5.8.0-22-generic #23-Ubuntu SMP Fri Oct 9 00:34:40 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

docker run alpine uname -a
# Linux f08dbbe9199b 5.8.0-22-generic #23-Ubuntu SMP Fri Oct 9 00:34:40 UTC 2020 x86_64 Linux

在上面的代碼片段中,在主機操作系統(tǒng)上執(zhí)行了 uname -a 命令以打印出內(nèi)核詳細信息。然后在下一行,我在運行 Alpine Linux 的容器內(nèi)執(zhí)行了相同的命令。

從輸出中可以看到,該容器確實正在使用主機操作系統(tǒng)中的內(nèi)核。這證明了容器虛擬化主機操作系統(tǒng)而不是擁有自己的操作系統(tǒng)這一點。

如果你使用的是 Windows 計算機,則會發(fā)現(xiàn)所有容器都使用 WSL2 內(nèi)核。發(fā)生這種情況是因為 WSL2 充當了 Windows 上 Docker 的后端。在 macOS 上,默認后端是在 HyperKit 虛擬機管理程序上運行的 VM。

什么是 Docker 鏡像?

鏡像是分層的自包含文件,充當創(chuàng)建容器的模板。它們就像容器的凍結(jié)只讀副本。 鏡像可以通過倉庫進行共享。

過去,不同的容器引擎具有不同的鏡像格式。但是后來,開放式容器計劃(OCI)定義了容器鏡像的標準規(guī)范,該規(guī)范被主要的容器化引擎所遵循。這意味著使用 Docker 構(gòu)建的映像可以與 Podman 等其他運行時一起使用,而不會有兼容性問題。

容器只是處于運行狀態(tài)的鏡像。當從互聯(lián)網(wǎng)上獲取鏡像并使用該鏡像運行容器時,實際上是在先前的只讀層之上創(chuàng)建了另一個臨時可寫層。

在本文的后續(xù)部分中,這一概念將變得更加清晰。但就目前而言,請記住,鏡像是分層只讀文件,其中保留著應(yīng)用程序所需的狀態(tài)。

什么是倉庫?

已經(jīng)了解了這個難題的兩個非常重要的部分,即 ContainersImages 。 最后一個是 Registry

鏡像倉庫是一個集中式的位置,可以在其中上傳鏡像,也可以下載其他人創(chuàng)建的鏡像。 Docker Hub 是 Docker 的默認公共倉庫。另一個非常流行的鏡像倉庫是 Red Hat 的 Quay。

在本文中,我將使用 Docker Hub 作為首選倉庫。

image.png

可以免費在 Docker Hub 上共享任意數(shù)量的公共鏡像。供世界各地的人們下載免費使用。

除了 Docker Hub 或 Quay,還可以創(chuàng)建自己的鏡像倉庫來托管私有鏡像。計算機中還運行著一個本地倉庫,該倉庫緩存從遠程倉庫提取的鏡像。

Docker 架構(gòu)概述

既然已經(jīng)熟悉了有關(guān)容器化和 Docker 的大多數(shù)基本概念,那么現(xiàn)在是時候了解 Docker 作為軟件的架構(gòu)了。

該引擎包括三個主要組件:

  1. Docker 守護程序: 守護程序(dockerd)是一個始終在后臺運行并等待來自客戶端的命令的進程。守護程序能夠管理各種 Docker 對象。
  2. Docker 客戶端: 客戶端(docker)是一個命令行界面程序,主要負責傳輸用戶發(fā)出的命令。
  3. REST API: REST API 充當守護程序和客戶端之間的橋梁。使用客戶端發(fā)出的任何命令都將通過 API 傳遞,最終到達守護程序。

根據(jù)官方 文檔,

“ Docker 使用客戶端-服務(wù)器體系結(jié)構(gòu)。Docker client 與 Docker daemon 對話,daemon 繁重地構(gòu)建、運行和分發(fā) Docker 容器”。

作為用戶,通常將使用客戶端組件執(zhí)行命令。然后,客戶端使用 REST API 來訪問長期運行的守護程序并完成工作。

全景圖

好吧,說的夠多了。 現(xiàn)在是時候了解剛剛學習的所有這些知識如何和諧地工作了。在深入解釋運行 docker run hello-world 命令時實際發(fā)生的情況之前,看一下下面的圖片:

image.png

該圖像是在官方文檔中找到的圖像的略微修改版本。 執(zhí)行命令時發(fā)生的事件如下:

還有 53% 的精彩內(nèi)容
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
支付 ¥19.99 繼續(xù)閱讀

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容