# Virtual Machine (CPU虛擬化)
#### 虛擬化的興起
- 1960 中期,IBM M44/44X 項目首次使用了 VM(Virtual Machine) 和 VMM(Virtual Machine Monitor)一詞,被認為是世界上第一個支持虛擬機的系統。
- 實現多個虛擬化概念,包括 Time Sharing、Paging 以及 VMM
#### Time Sharing
> - 將 CPU 的工作時間切割成很多 Time Slice,例如 0.01 秒,每個 Time Slice 都執行著不同的 process
> - 因為 CPU 切換速度很快,讓使用者感覺所有 process 同時執行
> 
### Paging
>- 虛擬記憶體定址
>- 作業系統會將記憶體中的資料分割成固定大小的區塊,稱為 page
>- 讓 process 的 Physical Address Space 可以是不連續的
>
- 什麼時候開始逐漸熱門

- 2005 Intel Virtualization Technology
- 支援虛擬化的硬體出現後,有效解決成本、效能問題
參考資料:https://www.newton.com.tw/wiki/Intel%20VT
#### 硬體虛擬化程度分類
- x86 CPU 特權模式

- Ring 0:權限最高,通常為作業系統 (Kernel)
- Kernel
- 可直接存取硬體和記憶體
- 使用特權指令
- Ring 1 & Ring 2:通常為周邊裝置的驅動程式
- Ring 3:使用者端所碰觸的 Application(應用程式)
#### 特權指令(Privileged Instruction)
>1. 凡是可能引起系統重大危害的指令,均可設為特權指令
>2. 只允許在kernel mode上執行(由kernel)

>1. 此圖是當一個用戶程序發起system call時,如何從user mode 切換到kernel模式,然後在執行完system call後再切換回user mode的流程。
>2. 所謂的"trap"(Software 所產生的Interrupt)和"return"是指程序從user mode切換到kernel mode和從kernel mode切換user mode的過程。當process發起system call時,會觸發一個trap,使得process從用戶模式(mode bit = 1)切換到核心模式(mode bit = 0)。在kernel mode下,操作系統可以執行privileged instruction。當system call完成後,process再次切換回user mode,以繼續執行其他非特權操作。
所以,這張圖雖然主要描述的是系統呼叫的過程,但它也間接地展示了在核心模式下,系統可以執行特權指令的概念。
#### 虛擬化的 CPU 特權問題
- Guest OS 不在 Ring 0 裡面,無法執行特權指令
- 沒有執行硬體資源的權限
Q : VM 怎麼通過 VMM 實現 Guest CPU 對硬體的存取?
A : 根據特權原理用半/全虛擬化的技術來完成
#### Full-Virtualization (全虛擬化)

- 特點
- Guest OS 不知道自己是 VM OS,權限被降成 Ring 1
- 優點:不需要修改 Guest OS Kernel,因此可運作大部分的作業系統種類
- 缺點:指令透過轉譯會消耗較多的硬體資源
#### Para-Virtualization (半虛擬化)

- 須修改 guest os kernel 將特權指令的 function name 改成 hypercll 再由 hypercall 去呼叫 hypervisor
- 特點
- Guest OS 自己是 VM OS,權限保持 Ring 0
- 優點:對硬體資源消耗相對較少
- 缺點:可於半虛擬化平台上運作的作業系統種類較少
- Hypercall
直接將指令轉換成 hypervisor(kernel) 可以執行的指令,再由 hypervisor 去要硬體資源
- 指令及架構層級的虛擬化
>通過純軟體的方式模擬各種不同 CPU 硬體的指令集來達到虛擬化的目的。
>- 優點:可以完全的模擬出所需要虛擬設備的所有特性
>- 缺點:性能太差且實現複雜
>- 代表軟體:QEMU
>1. 是純軟體實現的虛擬化模擬器
>2. 指令採用 binary translation
>3. 性能低
### 作業系統層級的虛擬化
>將 OS kernel 虛擬化,可使 Container 共用同個 Host OS。
>代表軟體有
Docker、LXC
>它允許你在相同的作業系統內核上運行多個隔離的用戶空間實例,這些實例被稱為容器(containers)。每個容器都運行著一份軟件、其依賴項以及運行時所需的庫,就好像它們運行在一個獨立的作業系統中一樣,但實際上它們共享同一個主機作業系統的內核。
---
### Virtual Machine


