Docker 是什麼?

What’s Docker?

直接破題好惹w

  • Docker 想解決的問題:
    改善傳統虛擬機器因為需要額外安裝作業系統(Guest OS),導致啟動慢、佔較大記憶體的問題

  • Docker 要提供的解法:
    以應用程式為核心虛擬化,取代傳統需要 Guest OS 的虛擬化技術

白話文的翻譯就像是:

「我寫好了一支程式,在我的電腦上可以正常運作,然後在你的電腦上運作就爆掉惹 ouo」

就像是我的 Ruby 版本跟你的 Ruby 版本不同,結果根本沒有那個方法可以用。又或者是小菜的電腦是 windows 其他人的都是 mac,光作業系統與硬體配置就不盡相同了!更何況是他的程式可能跟其他人電腦上的環境又都不相容,而透過「虛擬化」的方式模擬一個環境,讓程式可以在不同硬體上執行,都以為自己在同一個環境中執行。

最為熟悉的莫過於在買 mac 電腦時,很想裝個 虛擬機器 來打電動或者是開啟專屬於 windows 的軟體,而目前常見用來比較的虛擬化技術有兩種:

  1. 傳統方式是在硬體層面實現虛擬化,需要額外的虛擬機器管理軟體和虛擬機器作業系統層(Guest OS),如 Oracle VM VirtualBox
  2. Docker 容器是在作業系統層上實現虛擬化,直接使用本機的作業系統(Host OS),如 dotCloud Docker

所以什麼是 Docker?

如同前面破題的內容,知道了要解決的問題,因此來跟傳統的虛擬機技術來比較不同之處。傳統虛擬機技術是模擬出一套硬體後,在這系統上再運行所需要應用到的軟體;而 Docker 透過在容器內的應用直接運行於宿主的內核(Docker Engine),也不用模擬出虛擬的硬體(Guest OS)。

傳統虛擬機器:
image

Docker:
image

圖中名詞介紹(Host OS / Guest OS / Hypervisor)

Host OS | Guest OS

Host(Host OS)指的是用來安裝虛擬機器軟體的作業系統,而 Guest(Guest OS)則是指安裝在虛擬機器上的作業系統。

舉例來說,我在筆電上裝了 Winodws 7,然後在 Windows 7 上安裝 VirtualBox,接著再透過 VirtualBox 建立的虛擬機上又建立了 Windows 10 環境。由此例推導,VirtualBox 虛擬機器的 Windows 10 就是 Guest OS,而原本筆電上安裝的 Windows 7 就是 Host OS。

Hypervisor

又稱虛擬機器監視器(Virtual machine monitor),是用來建立與執行虛擬機器的軟體、韌體或硬體。

被 Hypervisor 用來執行一個或多個虛擬機器的電腦稱為宿主機(Host machine),這些虛擬機器則稱為客戶機(Guest machine)。Hypervisor 提供虛擬的作業平台來執行 Guest OS,負責管理其他 Guest OS 的執行階段,而這些 Guest OS 又共同分享虛擬化後的硬體資源。

虛擬機器 vs 容器

虛擬機器(Virtual machine)

虛擬機器是在系統層上虛擬化,透過 Hypervisor 在目標的機器上提供可以執行一個或多個虛擬機器的平台。而這些虛擬機器可以執行完整的作業系統。簡單來說,Hypervisor 就是一個可以讓你在作業系統(Host OS)上面再裝一個作業系統(Guest OS)。

透過選擇不同的 Guest OS,虛擬機器的技術就可以確保只要我的程式在該 Guest OS 上可以正常運作,那放到你的電腦上跑時,可以不管你的 Host OS 是什麼,只要在你的 Host OS 上先裝上我的 Guest OS,我的程式就可以正常在你的電腦上運作。

容器(Container)

容器是在作業系統層上虛擬化,透過 Container Manager(ex: Docker Engine) 直接將一個應用程式所需的程式碼、函式庫打包,建立資源控管機制隔離各個容器,並分配 Host OS 上的系統資源。透過容器,應用程式不需要再另外安裝作業系統(Guest OS)也可以執行。

總結

特性 容器 虛擬機器
啟動速度 分鐘
硬碟使用 通常為 MB 通常為 GB
電腦效能 接近於原本 弱於容器
系統支援數量 支持上千個容器 通常幾十個

好了,寫到這邊應該都對 Docker 技術、優勢及背景知識有了大概的了解,現在終於要來切入 Docker 啦~


Docker 三大元素

在了解完基本概念後,接下來我們要進一步了解要使用 Docker 時最重要的三個元素:映像檔(Docker Image,文中簡稱 Image)、容器(Docker Container,文中簡稱 Container)、倉庫(Docker Repository,文中簡稱 Repository)。

白話文的翻譯就像是:

我有一個很大的樂高積木箱子(Repository),裡面專門放置很多很多的樂高積木(Image),而透過積木產生的樂高,則是容器(Container)。

映像檔(Image)

Docker Image 是一個模板,用來重複產生 Container。如同一個 Image 裡可以包含一個完整的 PostgreSQL 資料庫服務、一個 Ruby 的編譯環境、或是一個 Ubuntu 作業系統。

透過 Image 我們可以快速的產生可以執行應用程式的 Container。而 Docker Image 可以透過撰寫 Dockerfile 建立,或甚至可以從公開的地方下載已經做好的 Image 來使用。另外要注意的是,Docker Image 是唯讀(Read-only)的。

Docker 設計時,充分利用 Union FS 的技術,來設計分層儲存的架構。因此,Image 在建構時,會一層層建構,前一層是後一層的基礎。每一層建構完就不會再發生改變,後一層上的任何改變只會發生在自己這一層。

容器(Container)

Container 是用 Image 建立出來的執行實例,他們之間的關係,就像是實體與類別的概念一樣,Image 是靜態的定義,Container 是 Image 運行的實體。它可以被創建、啟動、刪除、停止等,且每個容器都是相互隔離。

又可以把 Container 看做是一個執行的應用程式加上執行它的簡易版 Linux 環境(包括 root 使用者權限、程式空間、使用者空間和網路空間等),就好像在獨立的系統下操作一樣。

Container 與 Image 都是使用分層儲存。其儲存層的生命週期和 Container 一樣,Container 刪除時,容器儲存層也隨之結束。因此,任何保存於裡面的資訊都會隨 Container 刪除而丟失。

倉庫(Repository)

Image 建構完成後,可以很容易的當前的電腦上運行,但是如果需要在其他伺服器使用這個 Image 時候,就需要一個集中儲存 Image 的服務,Docker Registry 就是這樣的服務。

一個 Docker Registry 中可以包含多個 Repository;每個 Repository 又可以包含多個版本;每個版本對應一個 Image。

最常用的 Registry 公開服務是官方的 Docker Hub,也就是 Docker 倉庫註冊伺服器的代表,此外還有像是 Google 的 Google Container Registry,Kubernetes 的 Image 使用的就是這個服務。且概念及使用方式跟 Github 類似,你可以在上面建立多個倉庫,然後透過 push、pull 的方式上傳、存取。


狀況題

如同上述的灰色區塊可知,如果今天我想升級 mysql 的版本,於是我把正在跑的 mysql:5.5 關掉,然後重新跑一個 mysql:5.7 的 Container,那資料庫裡面的資料不就不見了嗎?

沒錯,這時候就需要 Volume 了,簡單來說 Volume 的生命週期獨立於 Container,Container 的結束不會影響 Volume 的存亡,因此使用 volume 就是用來保存容器內的資料。

那又是另一個主題了…


資料來源