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

Docker 非常棒! 它使軟件開發(fā)者無需擔(dān)心配置和依賴性,在任何地方打包,發(fā)送和運行他們的應(yīng)用程序。而在與 Kubernetes 相結(jié)合后,它使應(yīng)用集群部署和管理變得更方便。這使得 Docker 深受軟件開發(fā)者的喜愛,越來越多的開發(fā)者開始使用 Docker。

那么 Docker 到底是什么?

它是構(gòu)建、測試、部署和發(fā)布容器化應(yīng)用的平臺。稱其為平臺是因為 Docker 其實是一套用于管理與容器相關(guān)的所有事物的工具。作為 Docker 的核心,接下來我們將深入探討容器。

什么是容器?

容器提供了在計算機上的隔離環(huán)境中安裝和運行應(yīng)用程序的方法。在容器內(nèi)運行的應(yīng)用程序僅可使用于為該容器分配的資源,例如:CPU,內(nèi)存,磁盤,進程空間,用戶,網(wǎng)絡(luò),卷等。在使用有限的容器資源的同時,并不與其他容器沖突。您可以將容器視為簡易計算機上運行應(yīng)用程序的隔離沙箱。

這個概念聽起來很熟悉,有些類似于虛擬機。但它們有一個關(guān)鍵的區(qū)別:容器使用的一種非常不同的,輕量的技術(shù)來實現(xiàn)資源隔離。容器利用了底層 Linux 內(nèi)核的功能,而不是虛擬機采用的 hypervisor 的方法。換句話說,容器調(diào)用 Linux 命令來分配和隔離出一組資源,然后在此空間中運行您的應(yīng)用程序。我們快速來看下兩個這樣的功能:

Namespaces

簡單的講就是,Linux namespace 允許用戶在獨立進程之間隔離 CPU 等資源。進程的訪問權(quán)限及可見性僅限于其所在的 Namespaces 。因此,用戶無需擔(dān)心在一個 Namespace 內(nèi)運行的進程與在另一個 Namespace 內(nèi)運行的進程沖突。甚至可以同一臺機器上的不同容器中運行具有相同 PID 的進程。同樣的,兩個不同容器中的應(yīng)用程序可以使用相同的端口。

Cgroups

Cgroups 允許對可用資源設(shè)置限制和約束。例如,您可以在一臺擁有 16 G 內(nèi)存的計算機上創(chuàng)建一個 Namespace ,限制其內(nèi)部進程可用內(nèi)存為 1 GB。

到這,您可能已經(jīng)猜到 Docker 的工作原理了。當(dāng)您請求 Docker 運行容器時,Docker 會在您的計算機上設(shè)置一個資源隔離的環(huán)境。然后 Docker 會將打包的應(yīng)用程序和關(guān)聯(lián)的文件復(fù)制到 Namespace 內(nèi)的文件系統(tǒng)中,此時環(huán)境的配置就完成了。之后 Docker 會執(zhí)行您指定的命令運行應(yīng)用程序。

簡而言之,Docker 通過使用 Linux namespace 和 cgroup(以及其他一些命令)來協(xié)調(diào)配置容器,將應(yīng)用程序文件復(fù)制到為容器分配的磁盤,然后運行啟動命令。Docker 還附帶了許多其他用于管理容器的工具,例如:列出正在運行的容器,停止容器,發(fā)布容器鏡像等許多其他工具。

與虛擬機相比,容器更輕量且速度更快,因為它利用了 Linux 底層操作系統(tǒng)在隔離的環(huán)境中運行。虛擬機的 hypervisor 創(chuàng)建了一個非常牢固的邊界,以防止應(yīng)用程序突破它,而容器的邊界不那么強大。另一個區(qū)別是,由于 Namespace 和 Cgroups 功能僅在 Linux 上可用,因此容器無法在其他操作系統(tǒng)上運行。此時您可能想知道 Docker 如何在 macOS 或 Windows 上運行? Docker 實際上使用了一個技巧,并在非 Linux 操作系統(tǒng)上安裝 Linux 虛擬機,然后在虛擬機內(nèi)運行容器。

讓我們利用目前為止學(xué)到的所有內(nèi)容,從頭開始創(chuàng)建和運行 Docker 容器。如果你還沒有將 Docker 安裝在你的機器上,可以參考這里[1]安裝 Docker。在這個示例中,我們將創(chuàng)建一個 Docker 容器,下載一個用 C語言寫的 Web 服務(wù),編譯并運行它,然后使用瀏覽器訪問這個 Web 服務(wù)。

我們將從所有 Docker 項目開始的地方從創(chuàng)建一個 Dockerfile 開始。此文件描述了如何創(chuàng)建用于運行容器的 Docker 鏡像。既然我們還沒有聊到鏡像,那么讓我們看一下鏡像的官方定義[2]:

鏡像是一個可執(zhí)行包,其包含運行應(yīng)用程序所需的代碼、運行時、庫、環(huán)境變量和配置文件,容器是鏡像的運行時實例。