>利用Software 技術模擬出一套與底層硬體一模一樣的功能介面,為抽象化機器(abstract machime)
>VM的地位與底層實際machine一樣,VM可以安裝OS,OS可以執行Application
#### VM 特點
>1.每個應用程式 (App)擁有獨立甚至相互不同的作業系統、環境
>2.管理 Host 的資源 (CPU、RAM、Storage)並分配於各VM,供 App有效利用
>3.透過 Hypervisor 管理 VM 快照 (Snapshot),以利災難恢復 (Disaster Recovery)
>4. VM 是run 在user mode上,OS才是kernel mode
>5. VM 比 container 安全,因為VM是完全獨立運行(run 在user mode上)。不會直接用到底層 Host OS 的 kernel.
#### 好處:
> 一個實際的machine(一個實體硬體) 可以創造出多個VM,可裝多套OS:
> 1. 節省成本
> 2. 可測試新開發的OS在VM上,壞掉對整體也不影響
> 3. 提升系統安全性
> 4. 利於開發、研究
> 5. 可增加在cloud computing的資源利用率


### 缺點:

[底層運作]

[VM種類]:
1. Full Virtualization

2. Parallel-virtualization

3. JAVA Virtual Machine
>
#### [VMM(hypervisor)製作層次]
分類-



#### Hypervisor 0
> Hardware level
#### Hypervisor 1
> Kernel level(OS),最常見,企業的cloud service 採用

#### Hypervisor 2
> User level
> eg. Parallel Desktop

[VM優點]:
>1. 
>2. 
- 虛擬化技術對於雲端計算的成熟有著重要影響,
- 原因:
>1. 資源共享與最佳化:透過虛擬化,單一的實體伺服器可以運行多個VM,使資源得到更高效的利用。
>2. 彈性擴展:雲端服務提供商可以根據需求快速地增加或減少VM,滿足用戶的即時需求。實現隨選所需
>3. 隔離與安全性:每個VM之間都是獨立且隔離的,即使其中一台虛擬機器遭受攻擊或故障,也不會影響到其他虛擬機器。
>4. 成本節省:由於能夠在單一實體機器上運行多個VM,所以能減少實體硬體的購置和維護成本。
>5. 快速deploy與遷移:VM可以輕鬆地從一台server移動到另一台,或從一個資料中心遷移到另一個資料中心。
>6. 開發和測試的便利性:開發人員可以在虛擬環境中快速地部署和測試應用,無需擔心對實體硬體或其他系統造成干擾。
---
Q:使用AWS EC2 建立一個instance原理?
A: 實際上是在使用Amazon的資料中心裡的一台實體server上的一個或多個VM。這些實體server配置有高效能的硬體,可以支持多個VM同時運行。
Amazon使用了先進的虛擬化技術來保證每個EC2實例都在隔離的環境中運行,並且提供了所承諾的資源 (如CPU, RAM等)。這使得使用者可以根據自己的需求選擇不同大小和類型的EC2實例,而不需要擔心底層的實體硬體細節。

