歡迎光臨
每天分享高質量文章

Docker 工作原理及容器化簡易指南

 

Docker 非常棒! 它使軟體開發者無需擔心配置和依賴性,在任何地方打包,傳送和執行他們的應用程式。而在與 Kubernetes 相結合後,它使應用叢集部署和管理變得更方便。這使得 Docker 深受軟體開發者的喜愛,越來越多的開發者開始使用 Docker。
那麼 Docker 到底是什麼?
它是構建、測試、部署和釋出容器化應用的平臺。稱其為平臺是因為 Docker 其實是一套用於管理與容器相關的所有事物的工具。作為 Docker 的核心,接下來我們將深入探討容器。

 

什麼是容器?

 

容器提供了在計算機上的隔離環境中安裝和執行應用程式的方法。在容器內執行的應用程式僅可使用於為該容器分配的資源,例如:CPU,記憶體,磁碟,行程空間,使用者,網路,捲等。在使用有限的容器資源的同時,並不與其他容器衝突。您可以將容器視為簡易計算機上執行應用程式的隔離沙箱。
這個概念聽起來很熟悉,有些類似於虛擬機器。但它們有一個關鍵的區別:容器使用的一種非常不同的,輕量的技術來實現資源隔離。容器利用了底層 Linux 內核的功能,而不是虛擬機器採用的 hypervisor 的方法。換句話說,容器呼叫 Linux 命令來分配和隔離出一組資源,然後在此空間中執行您的應用程式。我們快速來看下兩個這樣的功能:
Namespaces
簡單的講就是,Linux namespace 允許使用者在獨立行程之間隔離 CPU 等資源。行程的訪問許可權及可見性僅限於其所在的 Namespaces 。因此,使用者無需擔心在一個 Namespace 內執行的行程與在另一個 Namespace 內執行的行程衝突。甚至可以同一臺機器上的不同容器中執行具有相同 PID 的行程。同樣的,兩個不同容器中的應用程式可以使用相同的埠。
Cgroups
Cgroups 允許對可用資源設定限制和約束。例如,您可以在一臺擁有 16 G 記憶體的計算機上建立一個 Namespace ,限制其內部行程可用記憶體為 1 GB。
到這,您可能已經猜到 Docker 的工作原理了。當您請求 Docker 執行容器時,Docker 會在您的計算機上設定一個資源隔離的環境。然後 Docker 會將打包的應用程式和關聯的檔案複製到 Namespace 內的檔案系統中,此時環境的配置就完成了。之後 Docker 會執行您指定的命令執行應用程式。
簡而言之,Docker 透過使用 Linux namespace 和 cgroup(以及其他一些命令)來協調配置容器,將應用程式檔案複製到為容器分配的磁碟,然後執行啟動命令。Docker 還附帶了許多其他用於管理容器的工具,例如:列出正在執行的容器,停止容器,釋出容器映象等許多其他工具。
與虛擬機器相比,容器更輕量且速度更快,因為它利用了 Linux 底層作業系統在隔離的環境中執行。虛擬機器的 hypervisor 建立了一個非常牢固的邊界,以防止應用程式突破它,而容器的邊界不那麼強大。另一個區別是,由於 Namespace 和 Cgroups 功能僅在 Linux 上可用,因此容器無法在其他作業系統上執行。此時您可能想知道 Docker 如何在 macOS 或 Windows 上執行? Docker 實際上使用了一個技巧,併在非 Linux 作業系統上安裝 Linux 虛擬機器,然後在虛擬機器內執行容器。
讓我們利用目前為止學到的所有內容,從頭開始建立和執行 Docker 容器。如果你還沒有將 Docker 安裝在你的機器上,可以參考這裡[1]安裝 Docker。在這個示例中,我們將建立一個 Docker 容器,下載一個用 C語言寫的 Web 服務,編譯並執行它,然後使用瀏覽器訪問這個 Web 服務。
我們將從所有 Docker 專案開始的地方從建立一個 Dockerfile 開始。此檔案描述瞭如何建立用於執行容器的 Docker 映象。既然我們還沒有聊到映象,那麼讓我們看一下映象的官方定義[2]:
映象是一個可執行包,其包含執行應用程式所需的程式碼、執行時、庫、環境變數和配置檔案,容器是映象的執行時實體。
簡單的講,當你要求 Docker 執行一個容器時,你必須給它一個包含如下內容的映象:
  1. 包含應用程式及其所有依賴的檔案系統快照。

  2. 容器啟動時的執行命令。