簡單的講,當(dāng)你要求 Docker 運行一個容器時,你必須給它一個包含如下內(nèi)容的鏡像:

  • 包含應(yīng)用程序及其所有依賴的文件系統(tǒng)快照。
  • 容器啟動時的運行命令。

在 Docker 的世界,使用別人的鏡像作為基礎(chǔ)鏡像來創(chuàng)建自己的鏡像是十分普遍的。例如,官方 reds Docker 鏡像就是基于 Debian 文件系統(tǒng)快照(rootfs tarball),并安裝在其上配置 Redis。

在我們的示例中,我們選擇 Alpine Linux 為基礎(chǔ)鏡像。當(dāng)您在 Docker 中看到 “alpine” 時,它通常意味著一個精簡的基本鏡像。 Alpine Linux 鏡像大小只有約為5 MB!

在您的計算機創(chuàng)建一個新目錄(例如 dockerprj),然后新建一個 Dockerfile 文件。

umermansoor:dockerprj$ touch Dockerfile

將如下內(nèi)容粘貼到 Dockerfile:

# Use Alpine Linux rootfs tarball to base our image on
FROM alpine:3.9 

# Set the working directory to be '/home'
WORKDIR '/home'

# Setup our application on container's file system
RUN wget http://www.cs.cmu.edu/afs/cs/academic/class/15213-00/www/class28/tiny.c \
&& apk add build-base \
&& gcc tiny.c -o tiny \
&& echo 'Hello World' >> index.html

# Start the web server. This is container's entry point
CMD ["./tiny", "8082"]

# Expose port 8082
EXPOSE 8082

這個Dockerfile 包含創(chuàng)建鏡像的內(nèi)容說明。我們創(chuàng)建鏡像基于 Alpine Linux(rootfs tarball),并將工作目錄設(shè)置為 /home 。接下來下載,編譯并創(chuàng)建了一個用 C 編寫的簡單 Web 服務(wù)器的可執(zhí)行文件,然后指定在運行容器時要執(zhí)行的命令,并將容器端口 8082 暴露給主機。

現(xiàn)在,我們就可以構(gòu)建鏡像了。在 Dockerfile 的同級目錄運行 docker build 命令:

umermansoor:dockerprj$ docker build -t codeahoydocker .

如果這個命令成功了,您將看到:

Successfully tagged codeahoydocker:latest

此時我們的鏡像就創(chuàng)建成功了,該鏡像主要包括:

  • 文件系統(tǒng)快照(Alpine Linux 和 我們安裝的 Web 服務(wù))
  • 啟動命令(./tiny 8092)

既然成功構(gòu)建了鏡像,那么我們可以使用如下命令運行容器。

umermansoor:dockerprj$ docker run -p 8082:8082 codeahoydocker:latest

讓我們了解下這里發(fā)生了什么。

通過 docker run 命令,我們請求 Docker 基于 codeahoydocker:latest 鏡像創(chuàng)建和啟動一個容器。-p 8082:8082 將本地的 8082 端口映射到容器的 8082 端口(容器內(nèi)的 Web 服務(wù)器正在監(jiān)聽 8082 端口上的連接)。打開你的瀏覽器并訪問 localhost:8082/index.html 。你將可以看到 Hello World 信息。

最后我想補充一點,雖然 Docker 非常棒,而且對于大多數(shù)項目來說它是一個不錯的選擇,但我們并非處處都要使用它。在我的工作中,Docker 與 Kubernetes 結(jié)合使用,可以非常輕松地部署和管理后端微服務(wù),我們不必為每個服務(wù)配置新的運行環(huán)境。另一方面,對于性能密集型應(yīng)用程序,Docker 可能不是最佳選擇。我經(jīng)手的其中一個項目必須處理來自移動游戲客戶端的 TCP 長連接(每臺機器1000個),這時 Docker 網(wǎng)絡(luò)出現(xiàn)了很多問題,導(dǎo)致無法將它用于該項目。

寫在最后

點關(guān)注,不迷路;Java蘇先生每天更新Java相關(guān)技術(shù)及資訊文章

?著作權(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ù)。

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

  • 一、Docker 簡介 Docker 兩個主要部件:Docker: 開源的容器虛擬化平臺Docker Hub: 用...
    R_X閱讀 4,521評論 0 27
  • Docker容器技術(shù)已經(jīng)發(fā)展了好些年,在很多項目都有應(yīng)用,線上運行也很穩(wěn)定。整理了部分Docker的學(xué)習(xí)筆記以及新...
    __七把刀__閱讀 11,629評論 0 58
  • 前言 在JAVA RESTful WebService實戰(zhàn)筆記(三)中已經(jīng)完成了對JAX-RS2定義的4中過濾器的...
    菜鳥_一枚閱讀 1,681評論 0 0
  • 2017/11/07 3峰隊 總共11人,已交 10人;未交0人;圍觀1人 007-1228|康遼遼 文章:一只有...
    etme閱讀 131評論 0 0
  • 很多男人不敢和女人聊天,怕沒話說女人覺得自己無聊,又怕說錯話留下了不好的印象,其實哪里有那么難,你們只是在聊天,又...
    QuantumCC閱讀 771評論 0 6

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