### CPU、OS、網路虛擬化 比較表:
| 分類 | CPU虛擬化 | OS虛擬化 | 網路虛擬化 |
|--------|---------------------------------------------------------------|--------------------------------------------------------------------|---------------------------------------------------------------|
| 定義 | 使用Hypervisor技術使一個CPU看起來好像是多個獨立的CPU。 | 在單一硬體上模擬出一個或多個與底層硬體隔離的作業系統環境。 | 通過軟體將網絡資源虛擬化,從而創建虛擬的網絡環境。 |
| 實現技術 | 核心模式(Type-1 Hypervisor):像VMware ESXi、Microsoft Hyper-V和Xen這樣的虛擬機器監控器直接運行在硬件之上,它們提供了更高效的性能和更好的隔離性。用戶模式(Type-2 Hypervisor):像VMware Workstation、Oracle VirtualBox和Parallels Desktop這樣的虛擬機器監控器運行在宿主操作系統之上,它們通過宿主OS提供虛擬化支持。 | 容器技術(如Docker和Kubernetes)在Host操作系統的用戶空間中運行,並利用Host OS提供的隔離功能(如Linux的cgroups和namespaces)來實現容器的隔離。 | 依賴於軟體定義網絡(SDN)技術,如OpenFlow協議或更高級的網絡功能虛擬化(NFV)。 |
| 跨環境 | 可以跨硬體平台,將虛擬機從一台實體機器遷移到另一台,不同架構間可能需要轉換。 | 通常可以跨不同硬體和宿主作業系統,容器化可提供更大的移植性。 | 可以跨物理位置,連接分散的網絡資源到一個虛擬網絡中。 |
| 主要優勢 | 提高資源利用率,便於管理,增強安全性,並能夠在不同虛擬機之間隔離。 | 促進開發和部署的敏捷性,減少與底層硬體的依賴,易於快速擴展和縮減。 | 提高網絡的靈活性和自動化程度,簡化網絡管理,實現細粒度的網絡控制。 |
| 應用實例 | 伺服器的集中化管理,虛擬主機的租賃,企業的私有雲或混合雲架構。 | 雲服務的IaaS層,如AWS的EC2或Azure的VM,開發人員的本地測試環境。 | 雲服務提供者的網絡,如AWS的VPC,企業數據中心的網絡組態。 |
| 限制 | 對於虛擬化技術的支持程度依賴於CPU硬體功能,且在不同硬體平台間遷移可能有限制。 | 操作系統的選擇可能受限於Hypervisor的支持,容器在不同操作系統間移植時可能需要額外的工作。 | 網絡虛擬化的實施可能需要改造現有的網絡架構和購買
新的管理工具。 |
### IaaS提供商的運作模式
> 1. 購入大量的server和其他硬體資源(eg. 儲存系統、網路設備等),然後透過OS虛擬化技術在server上創建許多VM(模擬了一台完整的電腦,包括處理器、記憶體、儲存空間和網絡連接等資源)
> 2. 資源集群化:IaaS提供商首先將他們的物理硬體資源集群化,這樣可以更高效地管理和分配這些資源。
> 3. 安裝虛擬化層:在物理伺服器上安裝Hypervisor(如VMware ESXi、Microsoft Hyper-V等),這個軟體層允許在單一物理機器上運行多個獨立的虛擬機器。
> 4. 創建虛擬機器:透過Hypervisor,IaaS提供商可以創建多個虛擬機器,每個虛擬機器都運行自己的作業系統和應用程序。
> 5. 自動化與管理:使用管理和自動化工具(如OpenStack、VMware vRealize等),來自動化創建虛擬機器的過程,並允許用戶通過網絡接口(如Web控制面板或API)自助配置和管理他們的虛擬機器。
> 6. 租賃模式:用戶根據需要選擇虛擬機器的大小(CPU、記憶體、儲存等),並根據使用時間或資源使用量支付費用。這就是“即服務”的概念。
# Docker