在 Docker 的世界,使用別人的映象作為基礎映象來建立自己的映象是十分普遍的。例如,官方 reds Docker 映象就是基於 Debian 檔案系統快照(rootfs tarball),並安裝在其上配置 Redis。
在我們的示例中,我們選擇 Alpine Linux 為基礎映象。當您在 Docker 中看到 “alpine” 時,它通常意味著一個精簡的基本映象。 Alpine Linux 映象大小隻有約為5 MB!
在您的計算機建立一個新目錄(例如 dockerprj),然後新建一個 Dockerfile 檔案。
 
  1. umermansoor:dockerprj$ touch Dockerfile
將如下內容貼上到 Dockerfile:
  1. # Use Alpine Linux rootfs tarball to base our image on
  2. FROM alpine:3.9
  3. # Set the working directory to be '/home'
  4. WORKDIR '/home'
  5. # Setup our application on container's file system
  6. RUN wget http://www.cs.cmu.edu/afs/cs/academic/class/15213-s00/www/class28/tiny.c \
  7. && apk add build-base \
  8. && gcc tiny.c -o tiny \
  9. && echo 'Hello World' >> index.html
  10. # Start the web server. This is container's entry point
  11. CMD ["./tiny", "8082"]
  12. # Expose port 8082
  13. EXPOSE 8082
這個Dockerfile 包含建立映象的內容說明。我們建立映象基於 Alpine Linux(rootfs tarball),並將工作目錄設定為 /home 。接下來下載,編譯並建立了一個用 C 編寫的簡單 Web 伺服器的可執行檔案,然後指定在執行容器時要執行的命令,並將容器埠 8082 暴露給主機。
現在,我們就可以構建映象了。在 Dockerfile 的同級目錄執行 docker build 命令:
  1. umermansoor:dockerprj$ docker build -t codeahoydocker .
如果這個命令成功了,您將看到:
  1. Successfully tagged codeahoydocker:latest
此時我們的映象就建立成功了,該映象主要包括:
  1. 檔案系統快照(Alpine Linux 和 我們安裝的 Web 服務)

  2. 啟動命令(./tiny 8092)

既然成功構建了映象,那麼我們可以使用如下命令執行容器。
  1. umermansoor:dockerprj$ docker run -p 8082:8082 codeahoydocker:latest
讓我們瞭解下這裡發生了什麼。
透過 docker run 命令,我們請求 Docker 基於 codeahoydocker:latest 映象建立和啟動一個容器。-p 8082:8082 將本地的 8082 埠對映到容器的 8082 埠(容器內的 Web 伺服器正在監聽 8082 埠上的連線)。開啟你的瀏覽器並訪問 localhost:8082/index.html 。你將可以看到 Hello World 資訊。
最後我想補充一點,雖然 Docker 非常棒,而且對於大多數專案來說它是一個不錯的選擇,但我們並非處處都要使用它。在我的工作中,Docker 與 Kubernetes 結合使用,可以非常輕鬆地部署和管理後端微服務,我們不必為每個服務配置新的執行環境。另一方面,對於效能密集型應用程式,Docker 可能不是最佳選擇。我經手的其中一個專案必須處理來自移動遊戲客戶端的 TCP 長連線(每臺機器1000個),這時 Docker 網路出現了很多問題,導致無法將它用於該專案。
希望上面這些內容有用。
相關連結:
  1. https://docs.docker.com/install/

  2. https://docs.docker.com/get-started/#images-and-containers

原文連結:https://codeahoy.com/2019/04/12/what-are-containers-a-simple-guide-to-containerization-and-how-docker-works/
贊(0)

分享創造快樂