為什麼要使用容器?


下班前 (02/07 Fri) 同事問 Container 除了可以讓應用程式在本機與正式環境一樣,跟 VM 比較起來還有什麼好處?認真說可以說很多,簡單整理 我在三分鐘內口述的東西,因為要趕公車,三分鐘到了我就先跑了XDD,這段文字是在公車上敲下的,原文點 這裡

當下第一個直覺就是清楚的資源邊界:隔離性,衍生的議題就是 資源管理成本。第二個想到的就是 資安,衍生議題就是 系統維運 (Operations) 。所以先針對這兩個部分描述。


容器的特性

隔離性:資源有效利用

以前寫 C 大概都遇過一些問題: Kernel Panic,在 Windows 就是 Blue Screen,很常發生就是錯誤的記憶體空間存取,像是把 Kernel Space 寫壞了,整個 OS 就炸鍋了。後來一些高階語言,為了避免類似的問題,都不讓開發者自行操作記憶體空間,透過語言層級的存取隔離性。

回到 Container 的好處:隔離性 (Isolation),這是 Container 呈現的現象,背後的動機是 資源分配 (Resource Allocation)。一台機器就是資源,資源如何有效地被利用,第一個把關的是 作業系統 (Operating Systems),然後就是 應用程式 (Application) 自己。一台電腦可以開多少應用程式是有限制的。

想像一個貨櫃能載多少貨,也是有上限的。如果每個貨品大小都不一,那就麽貨櫃空間就無法有效地被利用。貨櫃空間能夠最有效利用,就是每個箱子大小都一樣,把整個貨櫃填滿,這個大小就是 基礎單位。而每個箱子必須有一定的強度,不能隨便一碰或者擠壓就壞掉,或者裡面的貨品就被弄壞。

AWS 的 EC2 是一種虛擬技術,每個 AWS Account 開啟的機器,預設會跑在不同的實體機器,AWS 的客戶之間並不會相互干擾,也就是 Account A 跟 Account B 都各有一台 VM 跑在同一台實體機器,並不會因為其中一台 CPU 100% 就影響另一台機器。這個就是隔離性,也就是資源分配的概念。如果 VM 的資源會相互干擾,就會衍生出爭議。當然 AWS 也有真的共用資源的 t2/t3 系列,滿足開發測試使用的需求,或者專屬的實體機器給單一 AWS Account ,以滿足法規需求。

政府在做的工作就是資源分配,各個縣市的預算、土地、行政資源等。最近因為武漢肺炎,口罩的分配也是資源分配。最理想的就是掌握資源總量,找到固定的單位 (一週兩個,健保卡,特約藥局),然後統一發放,讓資源使用最大化、平均化。同樣的有隔離性,大家不會去搶別人的口罩,不會因為拿不到對幹。

Container 的基本概念是 Process,Docker 透過 cgroup / chroot / namespace 等方式實踐資源的隔離。相比於 VM 是更小的單位,VM 模擬的對象是整個 Hardware 的資源,而 Container 的基本單位則是 Process,他們有本質上的差異。這也就是很多的人搞不清楚 Container 與 VM 的差異,甚至會把 Container 當 VM 用,像是在一個 Container 裡面裝了整個 Stack (Web Server / DB / Log … etc)。

Container 透過相關技術,達到資源隔離,讓資源的分配達到格式化,也就是分配到等量的資源 (CPU / Memory),等量的資源就如同貨櫃裡的箱子大小都一樣,然後有效地利用整台機器的資源。

總結來說,Container 有以下特性:

  1. 目的:讓資源有效被利用、環境一致
  2. 特性:隔離性
  3. 效果:環境一致性、節省成本、系統可移植性高

有興趣寫一個應用程式,然後讓他的 Process 限制在一定的資源 (N 個 CPU core, M 個 memory size)。而現實中應用程式都會有類似的概念,像是 Java JVM HeapSize 就是類似的設計,先限制自己箱子的大小。

資安 - 易維運性

上線的 Server 除了服務終端使用者 (End Users),其實作業系統本身都要定期上資安更新 (Security Patch)、或者是版本升級,避免因為 EOL (End of Life) 變成孤兒,不管是 Linux or Windows 都是。這是很標準的 Operation Tasks。標準的程序是:

  1. 安裝一台新的機器,包含應用程式重新部署
  2. 在測試環境測試,沒問題了
  3. 開始更新 Production

