講到Docker之前就必須先談談容器化, 容器化是一種軟體開發的方法, 將程式、依賴及組態封裝在映像檔之中, 那映像檔對於大部份的人來說一定非常的熟悉, 尤其是VM這個詞, 虛擬化技術的先行者, 有了這項技術之後, 我們就可以減少一些因為環境產生的問題導致難以排查程式錯誤的狀況, 甚至可以避免因為A軟體需要的依賴及B軟體所需的依賴版本發生衝突的窘境。
我們就想像運輸的過程, 貨櫃就是一個容器與標準, 中間可以是船隻或者是火車…等載具, 那麼在Docker的架構之中也有容器(Container)的角色存在, 也是非常重要的一個關鍵, 開發人員負責在容器內裝箱, 維運IT人員負責佈署到目的, 雙方職責切割、互不干擾, 減少因為小環節出狀況很難釐清的狀況。
簡言之: 容器的好處也讓不同的應用程式在系統上隔離, 減少維運成本、專注於開發、各環境統一減少排錯變因。
先來談談我們過去較熟悉的VM虛擬機,這項技術主要模擬底層的各種硬體資源(CPU、RAM、Storage),架構中有一層Hypervisor平台,這平台主要進行資源分配,讓我們基於HostOS之上可以分身出另一個作業系統,這樣的好處是硬體資源在多個虛擬環境之下完全隔離,但相對的也因為較為龐大,故而資源浪費以外,啟動也稍慢一些。
那Docker的部分呢? 容器的架構下,每個容器只需要包含程式運行的函式庫,基本上容器不會模擬底層的OS資源,所有的程式共用一個Host核心,因此耗費的資源也相對較低,並且具有一定的獨立性,各個容器的應用服務基本上不會因為套件相互依賴而產生衝突。
總體而言,Docker是一個輕量且靈活的容器化解決方案,適用於快速部署和管理應用程式,而虛擬機則適合需要完全隔離和模擬多個獨立作業系統的場景。
但缺點也在這邊, 由於採取資源共用的機制, 因此安全性較VM完全隔離來的差一些, 這取決於我們因應什麼場景使用什麼樣的隔離技術, 如果是基礎層為主的應用就需要將硬體資源完全隔離, 強安全環境要求較高, 這時候就可以採取VM的策略, 但若只是一般的Application應用, 那個容器化會是較好的選擇。
這個部份主要在描述映像檔(Image)的組成方式, Docker就會依照我們的描述去產生映像檔(Image),那開發者可以根據不同的應用程式製作不一樣的映像檔。
我們只要記住Dockerfile等於是一份汽車製造設計圖,而車廠根據設計圖進行工程施作,最終打造出一台汽車也就是映像檔,待駕駛上坐之後開始運行,因此汽車相當於是載具,擔任乘客的容器。
但Dockerfile其實並沒有這麼簡單,我們後續也會根據Dockerfile撰寫專門的一篇來進行介紹。
映像檔(Image)的部份就是由Dockerfile描述後執行產生而來, 包含了需要佈署的應用程式、依賴套件、編譯環境、作業系統…等, 封裝後的靜態檔案可以攜帶至其他主機進行載入及啟動。
通常下載方式是這樣的:
# 樣版
docker pull ${映像檔名稱}:${版本號}
# 實際案例
docker pull alpine:latest
它就等於輕量級的沙盒, 讓我們在容器中執行應用程式, 而萬一壞掉也可以任意的刪除與重建。
# 樣版
docker run ${參數} ${映像檔名稱}:${版本號} ${執行的command...}
# 實際案例
docker run --rm alpine:latest echo "hello world"
簡單來說就是下載完的映像檔(Image)啟動之後會變成容器(Container), 這些容器裝載著各種不同的應用程式, 相互獨立、互不干擾。
簡單來說就是儲存映像檔(Image)的地方, 可以是公開的(Docker hub)也可以是私有的, 提供使用者上傳與下載。
那倉庫的部份我們一般都會去「Docker Hub」上傳或者下載我們需要的映像檔, 再啟動成容器(Container), 接下來也會說明如何實際的來下載一個Image去使用。
就把他想成是我們的Google Play、APP Store…等應用程式商店, 上面管控著各式各樣的應用程式, 我們只需要下載、安裝、刪除即可。
# 登入倉庫, 有些倉庫是需要建立帳號密碼的
docker login -u ${帳號} -p ${密碼} ${倉庫位置}
# 輸入帳號密碼
# 下載映像檔(Image)
docker pull ${映像檔名稱}:${版本號}
# 上傳映像檔
docker push ${映像檔名稱}:${版本號}
.
今天心血來潮突然想玩玩「Linux」系統, 做了一些功課之後發現到「alpine」這個Image的體積還蠻小的, 於是就決定下載來試試看…
# 下載alpine的映像檔(Image)
# 如果需要指定版本可以:
# docker pull alpine:3.8.13
docker pull alpine
接著我們啟動它來練習一下Linux的echo指令, 印出訊息:
# --rm: 容器退出時自動刪除容器。
docker run --rm alpine echo "成功啟動Alpine容器"
Docker的架構真的非常輕巧, 想想過往啟動一台虛擬機VM的時候總需要等個幾分鐘甚至更大型的需要半個小時, 但在Docker的架構底下可能只需要幾秒鐘甚至幾分鐘就可以啟動一個應用程式, 那麼微服務的時代之下Docker就非常重要, 讓我們的產品可以像積木一樣堆疊堆疊, 甚至彈性抽換, 每個積木獨立隔離減少依賴, 也省去了龐大的維護成本。