###### tags: `lsa` # 虛擬化技術 (一) [TOC] ## 虛擬化的興起 * 虛擬化的開始 * 1960 中期,IBM M44/44X 項目首次使用了 VM(Virtual Machine) 和 VMM(Virtual Machine Monitor)一詞,被認為是世界上第一個支持虛擬機的系統。 * 實現多個虛擬化概念,包括 Time Sharing、Paging 以及 VMM :::info **Time Sharing** * 將 CPU 的工作時間切割成很多 Time Slice,例如 0.01 秒,每個 Time Slice 都執行著不同的 process * 因為 CPU 切換速度很快,讓使用者感覺所有 process 同時執行 ![](https://i.imgur.com/A42lCpu.png) ::: :::info **Paging** - 虛擬記憶體定址 - 作業系統會將記憶體中的資料分割成固定大小的區塊,稱為 page - 讓 process 的 Physical Address Space 可以是不連續的 ![](https://i.imgur.com/71tHqxq.png) ::: * 帶動虛擬化技術的風氣 * 1978 年,x86 首次出現在 Intel 8086 CPU * 1980 ~ 1990 年代 * 8086 被 IBM 推出的 PC (Personal Computer) 採用,之後 x86 成為了個人電腦的標準平台 * Windows、Mac 等個人電腦平台使用 x86 架構 :::info **x86** * CPU 指令集架構 * 分成 user mode 和 kernel mode * 特權指令在 kernel mode 執行 ::: * 什麼時候開始逐漸熱門 * ![](https://sw.cool3c.com/user/93262/2020/426239a9-6d04-4d65-8960-0e8094515a93.png?fit=max&w=1400&q=80) > [圖片來源](https://www.cool3c.com/article/152320) * 2005 Intel Virtualization Technology * 支援虛擬化的硬體出現後,有效解決成本、效能問題 > [參考資料](https://www.newton.com.tw/wiki/Intel%20VT) ## 為什麼要虛擬化? * 你印象中的機房 * 裡面有很多櫃子放在那邊 * 很帥!看過去一片都是機器海 * 你老闆眼中的機房 * 都是錢啊!別燒太多 * 需要控制機器的溫度,又要花錢! ### 虛擬化的特點 - :smile:提高資源利用率 - 不用花太多時間維護硬體和基礎設施 - 硬體資源切出來租給別人,賺錢錢 :money_mouth_face: * 前提:伺服器不是滿載的狀況下才做虛擬化 - :smile:輕鬆配置和部署 - 當意外發生時,透過複製受影響的虛擬機就可以立刻部署 - 可快速架設虛擬機,配合臨時需求 - :smile:成本較低 - 不需要花大量的時間和金錢來管理機房 - :cry:架構複雜 - 虛擬機數量過多時,會有硬體分配問題 - 發生問題時,需要檢查一個個虛擬機,費時費力 - :cry:影響性能 - 虛擬機執行時無法直接向硬體資源溝通,須透過 Hypervisor 來完成資源請求 ## 什麼是虛擬化 ? ### 定義 將電腦的各種實體資源,予以抽象、轉換後呈現出來並可供分割、組合為一個或多個虛擬電腦,通常稱為虛擬機器 (VM) ## 虛擬化實現層級 ![](https://i.imgur.com/AZWrFd0.png =50%x) ### 硬體抽象層級的虛擬化 * 硬體本身有提供相對的技術來支援虛擬化 * 代表技術 * Intel Virtualization Technology (Intel VT) * AMD Virtualization (AMD SVM) 代表軟體有 * KVM(Kernel-based Virtual Machine) * 使用 Linux kernel 作為 Hypervisor * 運行速度加快 * Guest OS 的 CPU 指令不用再經過 QEMU 來轉譯便可直接運行,運行速度較快 * <font color=red>**BUT**</font> 只能提供 CPU 和 Memory 的虛擬化,所以它必須結合 QEMU 才能構成一個完整的虛擬化技術 * QEMU-KVM ![](https://i.imgur.com/dQoW5Fb.png =60%x) * QEMU:運行在 user mode,模擬其他 I/O 設備 * KVM:運行在 kernel mode,負責 CPU 虛擬化 + 記憶體虛擬化 ### 硬體虛擬化程度分類 (補充) #### x86 CPU 特權模式 ![](https://i.imgur.com/BmK3bor.png =50%x) * Ring 0:權限最高,通常為作業系統 (Kernel) * Kernel * 直接存取硬體和記憶體 * 使用特權指令 * Ring 1 & Ring 2:通常為周邊裝置的驅動程式 * Ring 3:使用者端所碰觸的 Application(應用程式) :::info **特權指令** ![](https://i.imgur.com/b24T3Xr.png) * I/O Instruction:為了保護 I/O 不被 User Process 濫用 * 記憶體清除指令:防止「User process」存取其他「User process」之記憶體空間以及「Kernel」的記憶體空間 * 暫存器狀態修改指令 * 有關記憶體管理、保護而用的暫存器 * 如:「Base register」、「limit register」 * 「Timer」設定指令 * 為了保護 CPU 不被濫用,防止「User process」無限期/長期佔用 CPU 而不釋放 * 如:「Set」、「Change」 * 「Enable interrupt」、「Disable interrupt」 * 「Halt」 * 當系統無及時的工作需要完成時作業系統會利用此指令以切換至「Idle state」 * 自「User mode」轉換到「Kernel mode」之指令 ::: #### 虛擬化的 CPU 特權問題 * Guest OS 不在 Ring 0 裡面,無法執行特權指令 * 沒有執行硬體資源的權限 Q : VM 怎麼通過 VMM 實現 Guest CPU 對硬體的存取? A : 根據特權原理用半/全虛擬化的技術來完成 #### Full-Virtualization (全虛擬化) ![](https://i.imgur.com/S47ipPx.png =50%x) * 特點 * Guest OS 不知道自己是 VM OS,權限被降成 Ring 1 * 優點:不需要修改 Guest OS Kernel,因此可運作大部分的作業系統種類 * 缺點:指令透過轉譯會消耗較多的硬體資源 #### Para-Virtualization (半虛擬化) ![](https://i.imgur.com/Z0QBUHC.png =50%x) * 須修改 guest os kernel 將特權指令的 function name 改成 hypercll 再由 hypercall 去呼叫 hypervisor * 特點 * Guest OS 自己是 VM OS,權限保持 Ring 0 * 優點:對硬體資源消耗相對較少 * 缺點:可於半虛擬化平台上運作的作業系統種類較少 :::info 指令分為 4 類: * **Privileged Instructions** 特權指令:只能在 kernel mode 下執行,無法在 user mode 下執行。 * **Control Sensitive Instructions** 控制敏感指令:修改 system registers 的指令。 * x86 中此類指令的示例有:PUSHF、POPF、SGDT、SIDT、SLDT、SMSW。 * **Behavior Sensitive Instructions** 行為敏感指令:行為取決於 mode 或 Hardware 配置的指令。 * x86 上此類指令的示例有 POP、PUSH、CALL、JMP、INT n、RET、LAR、LSL、VERR、VERW、MOV。 * **Normal Instructions** 普通指令:其餘指令 ::: :::info **Hypercall** 直接將指令轉換成 hypervisor(kernel) 可以執行的指令,再由 hypervisor 去要硬體資源 ::: ### 指令及架構層級的虛擬化 通過純軟體的方式模擬各種不同 CPU 硬體的指令集來達到虛擬化的目的。 * 優點:可以完全的模擬出所需要虛擬設備的所有特性 * 缺點:性能太差且實現複雜 代表軟體有 * QEMU * 是純軟體實現的虛擬化模擬器 * 指令採用 binary translation * 性能低 ### 作業系統層級的虛擬化 將 OS kernel 虛擬化,可使 Container 共用同個 Host OS。 代表軟體有 * Docker * LXC ### 函式庫層級的虛擬化 每種系統的函式庫都不同,編譯後的結果也不同。 > 例如:stdlib.h 用的是標準函式庫 C ,但如果使用 `.NET` 編譯,同樣功能的函式引用的會是 function name * 優點:可以使用不同系統編譯的檔案 代表軟體有 * Wine: * 容許 [UNIX-like](https://zh.wikipedia.org/wiki/%E7%B1%BBUnix%E7%B3%BB%E7%BB%9F) 作業系統在 [X Window System](https://zh.wikipedia.org/wiki/X%E8%A6%96%E7%AA%97%E7%B3%BB%E7%B5%B1) 運行 Microsoft Windows 程式的軟體 * 不對 Windows 的執行檔本身進行反組譯,而是利用黑箱測試法把 windows 的函式庫一一對照開發文件 :::info * UNIX-like:各種 UNIX 的衍生系統,實作不同,但介面、規格、設計理念都很像 * X Window System: 是一個能夠讓 UNIX-like 圖形介面組成的方式 / 元件 / 方案 * 黑箱測試法:針對軟體介面、功能及外部結構進行測試,而不考慮程式內部邏輯結構 ::: ### 應用層級的虛擬化 以**程式語言**為例: 將高階語言轉譯成一種名為 bytecode 的語言,透過虛擬機器 compile 成為可以直接執行的命令。 * 優點:跨作業系統平台 代表軟體有 * Oracle Java: ![](https://i.imgur.com/7ltp8Et.png) * JVM:Java 虛擬機,不同平台上的 source code 都不同 * bytecode:JVM 的執行碼 * 以太坊 * EVM:以太坊虛擬機 ## Hypervisor - 又稱為 VMM (Virtual Machine Monitor) - 負責管理與分配硬體資源 - 位於實體硬體與虛擬機之間的軟體層 - Host 指主機 - Guest 指虛擬機 - 類型 - Type 1 : Bare Metal Hypervisor - Type 2 : Hosted Hypervisor ![](https://i.imgur.com/F9sPfSe.png) ### Type 1 : Bare Metal Hypervisor ![](https://i.imgur.com/sQBe8Fo.png =80%x) - 直接把 Hypervisor 建立在硬體上 - 直接管理、存取硬體資源 - 呼叫的流程 : Guest OS :point_right: Hypervisor :point_right: 硬體 - 特點 - 效能較好,因為可以直接存取實體硬體 - 例子 - Xen - Firecracker :::info **沒有 Host OS,要怎麼管理全部的東西呢?** - 以 Xen 中,虛擬機叫做 Domain ,縮寫為 dom - dom 0 (domain 0) 是一個有特權 Guset - 最先被啟動並管理 dom U - dom U = unprivileged domains - 負責存取硬體、管理和建立其他虛擬機 (dom u) ![](https://i.imgur.com/Aq3MDwD.png) > [Xen - 學長提供資料](https://wiki.xenproject.org/wiki/Xen_Project_Software_Overview) ::: :::info **AWS Firecracker (VM)** - Open Source - VMM - 在 VMM 上疊加一層 KVM,目的用來取代 QEMU > [參考資料](https://www.amazon.science/publications/firecracker-lightweight-virtualization-for-serverless-applications) ::: ### Type 2 : Hosted Hypervisor ![](https://i.imgur.com/iqOAfqE.png =80%x) - 虛擬機的 Guest OS 透過 Host OS 來存取硬體資源 - 存取硬體流程 : Guest OS :point_right: Hypervisor :point_right: Host OS :point_right: 硬體 - 特點 - 效能比 Type 1 低,因為 Hypervisor 和每台 VM 的工作都必須透過 Host OS 才能存取實體硬體 - 如果 Host OS 出現問題,所有 VM 就不能運作 - 個人電腦適合 Hosted Hypervisor - 例子 - Oracle VM VirtualBox :::info **KVM 是 Type 1 也是 Type 2!** The distinction between these two types is not always clear. For instance, KVM and bhyve are kernel modules that effectively convert the host operating system to a type-1 hypervisor. At the same time, since Linux distributions and FreeBSD are still general-purpose operating systems, with applications competing with each other for VM resources, KVM and bhyve can also be categorized as type-2 hypervisors. > [維基 - Hypervisor](https://en.wikipedia.org/wiki/Hypervisor) ::: | | Bare-Metal Hypervisor | Hosted Hypervisor | | -------- | --- | --- | | 執行方式 | Hypervisor 直接在實體主機硬體上執行 | Hypervisor 在 Host OS 上執行 | | 呼叫流程 | Guest OS/kernel :point_right: Hypervisor :point_right: 硬體 | Guest OS/kernel :point_right: Hypervisor 接收 :point_right: Host OS/kernel :point_right: 硬體 | | 效能 | 較好 | 較差 | ## Container ### 為甚麼要用 Container - 故事時間 - 故事背景 - 指揮官 (虛擬機的管理員) 透過監測系統 (VMM) 發現某台 VM 使用率偏高,資源快耗完,覺得不妙,要趕快加派小兵 (VM) 請求支援 - 如果派 VM 小兵 - 因為 VM image 複製要時間、檔案太大 (Guest kernel)、開機太慢,花了十幾分鐘 VM2 小兵才準備好從基地出發,但一出門就發現敵人已經把家園的塔擊垮了 - 如果派 Container 小兵 - 因為 Host OS 都相同,所以加派小兵時,只需要準備 Container image 就好,包含應用程式的執行時所需要的相關環境與資料 (bins/libs),幾十秒可以準備好從基地出發幫助夥伴 - 所以派 Container 小兵會比派 VM 小兵好,因為啟動快速、記憶體使用量較少 ### 什麼是 Container ![](https://i.imgur.com/oXg7Lj6.png) - 是一個獨立、隔離的空間 - 包含應用程式與相關的函式庫、環境配置檔 - 特點 - 共用 kernel - 啟動快速,因為不用經過開機的流程 - 跟 VM 相比,較輕量 - 環境一致,不可以跨平台使用 - 獨立、隔離,因為用 cgroups 和 namespace 做到 Contanier 隔離,達到相對安全 :::info **什麼是 OS ?** - 由 kernel、其他應用程式、工具軟體組成的 ![](https://img-blog.csdnimg.cn/20200923142048223.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTgzMzUwOQ==,size_16,color_FFFFFF,t_70) > [參考資料 - 圖片來源](https://www.tutorialspoint.com/operating_system/os_linux.htm) 在 Container 中需要什麼元素 ? - 需要 - 包含執行應用程式所需的相關的函式庫、環境配置檔 - 不需要 - kernel ::: :::success 把程式包在 Container 裡,讓他跑起來 ::: ### OCI - 全名:Open Container Initiative - 定義 Container Formats、執行 Container 的方式 - 目的:希望能夠提供基於作業系統層級的虛擬化介面 - 定義兩大標準 - Image Specification :::info **Container Image** - Image 是一個 read-only 的模板,可以用來重複建立 Container > 像蛋糕的模型 ::: - Runtime Specification #### Image Specification - Container Image 檔案標準,如何建立 Image - **Image 的組成** ![](https://raw.githubusercontent.com/opencontainers/image-spec/main/img/build-diagram.png) > [圖片來源](https://github.com/opencontainers/image-spec/blob/main/spec.md) 1. Layer:相關的檔案系統配置,包含檔案的位置/內容/權限 2. Image Index:用來描述該 Image 的檔案 3. Configuration:應用程式相關設定檔案,包含使用的參數、用到的環境變數等 - 當應用程式要包裝成 Image 時,要符合以下規範 1. Image Layer Filesystem Changeset - 定義如何將資料以二進位的方式儲存,以及新增、刪除、修改 Filesystem 成為一個 Blob - Blob 稱為 Layer 2. Image Configuration - 定義 Filesystem 的資訊 3. Image Manifest - image 的組成元素 4. Image Index - Image Manifest 的 Index 5. Image Layout - 一個目錄結構,包含 Image 的內容 6. Conversion - 如何將 Image 轉換成 Runtime 的 Filesystem Bundle 7. Descriptor - 一個目標內容的位置 - Descriptor 包含內容的類型、ID (digest)、大小 - ![](https://i.imgur.com/aXHslfL.png) >[圖片來源](https://blog.tienyulin.com/open-container-initiative-oci/) :::info **Blob** 全名 Binary large object 資料以 binary 的形式儲存 ::: #### Runtime Specification - 執行標準、怎麼運作 Container - **Container 的三大規範內容** 1. Configuration - 設定檔案格式 - 不同的作業系統,有不同的規範 - 明確表示建立 container 需要的參數 - Container 執行時的環境要依照**設定檔**來建立 2. FileSystem Bundle - 檔案系統的資料夾 3. Runtime and Lifecycle ![](https://www.devopsschool.com/blog/wp-content/uploads/2018/07/docker-containers-lifecycle-phase-simple.jpg) >[圖片來源](https://www.devopsschool.com/blog/lifecycle-of-docker-containers/) :::info - Query State:查看目前 Container 是甚麼狀態 - creating:正在建立 - created:以建立好,但尚未被執行 - running:正在執行 - stopped:停止執行 - Create:建立 Container - Start:啟動 Container - Kill:強制停止 Container - Delete:刪除 Container > [參考資料 - Runtime and Lifecycle](https://github.com/opencontainers/runtime-spec/blob/main/runtime.md#operations) ::: :::success **符合 OCI 有什麼好處?** * 只要 Container Engine 符合 OCI 的標準規範的話,介面、運作方式會有一定的相似處 * 例如:podman 可以使用、管理 docker image、 docker container ::: ### Linux 隔離 process 的方式 - 前言 - 學校的每一位同學都有自己的學號,在不同班級中也有自己的座號 - 學號 :point_right: 以 Host 的角度看 process ID - 班級 :point_right: namespaces - 班級中的座號 :point_right: namespaces 下的 pid #### namespaces - 資源隔離 - 讓 Process 不會互相影響 - 限制 Container 所能看到的東西,不同 namespace 的程式互相看不見 - 當建立 Container 時,Container Engine 會為 container 建立一組 namespace :::info - Process ID (pid) - 每個 Container 都有可以看到自己 namespace 的 pid - Mount (mnt) - Container 有自己的 mount table - 一個 namespace 中的 process 無法訪問掛載在另一個 namespace 中的 Filesystem - Network (net) - 負責網路資源的隔離 - 包含網卡、iptables 等資源 - Inter-Process Communication (ipc) - process 只能和相同 container (namespace) 內的 process 溝通 - UNIX Time-Sharing (UTS) - Container 有自己的 host name 和 domain name - 讓每台 Container 都有自己的 host name 和 domain name,可以被看作一個獨立的網路節點 - User ID (user) - 讓 user ID、group ID 都是獨立的 - the container will be able to remap user and group IDs from the host to local users and groups within the container. - 包括 user ID、group ID、根目錄、以及特殊權限等,該命名空間技術支持進程在容器內外擁有不同級別的權限 ::: #### **實作** * pull a image * `sudo docker pull ubuntu` * ![](https://i.imgur.com/47fvhcK.png) * 建立 container * `sudo docker run -it ubuntu bash` * ![](https://i.imgur.com/mpJq4VN.png) * (進入 Container 的介面) * `ps aux` * ![](https://i.imgur.com/t3KF4cw.png) * (開新的 terminal) * 看 docker 下的 process 有哪些 * `sudo docker ps -a` * ![](https://i.imgur.com/bwY5k09.png) * 看 test1 (Container) 的 process 有什麼 * `sudo docker top <Container ID>` * ![](https://i.imgur.com/hrx6fKS.png) * 看 process 的 pid、NSpid * `sudo cat /proc/<Container 在 host 的 pid>/status` * ![](https://i.imgur.com/LIndQua.png) * namespaces * `cd /proc/<Container 在 host 的 pid>/` * `sudo ls -al ns` * ![](https://i.imgur.com/msPmbb7.png) #### cgroups - 控制 Container 內的資源限制 - 用來控制 Container 使用 Host 上的硬體資源,限制、占用和隔離一組 process 對資源的使用(CPU、記憶體、磁碟 I/O、網路等) - 四大特性 - 資源限制:限制了 task 可以使用多少資源,例如超過設定的記憶體上限,就發 OOM - 運行於作業系統內的 Process,在 cgroups 內被稱為 task - 優先級分配:不同的 Container 可以擁有不同的 CPU 跟 Disk I/O 使用優先順序 - 資源統計:計算 Container 的資源使用量,如 CPU、記憶體等使用情況 - 控制:可以暫停 Container 中的 process **小 DEMO** * 在 Host 下 * `cd /proc/<Container 在 host 的 pid>` * `cat cgroup` * ![](https://i.imgur.com/98j6BT0.png) ### VM v.s. Container ![](https://i.imgur.com/Y08J6S7.png) | | VM | Container | | -------- | -------- | -------- | |虛擬化層級|硬體虛擬化|作業系統虛擬化| | OS | Guest OS | Host OS | ||如果有 3 台 VM,3 台可以是不同作業系統|如果有 3 台 Container,3 台都是共用 Host kernel<br/>`注意:Container 的版本不能比 Host OS 還新`| |隔離|隔離 machine<br/>將主機分成多個 server |隔離 process<br/>將每個應用程式分成單獨的 process | |每台資源使用量|多|少| |安全等級|高 😁|中 🙂| ![](https://i.imgur.com/ke8IrAd.png) :::info **安全獨立的定義** * 不會對其他 VM/Container 造成影響 **VM** * 因為 VM 並沒有共用 kernel,都是用各自的 Guest OS * 如果 VM1 的 OS 有問題的話,也不會影響到 VM2 **Container 較不安全** * 因為 Container 共用 kernel * 如果 kernel 有問題的話,Container1 對 kernel 做的事,會影響到 Container2 ::: :::info **unprivileged mode** * 預設的 Container 資源會分隔開來 - 會有一個遮罩,檢查你有沒有權限,將 Host 和 Container 的資源隔開來 * 預設不能存取 Host 上所有的設備 - 因為有用 namespaces,cgroups 做遮罩限制 **privileged mode** * 可以存取 Host 上所有的設備 ![](https://phoenixnap.com/kb/wp-content/uploads/2021/04/docker-privileged-mode-explained.png) > [圖片來源](https://phoenixnap.com/kb/docker-privileged) ::: ## 各種 Container ### LXC/LXD * LXC * Linux Containers 的縮寫 * 目標:提供一個接近完整的 Linux 作業系統環境,但沒有 kernel ![](https://i.imgur.com/cYzuARe.png =70%x) * LXD * 是 LXC 的 Manager,用來管理和建立 Linux Container ![](https://i.imgur.com/9nRBjYx.png) >[圖片來源](https://linuxcontainers.org/lxc/introduction/) ### Docker - 特點:一個 Container 執行一個 process - docker 的 best practice - 包含元素:code, runtime, system tools, system libraries and settings. ![](https://i.imgur.com/mL8oUnD.png =70%x) #### LXC v.s. Docker ![](https://i.imgur.com/pT6ZF4u.png) ![](https://i.imgur.com/GBeUtT3.png) ### Podman * 沒有 Daemon,是透過 RunC runtime process 直接跟 Linux kernel 溝通來執行 Container :::info **RunC** * 是一個 CLI 工具,根據 OCI 標準來建立和執行 Container * 輕量級的工具,可以不用透過 docker Engine,直接執行 Container ::: * 特點 * 符合 OCI Runtime Spec * 可以在非 root 環境下執行 :::info **Container Daemon** * 管理、建立 Container ::: #### Docker v.s. Podman ![](https://media-exp1.licdn.com/dms/image/C4E22AQFwP9ecfBb81g/feedshare-shrink_2048_1536/0/1636952989092?e=1649894400&v=beta&t=HJRHHakJarDztuOBrqEWtHW2QVo9P97G3uDXE1U51Pg) >[圖片來源](https://www.linkedin.com/posts/sebastiaan-stoffels-6846462_podman-docker-activity-6866160672246517760-mOFL) ### AWS Firecracker (VM) #### 為什麼 Firecracker 會出現? - ![](https://i.imgur.com/SnhZ6Gd.png) > [圖片來源](https://aws.amazon.com/cn/blogs/china/deep-analysis-aws-firecracker-principle-virtualization-container-runtime-technology/) - 因為 Docker Container 共用 kernel,和 VM 比起來安全性還是低很多 - 所以需要讓這些 Container 跑在 VM 裡,達到安全隔離的需求 > [參考資料](https://www.amazon.science/publications/firecracker-lightweight-virtualization-for-serverless-applications) #### 介紹 - Open Source - 專為 serverless function 和 container 提供安全、快速部屬的環境 :::info **serverless function** * 將單一用途的程式碼交給雲端服務公司管理 * 使用者不需要再自行管理底層機器和維護工作 ::: - Firecracker 中的 VM 稱為 microVM - Firecracker (VMM) 調用 KVM 的技術來建 microVM - ![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/deep-analysis-aws-firecracker-principle-virtualization-container-runtime-technology2.png) >[圖片來源](https://github.com/firecracker-microvm/firecracker/blob/main/docs/design.md) - 取代 QEMU - 沒有模擬完整的電腦硬體設備,只模擬 5 個設備 - virtio-net - virtio-block - 以上分别用在 MicroVM 的網路和硬碟 I/O 存取 - virtio-vsock - 是 Host 和 Guest 之間的通訊設備 - VMM 可以透過 virtio-vsock 知道裡面的資訊 - serial console - 顯示 log 資訊 - minimal keyboard controller 關機鍵盤 :::info **VirtIO** 是一種半虛擬化 I/O 驅動方式 減少了 user mode 和 kernel mode 之間的切換次數 ::: - 更輕量、啟動更快速 - 可以透過 Restful API 去控制 Container :::info **Restful API** 讓不同軟體/程式在網路中互相傳遞資訊 ::: ![](https://s3.cn-north-1.amazonaws.com.cn/awschinablog/deep-analysis-aws-firecracker-principle-virtualization-container-runtime-technology5.png) >[圖片來源](https://github.com/firecracker-microvm/firecracker/blob/main/docs/design.md) ### AWS Fargate * Fargate 透過 firecracker-containerd runtime 利用 Firecracker microVM 執行 Container * firecracker-containerd * control plugin * 管理 lifecycle of the runtime * 實行 API,幫助我們管理 microVM 的 lifecycle * runtime * 將 microVM 外的 containerd 連接到 Firecracker (VMM) 的 runtime。 * agent * 在 microVM 內執行的 agent,它透過 containerd 的 containerd-shim-runc-v1 調用 runC,在 microVM 裡建立 標準 Linux Container * root file filesystem image builder * 用於建立 firecracker microVM 根文件系統(root filesystem),包含 runc 和 firecracker-containerd agent ![](https://d2908q01vomqb2.cloudfront.net/fe2ef495a1152561572949784c16bf23abb28057/2020/04/07/Fargatehood2.png) > [圖片來源](https://aws.amazon.com/tw/blogs/containers/under-the-hood-fargate-data-plane/) ![](https://i.imgur.com/MShtwMx.jpg) ## Docker ![](https://i.imgur.com/ybFmtqw.png =60%x) :::info [windows container](https://docs.microsoft.com/zh-tw/virtualization/windowscontainers/deploy-containers/containerd) ::: ### Docker 架構 ![](https://i.imgur.com/Ufd0MpU.png) > [圖片來源](https://docs.docker.com/get-started/overview/) #### Docker client * 將命令發送到 dockerd * Communicate with 多個 Dockerd #### Docker daemon (Dockerd) * Listens for Docker API 請求 * Socket-unix * unix domain socket (or IPC socket) 是預設的偵聽方式 * created at `/var/run/docker.sock` * 需要 root 權限 , or docker group membership * 管理 Docker object * images, containers, networks, and volumes. * Communicate with other Dockerd #### Docker Registries * Registry 是集中存放 image 的地方,可以是 public 和 private * public * [Docker Hub](https://hub.docker.com/):docker 預設使用的 registry,是一個任何人都可以使用的 public registry * [Google Container registry](https://cloud.google.com/container-registry?hl=zh-tw) * private * [Azure Container Registry](https://azure.microsoft.com/zh-tw/services/container-registry/#overview) ### Docker Object #### Docker Images ![](https://i.imgur.com/9iy7sZO.png) > [圖片來源](https://medium.com/@y721.tsai/docker-steve-notes-c741967c45b2) * 為一個 read-only 的模板,包含了構建 Docker Container 的必要資訊 * 可以是多個 Docker image 堆疊而成 :::info **bootfs**:用來載入 linux kernel ::: * 取得 Docker image 大致有三種方式: 1. 從 Docker Registry `pull` 下來 * 例如:Docker Hub 3. 在其他環境使用匯出 Docker image 並在自己電腦上 `load` 5. 使用 Dockerfile 自行配置 image ##### Dockerfile * 定義 build 和 run image 所需的步驟 * Dockerfile 中的每條指令都會在 image 中創建一個 Layer,最多達 127 層 * `command1 && command2 [&& command3 ...]` ```terminal= FROM nginx ADD index.html /usr/share/nginx/html/ ``` ![](https://i.imgur.com/NvoApmJ.png =50%x) #### Docker Container * 每個 images 可建立多個互相隔離的 Docker Container * 支援開始、停止、修改、刪除的操作 * 在 Docker image 最上層加上一層可讀可寫層 ##### 啟動 Docker Container 啟動 Docker Container 時主要會是三個部份組合而成的。 * 最上層:User 可以在此層去讀寫資料 * 第二層:Init Container 的設定 * 底層:Docker Image #### Network * `Bridge Network`: * 預設 Network drivers * Docker 會分配一個內網 ip 給 Container ![](https://i.imgur.com/skdt6yb.png =60%x) * `Host Network`:在該 Container 中可以直接使用 Network,不做 network namespace,不需要網路隔離,和 Host 共用相同的 network model。 * `Overlay Network`: * 不同的實體主機內的 Container 之間可以互相的溝通 * 將多個 docker daemon 連接在一起,使 swarm service 能夠相互溝通 ![](https://i.imgur.com/SCSHCgG.png =70%x) * `Macvlan Network`: * 允許你在主機的一個網路卡上配置多個虛擬的網路卡 * Container 的網路和 Host 都在同一個網段中 * 擁有自己網卡的 Container 分別在整個網路架構上被當成各自獨立的實體機器 ![](https://i.imgur.com/ZrJCRaz.png =60%x) :::info macvlanc:可讓使用者在同一張實體網卡上設定多個 MAC address ::: * `none`: * 對於該 Container,無法使用 Network * Network plugins: * 通過 Docker 安裝和使用第三方 Network plugins * Plugins 可從 Docker Hub 或第三方供應商獲得 ##### 使用情境 | Network | 使用情境 | | ------- | -------- | | Bridge | 對網路沒有要求,彼此能溝通就好 | | Host | 容器本身會需要對宿主機的網路環境進行操作或監控時想要直接存取 | | overlay | 跨 Docker Daemon (不同 Host 上的 Docker) 的 container 溝通 | | macvlan | 舊的 Application 轉換到 Container 時想沿用原本的網路架構 | | None | 開發 Network model | #### Volume Volume 是 Container 永久保存 Data 的地方。 ##### Container Lifecycle ![](https://i.imgur.com/ATTCeBT.png =70%x) > [圖片來源](https://techmormo.com/posts/docker-made-easy-3-container-lifecycle/) ##### 問題 ![](https://i.imgur.com/7QIAv52.png =80%x) * Container 本身是無狀態的或非持久性的 * Container 被刪除時,所儲存的 Data 都會消失 * 重新創建 Container 時,它們包含的 Data(status)會丟失 ##### 解決方法 ![](https://i.imgur.com/R4DtWNA.png =80%x) ![](https://i.imgur.com/OsRtwCB.png =80%x) > [圖片來源](https://medium.com/techmormo/how-do-docker-volumes-enable-persistence-for-containers-docker-made-easy-4-2093a1783b87) * Bind Mount:Stored ==anywhere== on the host filesystem * Volume:Stored in a part of the host filesystem which is managed by Docker (`/var/lib/docker/volumes/` on Linux) * 選擇 Volume 的原因 * 可移植性:Volume 由 Docker 管理,讓 Container 更具可移植性 * 安全性:Container 被限制在 filesystem 的某一部份,避免允許 Container 取訪問系統文件/目錄 * 可訪問性:可將 data 存儲在 remote servers 或 cloud * 掛載在外部存處裝置 * ex:NAS (Network Attached Storage) ## DEMO ![](https://i.imgur.com/7R2z9EF.png) ### 使用 Docker 的流程 ![](https://i.imgur.com/58v73xl.png) > [圖片來源](https://www.hellosanta.com.tw/knowledge/category-38/post-130) #### 前置作業 實作網站 - [Play with Docker](https://labs.play-with-docker.com/) 先建立 Docker 帳號 ![](https://i.imgur.com/26qAN8H.png) ![](https://i.imgur.com/3aFkGdZ.png) #### (1)`pull` * 指令:`docker pull nginx` ![](https://i.imgur.com/Na8m655.png) * 指令:`docker images` : 查看本機有哪些 image ![](https://i.imgur.com/yYzHjNt.png) #### (2) `run` * 指令:`docker run -d -p <host port>:<container port> <image>` ![](https://i.imgur.com/5kgZEY1.png) * `-d`:讓程式在背景運行 * `-p`:指定 `host port`:`container port` 的轉送 * 出現 `port` 網頁連結 ![](https://i.imgur.com/6YXYlwJ.png) * 成功開啟網頁 ![](https://i.imgur.com/UnrWDhY.png) * 也可以再連主機其他 `port` ![](https://i.imgur.com/mbWRHU7.png) * 指令:`docker ps` ![](https://i.imgur.com/hzyXEJV.png) * `ps`:列出目前所有的 `docker container` #### (3) start stop restart * `docker container stop <containerID>` * `docker container start <containerID>` * `docker container pause <containerID>` * `docker container unpause <containerID>` * `docker container restart <containerID>` * `docker exec -it <image ID> bash` ![](https://i.imgur.com/aJlksQG.png) * `-i`:跟 Container 做互動 * `-t`:提供一個 terminal * **修改 nginx** * `cd /usr/share/nginx/html` ![](https://i.imgur.com/b7Wq5Ep.png) * `vim index.html` ![](https://i.imgur.com/PImTAK0.png) * 將 `nginx` 畫面重新整理 ![](https://i.imgur.com/VtMIHUs.png) #### (4) `commit` * `docker commmit <ContainerID> <NewImage>` ![](https://i.imgur.com/QW3Z5Fj.png) * `commit`:將一個更改過的 Container 新建一個 image * `docker run -d -p <host port>:<container port> <NewImage>` * 打開剛剛設的 `host port` ,網頁會呈現剛才的頁面 #### (5) `build` * `mkdir <dirname>` ![](https://i.imgur.com/BtcdMAA.png =50%x) * `vim Dockerfile` ![](https://i.imgur.com/RJGYoPe.png =60%x) ```terminal= FROM nginx ADD index.html /usr/share/nginx/html/ ``` * `vim index.html` ```= <h1>LSA Docker DEMO</h1> ``` * `docker build -t <imageName> .` * `-t`:tag * `.`:從當前目錄 ![](https://i.imgur.com/hLJMCwM.png) * `docker run -d -p <host port>:<container port> <NewImage>` ![](https://i.imgur.com/hlrKblb.png) ![](https://i.imgur.com/4FErsoa.png) #### (6) `push` * `docker image tag imagelsa:latest <userID>/<imagename>:v1` ![](https://i.imgur.com/Q7oZgER.png) * `docker login` ![](https://i.imgur.com/hNApyFT.png) * `docker push 108213052/lsa:v1` ![](https://i.imgur.com/A12OYxi.png) ![](https://i.imgur.com/mnpD3ae.png) #### (7) `save` `docker save 'image' > 'filename'.tar` ![](https://i.imgur.com/h801C6s.png) ![](https://i.imgur.com/ZqeXD3o.png =50%x) #### (8) `load` * 先確認要刪 image `nginx` ![](https://i.imgur.com/eDqSkIK.png) * `docker container stop <containerID>` ![](https://i.imgur.com/lqcncHV.png) * `stop`:Stop running containers * `docker container rm <containerID>` ![](https://i.imgur.com/5iPqpWm.png) * `rm`:Remove containers * `docker rmi <imagename>:tag` ![](https://i.imgur.com/5sYz4V5.png) * `rmi`:Remove images * `docker load < nginx.tar ` ![](https://i.imgur.com/LbCUOYf.png) ### [Docker Swarm](https://docs.docker.com/engine/swarm/key-concepts/) #### 定義 A cluster of Docker engines, or nodes, where you deploy services. * swarm:叢集管理,子命令有init, join, leave, update * service:服務建立,子命令有create, inspect, update, remove, tasks * node:節點管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm * stack / deploy:用於多應用部署 #### Node ![](https://i.imgur.com/YD7CcCW.png) * manager node:負責管理 Node Worker 與協調 Container 的部署工作 * worker node:負責運行相關的 service 來執行 task #### Service ![](https://i.imgur.com/crJMKxy.png) > [圖片來源]() * Load balancing * 高效便捷的初始設置 * 可跨多主機網絡 * 不提供存儲選項 * Docker 是一家營利性公司,某些工具不是開源的 * 例如:Docker Desktop --- * manager:`docker swarm init --advertise-addr <ip>` * `docker swarm init`:Initialize a swarm * `--advertise-addr` ![](https://i.imgur.com/adK9G9y.png) * `docker swarm join --token SWMTKN-1-4jd8i1c4tcrsxtf2fku8rm4dbysd26m1ubalyxqhixa5kz30dq-1nscj6hl5pbvxd9hvpz9bxt14 192.168.0.18:2377` ![](https://i.imgur.com/CRTvX52.png) * `docker node ls` ![](https://i.imgur.com/msfHVrv.png) * `docker network create --driver overlay <networkName>` ![](https://i.imgur.com/begBuJZ.png) * `create`:Create a network * `--driver`:Driver to manage the Network * `docker network ls` ![](https://i.imgur.com/k7L72X4.png) * `docker service create --network vote --name voteapp --replicas 3 -p 8081:80 docker/example-voting-app-vote` ![](https://i.imgur.com/Rkw6C2e.png) * `create`:Creates a service * `--network`:Network attachments * `--name`:Service name * `--replicas`:Number of tasks * `docker service ls` ![](https://i.imgur.com/ToSXBAj.png) * `docker service ps voteapp` ![](https://i.imgur.com/xHM70vr.png) #### **Load balancing** ![](https://i.imgur.com/YrQH7at.png) > [圖片來源](https://medium.com/@webber.cheng/container-orchestration-docker-built-in-swarm-mode-%E5%AE%B9%E5%99%A8%E7%B7%A8%E6%8E%92-2be5d4959c3f) * manage:`iptables -L -nv -t nat` ![](https://i.imgur.com/GYOyqGb.png) * `-L`:List the rules in a chain or all chains * `-n`:number * `-v`:詳細 * `-t`:table * node2:`ifconfig` ![](https://i.imgur.com/8PZQfY5.png) * `docker network inspect docker_gwbridge` ![](https://i.imgur.com/19InmM5.png) * `inspect`:Returns information about one or more networks * `nsenter --net=/var/run/docker/netns/ingress_sbox` ![](https://i.imgur.com/uTob40z.png) * `nsenter --net`:enter network namespace * `iptables -L -nv -t mangle` ![](https://i.imgur.com/hLTzjqU.png) * `ipvsadm -L` ![](https://i.imgur.com/M3BunoY.png) * `ipvsadm`:Linux Virtual Server administration ### [Docker Swarm](https://docs.docker.com/engine/swarm/key-concepts/) #### 定義 A cluster of Docker engines, or nodes, where you deploy services. * swarm:叢集管理,子命令有init, join, leave, update * service:服務建立,子命令有create, inspect, update, remove, tasks * node:節點管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm * stack / deploy:用於多應用部署 #### Node ![](https://i.imgur.com/YD7CcCW.png) * manager node:負責管理 Node Worker 與協調 Container 的部署工作 * worker node:負責執行 Container #### Service ![](https://i.imgur.com/crJMKxy.png) > [圖片來源]() * **Load balancing** * swarm manager uses ingress load balancing * 如果不指定 port ,swarm manager 會為 service 分配一個 30000~32767 範圍內的port * Swarm manager node 為 swarm 中的每個服務分配一個唯一的 DNS 名稱,並對運行的 container 進行負載平衡 * 可以通過 swarm 中的 DNS 查詢在 swarm 中運行的每個 container #### 特點 * :smile: Load balancing * :smile: 高效便捷的初始設置 * :smile: 可跨多主機網絡 * :cry: 不提供存儲選項 * :cry: Docker 是一家營利性公司,某些工具不是開源的 * 例如:Docker Engine 和 Docker Desktop ![](https://i.imgur.com/AyJuiaN.png) ![](https://i.imgur.com/YrQH7at.png) > [圖片來源](https://medium.com/@webber.cheng/container-orchestration-docker-built-in-swarm-mode-%E5%AE%B9%E5%99%A8%E7%B7%A8%E6%8E%92-2be5d4959c3f) --- * manager:`docker swarm init --advertise-addr <ip>` ![](https://i.imgur.com/adK9G9y.png) * `docker swarm join --token SWMTKN-1-4jd8i1c4tcrsxtf2fku8rm4dbysd26m1ubalyxqhixa5kz30dq-1nscj6hl5pbvxd9hvpz9bxt14 192.168.0.18:2377` ![](https://i.imgur.com/CRTvX52.png) * `docker node ls` ![](https://i.imgur.com/msfHVrv.png) * `docker network create --driver overlay vote` ![](https://i.imgur.com/begBuJZ.png) * `docker network ls` ![](https://i.imgur.com/k7L72X4.png) * `docker service ls` ![](https://i.imgur.com/ToSXBAj.png) * `docker service ps voteapp` ![](https://i.imgur.com/xHM70vr.png) ## 參考資料 :::spoiler ### 虛擬化 * [參考資料 - time sharing](https://www.easyatm.com.tw/wiki/%E5%88%86%E6%99%82%E7%B3%BB%E7%B5%B1) * [參考資料 - paging](https://mropengate.blogspot.com/2015/01/operating-system-ch8-memory-management.html) * [虛擬化技術發展編年史](https://kknews.cc/zh-tw/news/6a6xrkl.html) * 虛擬化特點 * https://www.ibm.com/cloud/blog/5-benefits-of-virtualization * https://read01.com/zh-tw/3z5aoMy.html#.YiWbSBBBy3I - [維基 - Hypervisor](https://zh.wikipedia.org/wiki/Hypervisor) - [oracle - Hypervisor 種類](https://docs.oracle.com/cd/E50245_01/E50249/html/vmcon-hypervisor.html#) - [Virtualization Explained](https://www.youtube.com/watch?v=FZR0rG3HKIk&ab_channel=IBMTechnology) - [IBM - Hypervisor 的性質](https://www.ibm.com/tw-zh/cloud/learn/hypervisors) - [宿主虛擬化和裸機虛擬化](https://www.w3study.wiki/a/202110/1424775.html) - [Red Hat - What is a hypervisor?](https://www.redhat.com/en/topics/virtualization/what-is-a-hypervisor) - [What's the difference between Type 1 vs. Type 2 hypervisor?](https://searchservervirtualization.techtarget.com/feature/Whats-the-difference-between-Type-1-and-Type-2-hypervisors) - [The Definitive Guide to Bare Metal Servers for 2021](https://phoenixnap.com/blog/what-is-bare-metal-server) - [What is Bare Metal Hypervisor](https://phoenixnap.com/blog/what-is-bare-metal-hypervisor) - [參考資料 - Bare Machine and Resident Monitor](https://www.geeksforgeeks.org/bare-machine-and-resident-monitor/) ### Container * [pid_namespaces](https://man7.org/linux/man-pages/man7/pid_namespaces.7.html#top_of_page) * [cgroups](https://www.cnblogs.com/sparkdev/p/8296063.html) * [Docker與物理機-相愛相殺的隔離機制](https://kknews.cc/zh-tw/code/v6b9lzl.html) * [容器化技術的網路難題,為什麼它是安全的?](https://www.grandsys.com.tw/news/rd/901-linux-docker) * * [LXD 和 Docker®、Kata 表格](https://www.qnap.com/zh-tw/software/container-station) * [Container Engines 介紹](https://www.aquasec.com/cloud-native-academy/container-platforms/container-engines/) * [Windows Container 技術大剖析](https://www.ithome.com.tw/news/109035) * [How Do Containers Contain? Container Isolation Techniques](https://blog.aquasec.com/container-isolation-techniques) * [什么是 Linux 容器?](https://www.redhat.com/zh/topics/containers/whats-a-linux-container#%E4%B8%8D%E5%B0%B1%E6%98%AF%E8%99%9A%E6%8B%9F%E5%8C%96%EF%BC%9F) * [Cgroup與LXC簡介](https://www.twblogs.net/a/5c68fc3bbd9eee5c86dc4596) * [How Do Containers Contain? Container Isolation Techniques](https://blog.aquasec.com/container-isolation-techniques) :::