這是很累、高風險、且沒啥成就感的工作,卻是 OP 的必要工作。Container 其實可以很容易地更新這些工作,因為他天生底層的 OS 資料就少、好更新、風險小。容器天生就是牲畜,用完就刪,所以更新對於 container 是很理所當然的。VM 的更新就相對複雜,風險高。


Q and A

Container 是技術驅動,所以非技術人不易理解其優點。先留下一些問題,後續繼續完成。

  1. 工程團隊:導入 Container 需要具備怎樣的技術能力?要有怎樣的配套措施?基礎能力與知識?
  2. 技術管理:怎樣的狀況,導入 Container 才能讓效益更加顯著?

Q: Virtual Machine (VM) 跟 容器 (Container) 有什麼差異?

簡單回答:

Virtual Machine (VM) 模擬的是硬體資源,跑在上面的載體是 作業系統 (Operating System) ,隔離的是 硬體資源。通常在玩 VM 工具,建立的時候都要選擇要幾個 CPU、Memory、Disk、Network、I/O Devices … 等,然後也會選擇作業系統類型。

VM 相關工具市面上常見的有 VMWareOracle VirtualBoxQEMUProxmox

Container 是在作業系統裡面,模擬的是 應用程式的 Process ,隔離的是 Process 之間的資源與通訊。跑 Container 建立時選擇的是 應用程式 (Application),配置的是 volume、port mapping、resource allocate 等。容器的實踐有 docker、lxc,乃至於後來 K8s 因應 CRI (Container Runtime Interface) 的實作,像是 CRI-Ocontainerdkata containers

簡單列表如下:

類型 模擬對象 載體 實作
Virtual Machine 硬體 (CPU, Memory, I/O) 作業系統 (OS) VMWare, VirtualBox
Container 程序 (Process) 應用程式 (Application) Docker, LXC

列表不比較:

  1. 快慢的問題:這兩個東西本質上不一樣,比較的基準也不一樣。
    • 就像房子裡放了一個電視,然後比較房子和電視兩個移動五公尺,誰比較快?或者誰比較輕 … 有點鬼打牆。
  2. 誰取代誰的問題:container 還是跑在 host machine 上,至於 host machine 用什麼?取決於需求。至少目前為止還沒有真的誰取代誰的問題。

因為 VM 的實作通常比較重,也就是因為要模擬一台電腦的資源,因此啟動也會像一台真的電腦那樣跑得比較慢。後來衍生出的介於 VM 與 Container 之間的 Micro-VM 概念,最有名的實作就是 AWS 的 Firecracker,這篇論文有深入的介紹:Firecracker: Lightweight Virtualization for Serverless Applications

類似問題,我在 2014 年初學 docker 時,有整理網路上的文件:Experience Docker,但是當時的我其實並不知道其中的差異。


結論

其他好處還很多,像是環境建置、快速交付、Demo、多租戶架構 (Micro Services)、成本、治理 (Service Mesh) …. 等,當然事情都是一體兩面的,有好,就會有像是架構的複雜度提高,技術管理等問題浮出來。

PS

這段的原文也是在公車上寫的,原文點 這裡,很多朋友都說我三分鐘之內怎麼能說那麼多,紛紛留言吐草 XDDD

同事問我的過程,他一邊講問題,我邊聽、邊看公車進站的時間,當下第一個想法是:

  • 看看我三分鐘能講多少
  • 那一個瞬間我心裡已經有簡單的 Agenda

這也算是一種應變的訓練吧 XDDD

文字是在公車路上敲的,希望趁記憶溫度還夠的時候留下想法。文章中提及的項目,真的都有說到,甚至有些還有遺漏,已經想不起來。但文字不同的是,可以多補充口述不足的資料,所以看起來會很多。

Anyway,歡迎大家留言詢問,這種 Q and A 可以激盪很多想法。


延伸閱讀

站內文章

參考資料

更新紀錄

  • 2020/02/29: 增加 “Virtual Machine (VM) 跟 容器 (Container) 有什麼差異?”


Comments

  • 全站索引
  • 關於這裏
  • 關於作者
  • 學習法則
  • 思考本質
  • 一些領悟
  • 分類哲學
  • ▲ TOP ▲