>Docker engine是跑在實際的OS之上,使用 host OS(實際的OS)資源來運行container
>Docker engine與Host共享相同的kernel,但每個container都在自己獨立的執行環境中運行
>
>Docker 是一個容器平台,它可以用來創建、運行和管理容器。對於單一的容器或小型應用,可以直接在 Docker 上運行容器而不需要 Kubernetes。但對於需要高度擴展性和復雜管理的大型應用,Kubernetes 提供了更強大的工具和平台。
- Docker engine
>會提供給我們一個虛擬化的容器環境,是一個標準化的規範,所以所有東西都可以共用、通用。在一個Docker Engine的環境上面呢 我們可以部署多個Container
- Docker Container
>
>容器是用映像檔建立出來的執行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離、保證安全的平台。
>可以把容器看做是一個執行的應用程式加上執行它的簡易版 Linux 環境(包括 root 使用者權限、程式空間、使用者空間和網路空間等)。
>>建構在Docker engine之上,Container是一個虛擬空間,將會透過你的Docker Engine去看你的Host OS,去要求資源。如:索取CPU資源、記憶體資源等。
>
>另外要注意的是,Docker 映像檔是唯讀(read-only)的,而容器在啟動的時候會建立一層可以被修改的可寫層作為最上層,讓容器的功能可以再擴充。這點在下面的實例會有更多補充。
#### Container 優點:
> 1. VM 的image(映像檔) 通常落在數 GB 至數十 GB 都有,而container 的image 一般最大也才數百 MB。如此輕量級的特性,讓image 管理以及 App 的啟動、關閉流程皆方便迅速許多。
> 2. 容器的移轉性強:只要在實體伺服器上安裝了 Docker,無論Host os 為任何作業環境,皆能正常運行容器化後的應用程序。
> 3. 容器擁有不可變的特性,意指只要 App 能正常運作一次,未來不必擔心系統環境變動造成 App 出錯。
>
>4. 透過 Docker engine,容器的開發、管理與運行非常簡易,因此實踐Devops 的運作 (Development + Operation),解決以往常見開發與維運立場不一的問題。
>
>5. docker 不需要 Hypervisor 實現 host machine 虛擬化,因為運行在docker 容器上的 process 直接使用的都是 host resource。因此在CPU、cache 利用率上,container 會在效率上有優勢。
>6. docker 不需要 Guest os,而是利用host machine 的
OS/kernel。因此,當新建一個容器時,docker 不需要和 VM一樣安裝 Guest OS。 所以新建一個 container is more faster, that is a few seconds.
>7. 現代 OS是複雜的系統,VM的資源耗費比較大,因此,container 對比 VM 在資源消耗上佔有比較大的優勢。事實上,在一台物理機上我們可以很容易創建成千上百個 container 遠多於數個 VMs。
>8. container 快速啟動、低系統資源消耗的優點使 docker 在彈性雲平台和自動維運方面有很好的應用前景。
#### Container 缺點
>1. 資源隔離方面不如虛擬機,docker 是利用 cgroup 實現資源限制的,只能限制資源消耗的最大值,而不能隔絕其他進程佔用自己的資源。
>2. 安全性問題。docker 目前並不能分辦具體執行指令的用戶,只要一個用戶擁有執行 docker 的權限,那麼他就可以對docker 的容器進行所有操作,不管該容器是否是由該用戶創建。比如A 和 B都擁有執行 docker 的權限,由於docker 的 server 端並不會具體判斷 docker cline 是由哪個用戶發起的,(eg. A可以删除 B創建的容器),因此存在一定的安全風險。Docker Container 雖然會受到資源的隔離、控制,以及權限控制,但是由於跟 Linux 共用作業系統核心,進而會產生安全上的漏洞。
>3. docker 目前還在版本的快速更新中,細節功能調整比較大。一些核心模塊依賴於高版本内核,存在版本兼容問題。
>4. 容器不可變之特性,雖然非常有利於 App 的運行,但同時也意味著將無法隨意修改系統環境。如此一來,若維運人員需要升級或更動系統設置(System Configuration)時,則會遇到不少麻煩,通常也必須由開發人員協助深人改寫程序。反之,在使用 VM 的情況下,維運人員將能夠相對輕易地管理系統環境。
- Docker Image
> Docker image是一個模板,用來重複產生容器實體。
> 例如:一個映像檔裡可以包含一個完整的 MySQL 服務、一個 Golang 的編譯環境、或是一個 Ubuntu 作業系統。
>
>透過 Docker 映像檔,我們可以快速的產生可以執行應用程式的容器。而 Docker 映像檔可以透過撰寫由命令行構成的 Dockerfile 輕鬆建立,或甚至可以從公開的地方下載已經做好的映像檔來使用。
>
>舉例來說,如果我今天想要一個 node.js 的執行環境跑我寫好的程式,我可以直接到上 DockerHub 找到相對應的 node.js 映像檔 ,而不需要自己想辦法打包一個執行環境。
- 倉庫 Repository
>是集中存放映像檔檔案的場所,也可以想像成存放蛋糕模具的大本營。倉庫註冊伺服器(Registry)上則存放著多個倉庫。
>最大的公開倉庫註冊伺服器是上面提到過的 Docker Hub,存放了數量龐大的映像檔供使用者下載,我們可以輕鬆在上面找到各式各樣現成實用的映像檔。
- Docker Compose
>Docker Compose 是一個工具,用於定義和運行多容器 Docker 應用程序。使用 docker-compose.yml 文件來配置應用服務,然後使用 docker-compose up 命令來啟動所有的服務。
>>用途:方便地在單一主機上定義和運行多容器的 Docker 應用程序。
- Dockerfile
>文本文件,包含了用來構建 Docker 映像檔的所有命令。
>>用途:自動化映像檔的構建過程。
- .yml(或 .yaml)
>是一種文件類型。當你打開它時,它看起來就像一個簡單的文字檔,但它的組織方式很有特色。是一種數據序列化語言,主要用於配置文件、數據交換和保存設定或其他資料
>[特點]:
>1. YAML是設計來讓人容易閱讀和編寫的,也可以被電腦程序解析和生成
>2. 簡潔性:YAML提供一種更加簡潔和清晰的方式來表示數據,特別是與XML和JSON相比。
可讀性:YAML的可讀性對於設定文件和數據交換格式尤為重要。
通用性:可以用於多種程式語言和工具之間的數據交換。
3. 可以幹嘛?
>a. 設定文件:許多軟件和工具使用YAML作為其設定文件的格式,例如Docker Compose、Ansible、Kubernetes等。
b. 數據交換:YAML可以用作JSON的替代品,用於數據交換。
c. 資料描述:YAML可以描述數據的結構和關聯,例如在OpenAPI(之前稱為Swagger)中描述RESTful API。
d. 模板:某些工具使用YAML來定義模板,例如在AWS CloudFormation中描述資源堆疊。
-------
## Docker Containers vs Virtual Machines

