※ 透過三個場景來理解需要Docker的理由:
● 想像第一個場景:
- 你開發好的 Express.js 後端服務已經順利通過了 localhost 的測試。
- 發給你的同事以後,同事卻說他打不開。
- 你用同事的電腦 debug 以後,花了好幾個小時終於修好了。
- 修好以後把服務部署到線上主機,結果線上主機打開又報錯了...
發生原因:● 執行環境 (Environment)指的是程式運行時所依賴的所有條件,除了程式本身以外的因素:- 作業系統不同:(Windows XP, Windows 10, macOS, Debian, Ubuntu, CentOS ...)。
- 軟體版本不同: (Python, Node, Java, gcc ...)。
- 硬體架構不同: (arm, x86, risc-v ...)。
- 硬體配置不同: (cpu, ram, disk ...)。
● 結論:
同一個程式在不同的環境下,會有不同的結果。
※ 如何解決環境不同的問題:虛擬化技術
- docker的核心理念:把應用程式和程式所需要的「環境」,全部打包成像一個個的貨櫃來運送。
- 結論:這就是透過虛擬化的技術來解決環境不同的問題。
※ 虛擬機 vs Docker:
虛擬機:
- 模擬硬體 + 作業系統 + 所有東西。
- 資源分配是靜態的。
- 啟動速度慢。
- 隔離級別高。
Docker:
- 模擬執行環境 + 你的程式。
- 資源分配是動態的。
- 啟動速度快。
- 隔離級別較低。
※ 隔離級別:
● 想像第二個場景:
- 你開發好的後端順利部署到線上主機了。
- 你同事的服務也要部署到同一台主機。
- 他不小心覆蓋到你的服務需要的檔案。
- 你的服務壞掉了...。
結論:說明了服務隔離的重要性。
※ 虛擬化技術提供的服務隔離:
- 每個 Docker Container 從容器內部看就是一台獨立的機器。
- Docker 內部不會影響外面(Host–主機)的東西,例如被病毒攻擊也不會影響真正跑Docker的主機,只是Container壞掉而已。
- Docker 外面也沒辦法直接影響 Container 裡面的東西。
- Container 之間彼此也無法造成影響,除非額外設定。
※ 自動化完成重複性的動作:
● 想像第三個場景:
1.你每部署一個服務,就需要在新的主機上做很多事:
- 安裝 Node。
- 安裝 yarn。
- 執行 yarn install 安裝需要的套件。
- 設定各種其他有的沒的東西...終於設定好了。
2.結果老闆要你一次部署到 100 台主機上面。
※ 容器化提供的自動化流程:
- 為你的服務編寫一個腳本 Dockerfile,腳本會說明如何去編寫打包一個Image。
- 根據這個腳本來完成你的服務需要的所有前置要求。
- 腳本完成後,生成一個可以直接運行的容器鏡像 Image。
- Image具有濃縮的概念,就是把應用程式和程式所需要的「環境」全部打包成一個Image。你可以把 Image 便利地推送到任何地方。
- 並且在任何需要部署的地方將 Image 拉取下來。
- 只要那個地方有 Docker,就可以一鍵啟動你的服務。
※ Dockerfile:一個把服務打包成 Image 的腳本
- 腳本:是一行行由上而下的一個概念。把原本做的事情,寫成一段很多個命令的腳本。
- Dockerfile:基本概念就是透過指令讓Docker去做我不想要重複做的事情,讓它照著腳本來運行。
- 常用Dockerfile腳本編寫指令:
- FROM: 從別人已經寫好的 Image 為基礎,讓使用者不需要從零開始,跳過許多繁瑣的安裝與配置過程。FROM 是 Dockerfile 中的第一條指令,為整個構建過程設定基礎。例如:使用各種框架的Image。
- MAINTAINER: 設定 Image 的作者的資訊,相當於註解。
- LABEL: 設定 Image 的標籤(key-value pair),方便尋找哪個版本的Image。
- EXPOSE: 這個 Image 運行後需要對外開放的端口。也就是想要在Docker上面運行一個後端服務,一定要打開對外開放的一個端口。
- COPY: 把現有的檔案複製進去正在打包的 Image。
- RUN: 執行一段指令。例如:npm install。
- CMD: 宣告一個在 Image 被載入到 Container 被啟動後要執行的指令。例如:使用CMD去執行node然後index.js的這個指令。
※ 總結:
- 通過 Dockerfile 將服務打包成 Imag。
- 將打包好的 Image 上傳到 repository(倉庫的概念)。
- 從 repository 把 Image 下載到主機。
- 在主機通過 Docker 把這個 Image 啟動成 Container。