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

Docker 很是棒! 它使軟件開發者無需擔憂配置和依賴性,在任何地方打包,發送和運行他們的應用程序。而在與 Kubernetes 相結合後,它使應用集羣部署和管理變得更方便。這使得 Docker 深受軟件開發者的喜好,愈來愈多的開發者開始使用 Docker。html

那麼 Docker 究竟是什麼?程序員

它是構建、測試、部署和發佈容器化應用的平臺。稱其爲平臺是由於 Docker 實際上是一套用於管理與容器相關的全部事物的工具。做爲 Docker 的核心,接下來咱們將深刻探討容器。web

什麼是容器?

容器提供了在計算機上的隔離環境中安裝和運行應用程序的方法。在容器內運行的應用程序僅可以使用於爲該容器分配的資源,例如:CPU,內存,磁盤,進程空間,用戶,網絡,卷等。在使用有限的容器資源的同時,並不與其餘容器衝突。您能夠將容器視爲簡易計算機上運行應用程序的隔離沙箱。sql

這個概念聽起來很熟悉,有些相似於虛擬機。但它們有一個關鍵的區別:容器使用的一種很是不一樣的,輕量的技術來實現資源隔離。容器利用了底層 Linux 內核的功能,而不是虛擬機採用的 hypervisor 的方法。換句話說,容器調用 Linux 命令來分配和隔離出一組資源,而後在此空間中運行您的應用程序。咱們快速來看下兩個這樣的功能:docker

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 運行一個容器時,你必須給它一個包含以下內容的鏡像:

  • 包含應用程序及其全部依賴的文件系統快照。
  • 容器啓動時的運行命令。

在 Docker 的世界,使用別人的鏡像做爲基礎鏡像來建立本身的鏡像是十分廣泛的。例如,官方 reds Docker 鏡像就是基於 Debian 文件系統快照(rootfs tarball),並安裝在其上配置 Redis。

在咱們的示例中,咱們選擇 Alpine Linux 爲基礎鏡像。當您在 Docker 中看到 「alpine」 時,它一般意味着一個精簡的基本鏡像。 Alpine Linux 鏡像大小隻有約爲5 MB!

在您的計算機建立一個新目錄(例如 dockerprj),而後新建一個 Dockerfile 文件。

umermansoor:dockerprj$ touch Dockerfile

將以下內容粘貼到 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 包含建立鏡像的內容說明。咱們建立鏡像基於 Alpine Linux(rootfs tarball),並將工做目錄設置爲 /home 。接下來下載,編譯並建立了一個用 C 編寫的簡單 Web 服務器的可執行文件,而後指定在運行容器時要執行的命令,並將容器端口 8082 暴露給主機。

如今,咱們就能夠構建鏡像了。在 Dockerfile 的同級目錄運行 docker build 命令:

umermansoor:dockerprj$ docker build -t codeahoydocker .

若是這個命令成功了,您將看到:

Successfully tagged codeahoydocker:latest

此時咱們的鏡像就建立成功了,該鏡像主要包括:

  • 文件系統快照(Alpine Linux 和 咱們安裝的 Web 服務)
  • 啓動命令(./tiny 8092)

既然成功構建了鏡像,那麼咱們可使用以下命令運行容器。

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 網絡出現了不少問題,致使沒法將它用於該項目。

讀者福利

分享免費學習資料

針對於Java程序員,我這邊準備免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)

爲何某些人會一直比你優秀,是由於他自己就很優秀還一直在持續努力變得更優秀,而你是否是還在知足於現狀心裏在竊喜!但願讀到這的您能點個小贊和關注下我,之後還會更新技術乾貨,謝謝您的支持!

資料領取方式:加入Java技術交流羣963944895點擊加入羣聊,私信管理員便可免費領取

相關文章
相關標籤/搜索