Docker 與傳統的完全虛擬化技術之間的比較:


> The major difference between a Container and a VM is that in VMs a hypervisor is used to virtualize physical hardware. Each VM contains a guest OS, a virtual copy of the hardware that the OS requires to run, while in Containers instead of virtualizing the underlying hardware, they virtualize the operating system so each container contains only the application and its libraries.
>
> 容器和 VM 之間的主要區別在於,在 VM 中,虛擬機管理程式用於虛擬化物理硬體。每個 VM 都包含一個來賓作業系統,即作業系統運行所需的硬體的虛擬副本,而在容器中,它們不是虛擬化底層硬體,而是虛擬化操作系統,因此每個容器僅包含應用程式及其庫。
> 1) Operating System: Virtual machine has its guest OS above the host OS, which makes virtual machines heavy. While in Docker, multiple containers share the host OS, and that is why they are lightweight.
>
> 1)操作系統:虛擬機的客戶機操作系統高於主機操作系統,這使得虛擬機很重。在 Docker 中,多個容器共用主機操作系統,這就是它們輕量級的原因。
> 2) Security: Virtual Machine does not share OS, and there is strong isolation in the host kernel. Hence, they are more secure as compared to containers. Docker has a lot of security risks and vulnerabilities because containers share the host kernel.
>
> 2)安全性:虛擬機不共用操作系統,主機內核存在強隔離性。因此,與容器相比,它們更安全。Docker 存在很多安全風險和漏洞,因為容器共用主機內核。
> 3) Performance: Containers are lightweight and consume fewer resources while VM is heavy and consumes more resources, so containers give better performance than VM.
>
> 3)性能:容器是輕量級的,消耗的資源更少,而虛擬機很重,消耗的資源更多,因此容器的性能比虛擬機更好。
> 4) Portability: Containers are easily portable because they do not have separate operating systems. While virtual machines have separate OS, so porting a virtual machine is very difficult.
>
> 4)可移植性:容器易於移植,因為它們沒有單獨的操作系統。雖然虛擬機具有單獨的操作系統,但移植虛擬機非常困難。
| 特點/屬性 | Docker 容器 | 完全虛擬化 (如 VM) |
|-----------------------------------|------------------------------|---------------------------------|
| **基於的技術** | 初始使用 LXC,後來切換至 runC | 例如:Xen, VMware, Hyper-V(在Microsoft上建VM的功能) |
| **文件系統** | 使用分層文件系統 (如 AuFS) | 使用完整的操作系統映像檔 |
| **啟動時間** | 幾秒內,有時不到一秒 | 通常需要幾分鐘 |
| **資源共享** | 與Host OS分享資源 | 獲得自己的資源集,最少共享 |
| **隔離性** | 較少隔離 | 提供更完整的隔離 |
| **資源需求** | 輕量,需要較少資源 | 較重,需要較多資源 |
| **映像檔大小** | 通常較小,由於分層存儲 | 較大,因為包含整個操作系統 |
| **部署一致性** | 使用映像檔,確保一致性 | 可能會受到宿主差異的影響 |
| **對操作系統的"快照"** | 使用分層系統,只保存差異 | 通常需要完整映像檔 |
VM、Docker比較:
https://k21academy.com/docker-kubernetes/docker-vs-virtual-machine/
| | Container 容器 | Virtual Machines (VMs) 虛擬機器 (VM) |
| --- | --- | --- |
| Boot-Time 啟動時間 | Boots in a few seconds.幾秒鐘後啟動。 | It takes a few minutes for VMs to boot.VM 啟動需要幾分鐘時間。 |
| Runs on 運行於 | Dockers make use of the execution engine.Dockers 使用執行引擎。 | VMs make use of the hypervisor.VM 使用虛擬機監控程式。 |
| Memory Efficiency 記憶體效率 | No space is needed to virtualize, hence less memory. 虛擬化不需要空間,因此記憶體更少。 | Requires entire OS to be loaded before starting the surface, so less efficient. 需要在啟動圖面之前載入整個操作系統,因此效率較低。 |
| Isolation 隔離 | Prone to adversities as no provisions for isolation systems.由於沒有隔離系統的規定,容易遇到逆境。 | Interference possibility is minimum because of the efficient isolation mechanism.由於具有高效的隔離機制,干擾的可能性很小。 |
| Deployment 部署 | Deploying is easy as only a single image, containerized can be used across all platforms. 部署很容易,因為只有一個容器化的映射可以跨所有平臺使用。 | Deployment is comparatively lengthy as separate instances are responsible for execution.部署時間相對較長,因為單獨的實例負責執行。 |
| Performance 性能 | Limited performance 性能有限 | Native performance 原生性能 |
***Note:*** Check this blog on **[Azure Kubernetes Service](https://k21academy.com/microsoft-azure/az-104/video-containers-docker-kubernetes-in-azure-for-beginners/)** to know more in detail.
### 從安全性的角度來看,虛擬機器(VM)通常被認為比容器更安全。原因:
1. **更強的隔離性**:虛擬機器提供了硬件級別的隔離,每個虛擬機器都有自己獨立的操作系統。這種隔離層次比容器更深,後者共享宿主機的操作系統核心。
2. **攻擊面更小**:因為容器共享宿主機的核心,如果宿主機的核心受到攻擊,則所有的容器都可能受到影響。相比之下,即使一個虛擬機器受到攻擊,也不太可能影響到其他虛擬機器。
3. **成熟的技術**:虛擬機器技術比容器技術更加成熟,有較長時間的安全實踐和審計歷史,因此有更多的工具和最佳實踐可供遵循。
> 然而,這並不意味著容器本質上不安全,只是它們需要不同的安全考慮和措施。例如,運用容器管理和隔離工具(如Kubernetes)、網絡策略、強化容器映像和運行時安全可以顯著提高容器環境的安全性。
### Kubernetes(k8s)
> 是一個容器編排系統,它用於管理大量的容器化應用。提供一個分散式的平台來自動部署、擴展和運行應用程序容器,可以在不同的物理和虛擬機器上運行跨主機的容器化應用程序。當應用程式需要在多個容器中運行,或者需要在多個伺服器之間擴展和管理這些容器時,Kubernetes 就非常有用。它提供了自動部署、擴展、負載均衡和自我修復等功能。

https://k21academy.com/docker-kubernetes/kubernetes-architecture-components-overview-for-beginners/
參考資料:
1. NTHU 周志遠OS授課
2. 洪逸 OS授課
3. https://www.cherryservers.com/blog/a-complete-overview-of-docker-architecture
4. https://chengweihu.com/docker-tutorial/
5. https://stackoverflow.com/questions/16047306/how-is-docker-different-from-a-virtual-machine#
6. https://blog.cloud-ace.tw/application-modernization/devops/docker-k8s-gke-intro/ (好文 K8S 介紹 之後要搞懂!!)
7. https://k21academy.com/docker-kubernetes/docker-vs-virtual-machine/