---
# System prepended metadata

title: OpenStack

---

# OpenStack
[TOC]
## OpenStack 是什麼
* 雲端運算軟體
* 提供建置或管理 IaaS 服務的開放原始碼平台
* 可以建立和管理虛擬機
* 使用者可以透過 Openstack 做到像 Amazon , Google GCP 提供的 IaaS 服務
* 由多個服務組成，使用者可以組合多個服務來達到需求
* 服務透過 REST API 提供
::: info
[RESTful API](https://medium.com/itsems-frontend/api-%E6%98%AF%E4%BB%80%E9%BA%BC-restful-api-%E5%8F%88%E6%98%AF%E4%BB%80%E9%BA%BC-a001a85ab638)
* REST (Representational State Transfer)，一種 API 設計規範
* 以 REST 為規範的 API 就稱為 RESTful API
* 一般 API : 設計方法因人而異
    ```
    取得資料 GET    /getData
    新增資料 POST   /createData
    刪除資料 DELETE /deleteData/1
    ```
* RESTful API : 用一個唯一的 URL 定位資源，將動作藏在 HTTP 的 method 裡
    ```
    獲得資料 GET /data
    新增資料 POST /data
    刪除資料 DELETE /data/1
    ```
* 特點
    * 有唯一的 URL 表示資源位置
    * 無狀態，以登入系統為例：
        * 有狀態
            * Client 端登入時 Server 端儲存 Session（使用者登入資訊），Client 端再次請求時，Server 端會依照 Session 做出不同回應
            * Server 端儲存 session 會增加工作量
        * 無狀態
            * Client 端自行保存狀態，在請求 Server 端時，一起傳給 Server
            * Server 端不保存 Client 端的狀態資訊
            * 登入時 Server 產生紀錄登錄狀態的 token 還給 Client，Client 再次發送請求時，會把 token 一起傳給 Server，Server 就能知道 Client 的狀態
:::
## 架構
![](https://i.imgur.com/0KqUnQE.png)
> [來源](https://www.openstack.org/software/)
> 圖中粗體字的部分為核心功能
### 核心功能
* Nova : 運算服務 (Compute Service)
* Keystone : 身分服務 (Identity Service)
* Neutron : 網路服務 (Networking)
* Cinder : 區塊儲存服務 (Block Storage)
* Swift : 物件儲存服務 (Object Storage)
* Glance : 映像檔服務 (Image Service)
* Ironic : 裸機部署服務 (Baremetal Provisioning Service)
* Horizon : 儀錶板 (Dashboard)
* Heat : 編排服務 (Orchestration)
### 服務之間如何串聯
![](https://i.imgur.com/bgrOZkd.png)
> [來源](https://www.researchgate.net/figure/Virtual-machine-spawning-sequence-in-OpenStack_fig3_346347453)
### Nova (運算服務)
* 功用 : 建立和管理虛擬機
* 基本功能需要搭配其他服務使用 : 
    * Keystone 身分服務
    * Glance 映像檔服務
    * Neutron 網路服務
    * Cinder 區塊儲存服務
    * Placement : 從 Nova 中拆分出來的服務，主要功能是追蹤不同類別的可用資源和使用量，例如：CPU , RAM...
* 架構 :
    ![](https://i.imgur.com/9Pqc6xg.png)
    > [來源](https://zhiliao.h3c.com/Theme/details/77423)
    * nova-api : 接收外部請求
        * Nova 對外的接口
        * 其他服務只能透過 nova-api 使用 nova 的服務 (比如用 Dashboard 請求 nova 創建一個虛擬機)
        * 透過 nova-api 傳送進來的請求會進入 message queue 中，再傳遞給 Nova 的其他服務 (nova-scheduler , nova-compute...)
    * [nova-scheduler](https://docs.openstack.org/nova/latest/admin/scheduling.html) : 根據資源使用狀況，決定哪個節點來生成虛擬機
        * 創建虛擬機時，會透過 Filtering 和 Weighting 來決定哪個節點來創建
        * Filtering : 有許多 filter，以此篩選出符合的節點
            ![](https://i.imgur.com/735DTVU.png)
            > [來源](https://docs.openstack.org/nova/latest/admin/scheduling.html)
            * ComputeCapabilitiesFilter : 以運算能力來過濾，比如
                * free_ram_mb (compared with a number, values like >= 4096)
                * num_instances (compared with a number, values like <= 10)
            * ComputeFilter : 過濾出開啟且可用的節點
                * 基本上是一直開啟的
        * Weighting : 依照目前資源的使用率，計算出各節點的 weight，然後進行排序，決定出最適合節點
            ![](https://i.imgur.com/hSpT5tI.png)
            > [來源](https://docs.openstack.org/nova/latest/admin/scheduling.html)
            * 公式 : `weight = w1_multiplier * norm(w1) + w2_multiplier * norm(w2) + ...`
            * multiplier : 權重，權重器之間的優先級，越大在公式計算中佔的比例就越大，也就代表該權重器較優先，可以是負數
            * norm : 權重器，比如 DiskWeigher 是以節點可用磁碟空間來計算
            * 根據計算結果做排序，越大就代表越適合
    * nova-compute : 建立虛擬機

        ![](https://i.imgur.com/wSPxk2K.png)
        > [來源](https://www.xjimmy.com/openstack-5min-28.html)
        * nova-compute 不是直接操作 Hypervisor
        * 而是透過 LibVirt 或 Hypervisor 的 API 來使用各種 Hypervisor 建立虛擬機
        * LibVirt : 統一的應用程式介面，讓不同種類 Hypervisor 可以連接
    * nova-conductor : 根據請求讀取資料庫
        ![](https://i.imgur.com/vx1I3wg.png)
        > [來源](https://docs.openstack.org/security-guide/databases/database-access-control.html)
        * 介於 nova-compute 與資料庫中間的間接程式，主要是避免 nova-compute 直接接觸資料庫，增加系統的安全性
        * 因為 nova-compute 是負責管理租戶虛擬機，最不受信任
        * 也可以避免大量系統存取資料庫的資料
* nova 流程圖
    ![](https://i.imgur.com/g0SwJyL.png)
    > [來源](https://www.cnblogs.com/ajunyu/p/11111468.html)
    1. 使用者或其他服務透過 nova-api 發送建立虛擬機請求
    2. 該請求被放到 message queue
    3. nova-scheduler 接收到請求後找出最適合的建立節點
    4. 把在該節點建立虛擬機的訊息放到 message queue
    5. nova-compute 接收到訊息後，透過 nova-conductor 從資料庫取得虛擬機資訊，並開始建立虛擬機
* message queue
    * 使用 AMQP 協定傳送 Nova 內部元件間傳遞的 RPC 訊息
    ::: info
    [RPC](https://ithelp.ithome.com.tw/articles/10223580) (Remote Procedure Call)
    * 一種電腦通訊協定
    * 使用者可以透過網路遠端呼叫其他電腦上的 function，就像是在呼叫本地的 function
    * Openstack 中的服務內部都是利用 RPC 互相通訊
    :::
    * [AMQP](https://zh.wikipedia.org/zh-tw/%E9%AB%98%E7%BA%A7%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E5%8D%8F%E8%AE%AE) (Advanced Message Queuing Protocol)
        * OpenStack 服務的內部元件之間的 RPC 訊息所使用的協定
        * 目的是對訊息的排序、路由、保持可靠性和安全性
        * 可以非同步處理訊息，不用等待一些費時操作的回應
        * AMQP 預設是用 RabbitMQ 實現，其他有 QPid , ZeroMQ
    * AMQP 架構圖
        ![](https://i.imgur.com/WSOCwKA.png)
        > [來源](https://www.jianshu.com/p/da331ecc9ae8)
        * Publisher : 訊息發送者
        * Consumer : 訊息接收者
        * Broker : 處理訊息的 Server，比如 RabbitMQ
        * vhost : 一群 Exchange , Queue 和其他元件的集合，Broker 裡可以有多個 vhost，vhost 彼此之間互相獨立
        * Queue : 存放訊息的佇列
        * Exchange : 交換器，從 Publisher 接受訊息，根據 Routing key 和 Binding 把訊息傳送到對應的 Queue
            * Routing key : Exchange 用 Routing key 來判斷要傳送到哪個 Queue
            * Binding : Exchange 和 Queue 之間的綁定配置
            * Exchange 有四種交換機制
                * fanout : 廣播，會無視 Routing key 從 Exchange 分配訊息到 Binding 的所有 Queue
                * direct : 精確匹配，Routing key 要和 Binding 配置匹配才會傳送
                * topic : 模糊匹配，Routing key 和 Binding 中有`*`和`＃`兩種符號，`*`代表任一單詞，`#`代表零個或多個任一單詞，只要匹配就會傳送
                * header (不常用) : 不使用 Routing key，根據訊息和 Binding 的 header 內容決定傳到哪個 Queue。header 中的 x-match 是匹配模式，any 只要符合一項就能匹配，all 需要全部都符合才能匹配
                ![](https://i.imgur.com/bP83zy3.png)
                > [來源](https://medium.com/h1dra-security-team/%E7%89%A9%E8%81%AF%E7%B6%B2%E5%8D%94%E5%AE%9A%E8%88%87%E8%B3%87%E5%AE%89%E7%9A%84%E8%B7%9D%E9%9B%A2-amqp-%E9%80%9A%E8%A8%8A%E5%8D%94%E5%AE%9A%E6%B7%BA%E8%AB%87-3c914a528773)
                * [可以模擬 RabbitMQ 的網站](http://tryrabbitmq.com)
        * AMQP 傳送訊息流程 : 
            1.  Publisher 發送訊息給 Broker
            2.  Broker 中 Exchange 根據訊息的 Routing key 和 Binding 配置傳送給 Queue
            3. Queue 收到訊息後，如果有 Consumer 連接到這個 Queue，Consumer 就會收到訊息。否則 Queue 會儲存訊息直到有 Consumer 連接
    * Openstack 中 RPC 分成兩種發送訊息的方法，兩者的差別在於一個有回應一個沒有
        * rpc.call
            ![](https://i.imgur.com/8SP10SH.png)
            > [來源](https://docs.openstack.org/nova/latest/reference/rpc.html)
            * Invoker 端的 Topic Publisher 是訊息發送者，Worker 端是接收者
            * Worker 端接收訊息後作為 Direct Publisher 回傳回應給 Invoker
            * 流程 : 
                1. Invoker 端 Topic Publisher 發送訊息給 Broker (RabbitMQ)
                2. Exchange 根據 Routing key 和 Binding 傳送訊息給對應的 Queue (交換機制可以是 topic , fanout , direct)
                3. Worker 端連接該 Queue 的 Consumer 接收到訊息
                4. 處理訊息後，Worker 端會作為 Direct Publisher 回傳回應給 Invoker 端
                5. 該回應的交換機制會是 direct，只傳給一開始的訊息發送者
                6. Invoker 端的 Direct Consumer 接收到回應
        * rpc.cast
            ![](https://i.imgur.com/UTDflii.png)
            > [來源](https://docs.openstack.org/nova/latest/reference/rpc.html)
            * Invoker 端的 Topic Publisher 是訊息發送者，Worker 端是接收者
            * Worker 端接收訊息後不會發送回應
            * 流程 : 
                1. Invoker 端 Topic Publisher 發送訊息給 Broker (RabbitMQ)
                2. Exchange 根據 Routing key 和 Binding 傳送訊息給對應的 Queue (交換機制可以是 topic , fanout , direct)
                3. Worker 端連接該 Queue 的 Consumer 接收到訊息 
* reference :
    * https://docs.openstack.org/nova/latest/admin/scheduling.html
    * https://docs.openstack.org/security-guide/databases/database-access-control.html
    * https://ithelp.ithome.com.tw/articles/10260919
    * http://blueskyfreeway2.blogspot.com/2019/05/openstack.html
    * https://www.cnblogs.com/ajunyu/p/11111468.html
    * https://www.cnblogs.com/mh20131118/p/12939358.html
    * https://blog.51cto.com/u_14557673/2476104
    * https://docs.openstack.org/nova/latest/reference/rpc.html
    * https://blog.csdn.net/songfeihu0810232/article/details/73321828
    * https://www.jianshu.com/p/da331ecc9ae8
    * https://blog.csdn.net/juvxiao/article/details/23016155
### Keystone (身分服務)
* 功用 : 
    * 使用者 (User) 管理 ： 驗證使用者使用 Openstack
    * 服務 (Service) 管理 ： 在使用者或服務要使用某服務時，會先向 Keystone 進行認證，通過認證才可以使用該服務
    * 記錄所有 OpenStack API 的所在位置 (Endpoint)


* 架構：
    ![](https://i.imgur.com/0Z3CJLt.png)
    > [來源](https://www.oreilly.com/library/view/identity-authentication-and/9781491941249/ch01.html)
    * Identity : 提供使用者和群組 credential 的驗證服務
        * 使用者 (User)  : 人或 Openstack 的服務
        * 群組 (Group) : 使用者的集合，方便指派 Role
        * credential : 第一次驗證時要用的憑證，比如 username and password 或 API key
        * Authentication : Openstack 驗證 credential 的過程
    * Resource : 提供有關 Project 和 Domain 的資料
        ![](https://i.imgur.com/6PWYQHh.png)
        * Project (Tenant) : 
            * OpenStack 中所有權的基本單位
            * OpenStack 中的所有資源都由特定 Project 擁有
        * Domain :
            * Project , User , Group 的上層容器
            * 每個 Project , User , Group 都由一個 Domain 擁有
            * Keystone 提供了一個預設 Domain，就叫做 Default
            
    * Assignment : 提供 Role 和 Role Assignments 的資料，以做到 OpenStack 的 RBAC 策略
        ::: info
        [RBAC](https://docs.openstack.org/patrole/latest/rbac-overview.html) (Role Based Access Control)
        * 用 Role (角色) 來做訪問控制
        * 符合權限的 Role 才能做出對應的動作
        :::
        * Role :
            *  Role 決定了使用者或群組可以獲得的權限
            *  可以在 Domain 或 Project 授予 Role 給使用者或群組
        * Role Assignments :
            * 具有 Role , Resource , Identity 的 tuple
            * 記錄 Role 跟 Resource 的關係
    * Token : 管理跟驗證 token
        * 使用者經過 credential 驗證後會發給使用者一個 token，之後對服務的存取會透過 token 來做驗證，目的是要增加安全性
        * 因為如果使用者每次使用服務時都出示 user name 和 password 可能會有安全問題
    * Catalog : 記錄了 OpenStack 服務的所在位置 (Endpoint)
        * Endpoint : 一個 URL，user 在認證成功後會取得可以訪問的端點位置，每個服務都有三種類型的 Endpoint
            * Admin : Admin user 才能訪問
            * Public : 可以跨 Region 訪問
            * Internal : 只有 Region 內的 user 可以訪問
        *  `microstack.openstack catalog list` 可以看到所有服務的 Endpoint
        ![](https://i.imgur.com/glPmKox.png)
    * Policy : 用來管理訪問權限，定義什麼角色有什麼權限
* 使用者請求 Nova 建立虛擬機的 Keystone 流程圖
    ![](https://i.imgur.com/xWqZP7Y.png)
    > [來源](https://www.cnblogs.com/yuki-lau/archive/2013/01/04/2843918.html)
* 以辦理入住飯店為例 :
    1. 進飯店時，要先到櫃台 （Keystone） 登記 (Authentication)，我要拿出我的身分證 (credential) 證明是我本人。櫃台確認是我本人之後就會給我房卡 (token)
    2. 房卡有分普通、會員、白金卡 (role)，不同的卡待遇自然不同
    3. 櫃台會給你導覽圖 (Catalog) 讓你知道有哪些房間和設施 (Service)，可以走什麼路線 (Endpoint) 去
    4. 有不同路線可以到這些地方，比如走後門 (admin)、內部員工通道 (internal)、客人通道 (public)
    5. 找到設施要使用之前，要先檢查你的卡能不能用這個設施，所以跟櫃台（Keystone）確認你可不可以用，確定可以才讓你使用
* reference :
    * https://docs.openstack.org/keystone/pike/getting-started/architecture.html
    * https://ithelp.ithome.com.tw/articles/10261708
    * https://www.cnblogs.com/itzhao/p/11333478.html
    * http://blueskyfreeway2.blogspot.com/2019/05/openstack.html
### Neutron (網路服務)
* 功用 : 提供網路虛擬化的服務，讓虛擬機可以上網
* 主要提供以下服務 :
    * 交換器：提供同一網段的虛擬機 L2（資料連結層）的連通性
    * 路由器：提供 L3（網路層）網路功能，SNAT , DNAT...
    * 防火牆：提供基本防火牆，port blocking... 
* 架構
    ![](https://i.imgur.com/fu3rqMs.png)
    > [來源](https://www.oreilly.com/library/view/learning-openstack-networking/9781788392495/b2f8b25a-d590-4313-8d11-2a3f5f16d470.xhtml)
    * neutron-server : 接受外部請求並傳給對應的 neutron-plugin 處理
    * neutron-plugin : 決定網路如何建置，把建置請求傳給 neutron-agent，把網路資訊存到資料庫
        * plugin 有對應的 agent，使用什麼 plugin 就要使用什麼 agent
        * 分成 Core plugin 和 Service plugin
            * Core plugin 管理 network , subnet , port 等服務
            * Service plugin 管理 router , 防火牆等服務
        * 常見的 plugin 有 OVS , Linux Bridge , OVN
        ::: info
        [ML2 plugin](https://blog.csdn.net/zouyh/article/details/122653963) (Module Layer2 plugin)
        * 傳統的 Core plugin 只能使用對應的 agent
        * 網路環境只能使用一個 Core plugin 建置
        * 使用 ML2 可以同時使用多個 agent
        ![](https://i.imgur.com/1EgsqYZ.png)
        > [來源](https://blog.csdn.net/zouyh/article/details/122653963)
    * neutron-agent : 建置網路
        * 常見的 agent 有 L3 , DHCP , plugin-agent
        * plugin-agent 是指某個 plugin 對應的 agent
        * L3 和 DHCP agent 沒有對應的 plugin ，任何 plugin 都能使用
    * SDN Service (Software-Defined Networking Service) : 提供額外的網路服務
        * Neutron 如果要包含所有網路服務功能的話需要寫一堆 agent 跟 driver，功能上會變很複雜，所以一些網路服務可以直接使用現成的 SDN 服務
    * Message Queue : neutron 內部元件之間傳遞訊息的方式
    * 資料庫 : 儲存網路狀態和資訊
* 流程圖 :
    ![](https://i.imgur.com/tHxsLJh.png)
    > [來源](https://blog.csdn.net/zhengmx100/article/details/54743624)
    * 外部發送請求給 neutron-server
    * neutron-server 把請求傳給 neutron-plugin
    * neutron-plugin 把網路資訊存到資料庫，並把請求傳給 neutron-agent 和 SDN
    * neutron-agent 和 SDN 建立網路服務
* 提供兩種網路類型 Provider Networks 和 Self-Service Networks
* 預設情況下 project 網路之間是隔離的，Openstack 支援幾個隔離和 overlay network 技術
    * Flat
        * 所有 instance 都在同一個 L2 網路上，沒有 VLAN tagging 隔離網路
    * VLAN
        * 用戶可以使用 VLAN ID（802.1Q tagging）創建多個 provider 或 project networks
        * 同一 VLAN 的 instance 可以互相通訊
        * 不同 VLAN 則要透過 router 轉發
        ::: info
        [IEEE 802.1Q 規範](https://zh.wikipedia.org/wiki/IEEE_802.1Q)
        ![](https://i.imgur.com/dmdDxRA.png)
        > [來源](https://support.huawei.com/enterprise/en/doc/EDOC1100088104)
        * 會在 Ethernet Frame 中加入 VLAN tag
        * TPID : 識別是否為 802.1Q 封包，0x8100 代表是
        * PRI : 用 0~7 的數字來指定優先權，數字越大優先權越高。如果發生壅塞，優先權越高的封包越先被發送
        * CFI : 0 表示 MAC 位址以標準格式封裝，1 則相反
        * VID : 用來區別不同 VLAN，0 和 4095 為保留，可用 VLAN 數有 4094 個
        :::
    * GRE, VXLAN, GENEVE
        * 都是封裝協定 (encapsulation protocols)
        * 透過創建 overlay 網路來控制不同 instance 之間的通訊
        * Neutron 需要一個虛擬路由器讓 project 網路中的 instance 能夠對外通訊
        ![](https://i.imgur.com/gQAdiwf.png)
        > [來源](https://docs.openstack.org/neutron/rocky/admin/intro-os-networking.html)
        ::: info
        [VXLAN (Virtual Extensible LAN)](https://chunchaichang.blogspot.com/2019/03/vxlan-vs-vlan.html)
        
        ![](https://i.imgur.com/DqVgGUU.png)
        > [來源](https://chunchaichang.blogspot.com/2019/03/vxlan-vs-vlan.html)
        * 將 Ethernet Frame 封裝在 UDP 封包裡面
        * VXLAN header 中有 24 bit 的 VNID 用來區別不同 L2 網路，總共可以標識一千多萬個 L2 網路
        * VXLAN 與 VLAN 對比 : 
            * 解決 VLAN 提供網路數量不足，可提供的網路數量比 VLAN 多非常多
            * 解決 switch MAC 地址表不夠問題。VLAN 是藉由 MAC 地址表紀錄 MAC 位址對應的 VLAN，如果地址表滿了，新的 MAC 位址就無法紀錄
        * 架構 : 
            ![](https://i.imgur.com/4NFxmwV.png)
            > [來源](https://support.huawei.com/enterprise/en/doc/EDOC1100086966)
            * VNI : 用來區別不同 VXLAN
            * VTEP (VXLAN Tunnel Endpoint) : 可以是實體或虛擬 switch，負責將封包封裝在 UDP 封包裡，然後透過 tunnel 傳遞給目標 VTEP
            * tunnel : VTEP 之間傳遞的虛擬隧道，表面上 VTEP 好像是直接通信，但實際上需要其他實體設備轉發
        :::
    * Provider Networks :
        * Provider Networks 的內部元件 :
            ![](https://i.imgur.com/EzbeT8N.png)
            > [來源](https://docs.openstack.org/install-guide/overview.html#networking)
        * 處理虛擬機 L2 的網路連接
        * 將虛擬機橋接到實體網路的 switch，使用實體網路 L3 的服務
        * 只有管理員才能創建或更新，因為設定要跟實體的網路基礎設施吻合，而一般使用者通常不會有這些資訊 
        * 使用 VLAN (802.1q) tagging 來識別和隔離網路
        * Linux Bridge with Provider Networks
            * 可以是一個 untagged (flat) network 或多個  tagged (VLAN) networks
            * 架構 :
                ![](https://i.imgur.com/DAmFeKo.png)
                > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-provider.html)
                * 上圖是多個 Provider Networks 情境下的架構
                * 每一個 Provider Networks 會在 Compute Node 上對應到一個 Linux Bridge，並用 VLAN 隔離
                * 虛擬機的網卡會接到對應的 Linux Bridge
            * 封包流通方式 : 
                * 南北向 (封包從虛擬機送往外網)
                    ![](https://i.imgur.com/BEEgCPE.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-provider.html)
                    1. 從 compute node 發送出去 :
                        * 虛擬機的網卡 (1) 透過 veth 將封包送往 Provider Bridge 上的 instance port (2)
                        * 在 Provider Bridge 上 iptables (3) 會處理防火牆功能
                        * Provider Bridge 上的 VLAN sub-interface port (4) 會將封包送往實體網卡 (5)
                        * 實體網卡將封包加上 VLAN tag 並送往實體 switch (6)
                    2. 後續由實體網路設施處理 :
                        * switch 拿掉封包上的 VLAN tag 然後轉送封包給 router (7)
                        * router 把封包從 provider network (8) 路由到外網 (9)，然後轉送封包給 switch (10)
                        * switch 轉送封包到外網(11)
                        * 外網 (12) 接收到封包
                
                * 東西向 1 (封包從虛擬機送往同網路下的虛擬機)
                    ![](https://i.imgur.com/nPFVB4Q.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-provider.html)
                    1. 從 compute node 1 發送出去 :
                        * instance 1 的網卡 (1) 透過 veth 將封包送往 Provider Bridge 上的 instance port (2)
                        * 在 Provider Bridge 上 iptables (3) 會處理防火牆功能
                        * Provider Bridge 上的 VLAN sub-interface port (4) 會將封包送往實體網卡 (5)
                        * 實體網卡將封包加上 VLAN tag 並送往實體 switch (6)
                    2. 實體網路設施中 :
                        * switch 把封包從 compute node 1 送往 compute node 2
                    * 傳給 compute node 2 後 : 
                        * 實體網卡 (8) 將 VLAN tag 101 拿掉並送往 Provider Bridge 上的 VLAN sub-interface port (9)
                        * 在 Provider Bridge 上 iptables (10) 會處理防火牆功能
                        * Provider Bridge 上的 instance port (11) 透過 veth 將封包送往 instance 2 的網卡 (12)
                
                *  東西向 2 (封包從虛擬機送往不同網路下的虛擬機)
                    ![](https://i.imgur.com/lKYsYKy.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-provider.html)
                    1. 從 instance 1 發送出去：
                        * instance 1 的網卡 (1) 透過 veth 將封包送往 Provider Bridge 的 instance port (2)
                        * 在 Provider Bridge 上 iptables (3) 會處理防火牆功能
                        * Provider Bridge 上的 VLAN sub-interface port (4) 會將封包送往實體網卡 (5)
                        * 實體網卡將封包加上 VLAN tag 101 並送往實體 switch (6)
                    2. 在實際網路設施中：
                        * switch 將封包 VLAN tag 101 拿掉並送往 router (7)
                        * router 將封包從 provider network 1 (8) 路由到 provider network 2 (9)
                        * router 將封包送往 switch (10)
                        * switch 將封包加上 VLAN tag 102 (11) 並送往 compute node 1
                    3. 回到 compute node 1 上：
                        * 實體網卡 (12) 將 VLAN tag 102 拿掉並送往 Provider Bridge 上的 VLAN sub-interface port (13)
                        * 在 Provider Bridge 上 iptables (14) 會處理防火牆功能
                        * Provider Bridge 上的 instance port (15) 透過 veth 將封包送往 instance 2 的網卡 (16)
                
    * Self-Service Networks :
        * Self-Service Networks 的內部元件
            ![](https://i.imgur.com/SIXDPIm.png)
            > [來源](https://blog.csdn.net/zhongbeida_xue/article/details/103729661)
        * 可以讓使用者不用透過管理員去管理自己的網路
        * 網路是完全虛擬的，需要虛擬路由器路由到供應商提供的外部網路
        * 使用 VXLAN、GRE 或 GENEVE 建立 overlay 網路
        * Linux Bridge with Self-Serivce Networks :
            * 架構 :
                ![](https://i.imgur.com/bhEz704.png)
                > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html)
                * 上圖是一個 Self-Service Networks 和一個 untagged Provider Networks 組成的架構，以 VXLAN 建立 overlay network
            * 封包流通方式 :
                * 南北向 1 (固定 IP 的虛擬機將封包送往外網)
                    ![](https://i.imgur.com/smFvmy2.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html)
                    1. 從 compute node 發送出去 : 
                        * 虛擬機的網卡 (1) 透過 veth 將封包送往 Self-Service Bridge 的 instance port (2)
                        * 在 Self-Service Bridge 上 iptables (3) 會處理防火牆功能
                        * Self-Service Bridge 轉發封包到 VXLAN interface (4) 並將封包包入 VNI 101
                        * VXLAN interface 對應的實體網卡 (5) 透過 overlay 網路 (6) 將封包送往 network node
                    2. network node 接收封包之後
                        * 實體網卡 (7) 將封包送往對應的 VXLAN interface (8) 並且解開 VXLAN 封包
                        * Self-Service Bridge 上的 router port (9) 將封包送往 Self-Service router namespace 內的 Self-Service network interface (10)
                            * 在 IPv4 的狀況下，router 會用 SNAT 將 source IP 改成 router 的 IP 之後將封包透過 Provider Network 上的 gateway 介面 (11) 送往 gateway
                            * 在 IPv6 的狀況下，router 會將封包送往 next-hop IP 地址，通常就是 Provider network gateway 的 IP 位址，所以也一樣是會透過 Provider Network 上的 gateway 介面 (11) 送往 gateway
                        * router 將封包送往 Provider Bridge 上的 router port (12)
                        * Provider Bridge 上的 VLAN sub-interface port (13) 會將封包送往 Provider 實體網卡 (14)
                        * Provider 實體網卡 (14) 將封包加上 VLAN tag 101 並且送往實體網路設施中 (15)
                        * 封包在實體網路設施中送往實體 router 後送往外網
                        ::: info
                        註 : 外網沒辦法主動連線到 Self-Service Network 中使用固定 IP 的虛擬機 (需要使用 floating IP)
                        :::
                
                ::: info
                [floating IP](https://www.cnblogs.com/CloudMan6/p/6020949.html)
                * 設定一個 floating IP 對應到一個虛擬機
                * 外網送到該 floating IP 的封包就會做 DNAT，然後轉送給該虛擬機
                * 這樣外網就能主動發送封包到虛擬網路中的虛擬機
                * 對於 NAT 來說，IPv6 的地址空間和複雜性比 IPv4 大得多，所以 NAT 不支持 IPv6。也就是說 IPv6 不能使用 floating IP
                :::
                * 南北向 2 (外網將封包送往使用 floating IP 的虛擬機)
                    ![](https://i.imgur.com/M7CqJDK.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html)
                    * 使用 floating IP 的虛擬機，送出封包到外網時會做 SNAT，從外網傳到虛擬機的封包會做 DNAT
                    * 因為從 instance 送出封包到外網的步驟和沒有使用 floating IP 時一樣，所以這裡範例是由外網傳送到 instance
                    1. 外網封包到 network node 後 :
                        * 實體網路設施 (1) 將封包送往 Provider 實體網卡 (2)
                        * Provider 實體網卡 (2) 將 VLAN tag 101 拿掉之後送往 Provider Bridge 上的 VLAN sub-interface port (3)
                        * Provider Bridge (4) 將封包送往 Self-service router 上的 Provider Network gateway 介面 (5)
                            * 在 IPv4 的狀況下，router 會用 DNAT 將 destination IP 改成 instance 的 IP 之後將封包透過 Self-service 介面 (6) 送往 Self-service Network
                            * 在 IPv6 的狀況下，router 會將封包送往 next-hop IP 地址，通常是 Self-Service Network gateway 的 IP 位址，所以也一樣是會透過 Self-Service 介面 (6) 送往 Self-Service Network
                        * router 將封包送往 Self-Service Bridge 上的 router port (7)
                        * Self-Service Bridge 將封包送往 VXLAN 介面 (8) 並將封包包進 VNI 101
                        * VXLAN 對應的實體網卡 (9) 將封包透過 overlay 網路 (10) 送往 compute node
                    2. 封包到達 compute node 後 :
                        * 實體網卡 (11) 將封包送往對應的 VXLAN 介面 (12) 並且解開 VXLAN 封包
                        * 在 Self-Service Bridge 上 iptables (13) 會處理防火牆功能
                        * Self-Service Bridge 的 instance port (14) 透過 veth 將封包送往虛擬機的網卡 (15)
                
                * 東西向 1 (封包從虛擬機送往同網路下的虛擬機)
                    ![](https://i.imgur.com/KnKfOQp.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html)
                    1. compute node 1 發送出去 : 
                        * 虛擬機的網卡 (1) 透過 veth 將封包送往 Self-Service Bridge 的 instance port (2)
                        * 在 self-service bridge 上 iptables (3) 會處理防火牆功能
                       * Self-Service Bridge 轉發封包到 VXLAN 介面 (4) 並將封包包入 VNI 101
                        * VXLAN 介面對應的實體網卡 (5) 透過 overlay 網路把封包送往 compute node 2 (6)
                    2. 封包到 compute node 2 之後：
                        * 實體網卡 (7) 將封包送往對應的 VXLAN 介面 (8) 並解開 VXLAN 封包
                        * 在 Self-Service Bridge 上 iptables (9) 會處理防火牆功能
                        * Self-Service Bridge 的 instance port (10) 透過 veth 將封包送往虛擬機的網卡 (11)
                
                * 東西向 2 (封包從虛擬機送往不同網路下的虛擬機)
                    ![](https://i.imgur.com/8CuCbeD.png)
                    > [來源](https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html)
                    1. 從 instance 1 發送出去：
                        * instance 1 的網卡 (1) 透過 veth (2) 將封包送往 Self-Service Bridge 的 instance port
                        * 在 Self-Service Bridge 上 iptables (3) 會處理防火牆功能
                        * Self-Service Bridge 轉發封包到 VXLAN 介面 (4) 並將封包包入 VNI 101
                        * VXLAN 介面對應的實體網卡 (5) 透過 overlay 網路 (6) 把封包送往 network node
                    2. 封包到達 network node 後：
                        * 實體網卡 (7) 將封包送往對應的 VXLAN 介面 (8) 並解開 VXLAN 封包
                        * Self-Service Bridge 的 router port (9) 將封包送往 router namespace 內的 Self-Service Network 1 介面 (10)
                        * router 將封包透過 Self-Service Network 2 介面 (11) 送往 Self-Service Network 2 Bridge 上的 router port (12)
                        * Self-Service Network 2 Bridge 送往 VXLAN 介面 (13) 並將封包包入 VNI 102
                        * VXLAN 介面對應的實體網卡 (14) 將封包透過 overlay network (15) 送往 compute node
                    3. 回到 compute node 上：
                        * 實體網卡 (16) 將封包送往對應的 VXLAN 介面 (17) 並解開 VXLAN 封包
                        * 在 Self-Service Bridge 上 iptables (18) 會處理防火牆功能
                        * Self-Service Bridge 的 instance port (19) 透過 veth 將封包送往 instance 2 的網卡 (20)
                
* reference : 
    * https://ithelp.ithome.com.tw/articles/10262008
    * https://docs.openstack.org/security-guide/networking/architecture.html
    * https://docs.openstack.org/neutron/pike/admin/deploy-lb-provider.html
    * https://docs.openstack.org/neutron/pike/admin/deploy-lb-selfservice.html
    * https://blog.csdn.net/zhengmx100/article/details/54743624
    * https://blog.csdn.net/zouyh/article/details/122653963
    * https://www.cnblogs.com/CloudMan6/p/5722305.html
### Cinder (區塊儲存服務)
* 功用 : 
    *  提供 Block Storage 管理服務，為虛擬機提供 volume
    *  簡單來說就是負責掛載硬碟到虛擬機上，讓虛擬機有儲存空間
    *  本身不是儲存設備，而是管理者
    *  也提供 volume 快照和備份的功能
    ::: info
    [Block Storage](https://www.796t.com/article.php?id=133569)
    
    作業系統獲得儲存空間的方式一般有兩種：
    1. Block Storage : 透過某種協議（SAS , SCSI , SAN , iSCSI...）掛接裸硬碟，然後分割槽、格式化、建立檔案系統。每個裸硬碟就叫做 volume
    2. 檔案系統儲存 : 透過 NFS , CIFS 等協議，mount 遠端的檔案系統
    :::
* 架構 : 
    ![](https://i.imgur.com/hpzzkvK.png)
    > [來源](https://netapp.github.io/openstack-deploy-ops-guide/liberty/content/section_cinder-processes.html)
    * cinder-api
        * 接收外部請求，再把請求透過 message queue 傳給 Cinder 的其他服務
    * cinder-volume
        * 透過不同的 driver 與各種 volume-provider (也稱為 Backend) 連接
        * 讓 volume-provider 提供實際的儲存空間
    ::: info
    volume-provider
    * 為 volume 提供實際儲存空間的儲存裝置就被稱為 volume-provider
    * cinder-volume 支援多種 volume-provider (Swift, Ceph , IBM TSM , NFS...)
    * 每種 volume-provider 通過自己的 driver 來和 cinder-volume 協調工作 
    
    driver
    * 因為 Cinder 支援多種 volume-provider，Cinder 為這些 volume-provider 提供一個統一的介面，volume-provider 只需要對接這個介面就可以隨插隨用到 OpenStack 中
    :::
    * [cinder-scheduler](https://blog.csdn.net/qq_42533216/article/details/114693454)
        * 就像 nova-scheduler 在 Nova 中的角色，透過 Filtering 和 Weighting 找出最適合的儲存節點建立 volume
    * cinder-backup
        * 提供 volume 的備份功能
        * 將 volume 備份到 volume-provider中
        * 也可以將備份 Restore 成為 volume
* 建立 volume 流程圖 :
    ![](https://i.imgur.com/IeedanN.png)
    > [來源](https://netapp.github.io/openstack-deploy-ops-guide/liberty/content/section_cinder-processes.html)
    1. 使用者發送建立 volume 的 api 請求
    2. cinder-api 驗證使用者後把請求訊息放到 message queue
    3. cinder-volume 收到訊息後傳訊息給 cinder-scheduler
    4. cinder-scheduler 篩選並排序出適合建立 volume 的 volume-provider
    5. cinder-volume 根據排序依次讓 volume-provider 建立 volume 直到成功
    6. volume-provider 建立好 volume
    7. cinder-volume 傳遞 volume 的資訊給 cinder-api
    8. cinder-api 傳遞 volume 的資訊給使用者
    9. 使用者收到 volume 資訊
* reference : 
    * https://netapp.github.io/openstack-deploy-ops-guide/liberty/content/section_cinder-processes.html
    * https://ithelp.ithome.com.tw/articles/10268879
    * https://blog.csdn.net/qq_42533216/article/details/114693454
    * https://www.796t.com/article.php?id=133569 
### Glance (映像檔服務)
* 功用 :
    * 映像檔 (image) 管理，包含查詢與存取虛擬機映像檔
    * 本身不提供儲存映像檔
    * 透過其他方式儲存映像檔，常見的有 local filesystem , Ceph , Swift...
    * 在創建虛擬機的時候執行快照建立映像檔
* 架構 : 
    ![](https://i.imgur.com/9eVeUHm.png)
    > [來源](https://blog.csdn.net/qq_33909098/article/details/104414587)
    * glance-api : 
        * 接收外部請求
        * 轉發請求，查詢映像檔資訊就傳給 glance-registry，存取映像檔就傳給 store backend
    * glance-registry : 
        * 在資料庫中儲存映像檔資訊 (metadata)，如 id , size , status , location...
        * location 紀錄映像檔實際存放位置
    * store backend : 實際存放映像檔的地方
* 流程圖 :
    ![](https://i.imgur.com/YmYSMD4.png)
    > [來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FRCga1NuaS2qnrTbLjb8KpA%3Fview#%E5%AE%89%E8%A3%9D-MicroStack)
* reference :
    * https://ithelp.ithome.com.tw/articles/10268127
    * https://blog.csdn.net/qq_33909098/article/details/104414587
### 建立虛擬機的流程 (Nova , Neutron , Keystone , Cinder , Glance)
![](https://i.imgur.com/bgrOZkd.png)
> [來源](https://www.researchgate.net/figure/Virtual-machine-spawning-sequence-in-OpenStack_fig3_346347453)
1. 使用者要建立虛擬機前，要先跟 Keystone 取得使用 nova-api 的認證
2. 通過 Keystone 認證後，回傳 token 給使用者
3. 使用者拿著 token 跟 nova-api 說我要建立虛擬機
4. nova-api 拿這個 token 去跟 Keystone 確認
5. Keystone 回傳驗證結果
6. nova-api 和資料庫通訊
7. nova-api 把要建立的虛擬機的資訊存到資料庫
8. nova-api 把建立虛擬機的訊息傳給 nova-scheduler
9. nova-scheduler 收到建立虛擬機的消息
10. nova-scheduler 從資料庫查詢計算資源的使用狀況
11. nova-scheduler 拿到資料後決定虛擬機要建立在哪個主機上
12. nova-scheduler 把建立在哪個主機上的訊息傳給 nova-compute
13. nova-compute 收到 nova-scheduler 的訊息
14. nova-compute 透過 nova-conductor 跟資料庫要求虛擬機的資訊
15. nova-conductor 收到 nova-compute 的請求
16. nova-conductor 跟資料庫要虛擬機的資訊
17. 資料庫把虛擬機的資訊回傳給 nova-conductor
18. nova-conductor 把虛擬機的資訊傳給 nova-compute，nova-compute 收到虛擬機的資訊
19. nova-compute 透過從 Keystone 拿到的 token 向 glance-api 請求映像檔
20. glance-api 拿這個 token 去跟 Keystone 確認，Keystone回傳驗證結果
21. nova-compute 取得映像檔
22. nova-compute 透過從 Keystone 拿到的 token 向 neutron-server 請求網路資源
23. neutron-server 拿這個 token 去跟 Keystone 確認，Keystone回傳驗證結果
24. nova-compute 取得網路資源
25. nova-compute 透過從 Keystone 拿到的 token 向 cinder-api 請求儲存資源
26. cinder-api 拿這個 token 去跟 Keystone 確認，Keystone回傳驗證結果
27. nova-compute 取得儲存資源
28. nova-compute 根據虛擬機資訊建立虛擬機
### Ceph
提供物件、區塊、檔案系統的儲存服務

![](https://i.imgur.com/0bjC5sV.png)
> [來源](https://www.wenjiangun.com/blog/952/)
* RADOS
    * 一個儲存叢集，由一些 daemon 和多個儲存節點組成
    * daemon :
        * OSD (Object Storage Daemon)
            * 負責儲存資料
            * 監控自己和其他 OSD 的狀態並傳给 Monitor
            * 每個儲存節點上都有一個 OSD
        * Monitor
            * 負責管理叢集狀態
            * 管理叢集成員之間的相對位置，如 OSD Map , MON Map , PG Map , Crush Map，這些 Map 統稱為 Cluster Map
            * Cluster Map 會用 hash 演算法處理 map 資料，這樣在查找 map 資料 (比如找出 Object 對應的 Placement Group) 時，可以更快速
        * Manager
            * 負責追蹤叢集的狀態，如存儲空間使用率、性能、系統負載
        * Metadata Server (MDS)
            * 負責儲存 Filesystem 的 metadata
            * metadata 記錄了目錄、檔案擁有權、存取模式等資料
    * RADOS 儲存資料流程 : 
        * 不論是物件儲存、區塊儲存或是檔案系統儲存的資料，在 RADOS 中都會經過以下步驟儲存至實體儲存設備
        1. client 先向 Monitor 取得叢集資訊 (Cluster Map)
        ![](https://i.imgur.com/R41DG9f.png)
        > [來源](https://docs.ceph.com/en/latest/architecture/#about-pools)
            
        ![](https://i.imgur.com/kPTUu5k.png)
        > [來源](https://blog.csdn.net/bandaoyu/article/details/121847874)
        2. File 是指要儲存的資料
        3. 將 File 以設定的大小 (通常是 2 或 4mb) 切分成多個 Object
        4. 透過 PG Map 的資訊找出每個 Object 各自對應的一個 Placement Group (PG)
        5. 接著透過 Crush Map (是以 CRUSH 演算法處理) 讓每個 PG 對應到多個 OSD (一個 Primary OSD 和多個 Replica OSD)，如果 Primary OSD 故障，可以有複製的 Replica OSD 代替為新的 Primary OSD 和複製一個新的 Replica OSD
        6. OSD 再透過 store backend (預設是 bluestore) 儲存到實體設備
        ::: info
        ![](https://i.imgur.com/Ohl6wdf.jpg)
        > [來源](https://llussy.github.io/2019/08/17/ceph-architecture/)
        * Placement Group (PG) : 
             * PG 裡有多個 Object，可以方便管理多個 Object
             * 如果沒有 PG，Object 就需要一個一個管理(比如更改資料儲存位置)，那就會很麻煩
             * 類似資料夾的概念
        * Pool : 
            * 每個 Pool 由一個使用者擁有
            * 可以做存取控制。Pool 可以設定 PG 查找對應 OSD 時使用的 CRUSH 演算法規則，這就會決定最後對應到的 OSD
            * 也就是說，可以用 Pool 來決定哪個使用者可以存取到哪些儲存設備
        :::
* LIBRADOS
    * 讓 Ceph Clients 對 RADOS 進行操作的函式庫
* Ceph Clients : 
    * Ceph Object Gateway
        ![](https://i.imgur.com/RdprGwj.png)
        > [來源](https://www.sparkmycloud.com/blog/ceph-internals-and-integration-with-openstack/)
        * Ceph 的物件儲存服務
        * 又稱 RADOS Gateway (RGW)
        * 對外提供 Swift API , S3 API 和 Admin API，處理 HTTP 請求
        * RADOS Gateway 接收請求後透過 LIBRGW 把請求處理成 LIBRADOS 與 RADOS 溝通時使用的格式，再傳給 LIBRADOS
        * LIBRADOS 再去 RADOS 進行存取
    * Ceph Block Device
        ![](https://i.imgur.com/pog9VBu.png)
        > [來源](https://www.sparkmycloud.com/blog/ceph-internals-and-integration-with-openstack/)
        * Ceph 的區塊儲存服務
        * 又稱 RADOS Block Device (RBD)
        * Client 可以透過 Kernel RBD (krbd) 或 LIBRBD 向 LIBRADOS 發送請求
            * krbd 通常是 Container 或裸機使用
            * LIBRBD 通常是虛擬機使用
        * LIBRADOS 再去 RADOS 進行存取
    * Ceph File System
        ![](https://i.imgur.com/RL9YEkM.png)
        > [來源](https://docs.ceph.com/en/latest/cephfs/#administration)
        * Ceph 的檔案系統儲存服務
        * 又稱 CephFS
        * Client 透過 LIBCEFS 向 LIBRADOS 發送請求
        * LIBRADOS 再去 RADOS 進行存取
        * RADOS 中的 MDS (Metadata Server) 會記錄 filesystem 的 metadata (如目錄、檔案擁有權)
        * 會有一或多個正在運作的 Active MDS 和一或多個預備用的 Standby MDS，如果 Active MDS 故障，會由 Standby MDS 接替，可以提高可用性
        ::: info
        journal
        journal 在檔案寫入的過程中會做記錄，如果寫入過程中發生 crash，可以透過 journal 復原相對應的工作
        :::
* Openstack 服務使用 Ceph 的關係圖
![](https://i.imgur.com/lrXwPsd.png)
> [來源](https://www.sparkmycloud.com/blog/ceph-internals-and-integration-with-openstack/)
        
### Ironic (裸機部署服務)
* 功用 :
    * 裸機部署服務，部署映像檔到實體的伺服器上
    * 某些使用情況下，虛擬化的環境是不合適的，若要部署在實體的伺服器上，就需要 Ironic 這個服務
* 部署裸機的原因 : 
    * 某些運算任務無法訪問虛擬化的硬體
    * 當作資料庫主機，某些資料庫在虛擬化環境下效能不佳
    * 單租戶，效能和安全性較好
    * 快速部署雲基礎設施
* 架構 :
    ![](https://i.imgur.com/Z7BEpec.png)
    > [來源](https://docs.openstack.org/ironic/xena/install/get_started.html)
    * ironic-api : 接收外部請求
    * ironic-conductor :
        * 新增 / 編輯 / 刪除裸機節點
        * 透過 driver 操作硬體
    * driver : ironic-conductor 跟不同硬體溝通的介面
    * 資料庫 : 儲存裸機的硬體資訊和狀態
* 部署裸機流程圖 :
    ![](https://i.imgur.com/jXFboNT.png)
    > [來源](https://docs.openstack.org/ironic/xena/install/get_started.html)
    1. nova-api 和 nova-sheduler 發送部署裸機請求給 nova-compute 
    2. nova-compute 透過 ironic virt driver 把請求傳給 ironic-api
    3. ironic-api 把請求傳給 ironic-conductor
    4. ironic-conductor 透過 driver 部署裸機
* reference :
    *   https://docs.openstack.org/ironic/latest/user/architecture.html
    * https://docs.openstack.org/ironic/xena/install/get_started.html
    * https://ppfocus.com/0/te1deaa0e.html
### Horizon (儀錶板)
* 使用者操作介面，用瀏覽器開啟
* 讓使用者可以不用以指令操作 Openstack

![](https://i.imgur.com/0bNcPCR.png)
> [來源](http://blueskyfreeway2.blogspot.com/2019/05/openstack.html)
### Heat (編排服務)

* 功用 : 
    * 當需要管理的資源太多時，一個一個手動設定會很麻煩，可以透過 heat 來自動化部署或配置，比如自動創建虛擬機、自動掛載 volume...
    * 以 template (模板) 定義對 resource (資源) 的操作順序
        * resource : 指虛擬機或 volume 等 Openstack 中的資源
    * heat 解析 template 後會產生 stack
        * stack : resource 的集合
    * 完成一個 stack 的創建，就能完成對多個資源的操作
    ![](https://i.imgur.com/XkkjNz9.png)
    > [來源](https://zhuanlan.zhihu.com/p/60683564)
* reference : 
    * http://wsfdl.com/openstack/2014/02/14/Introduction_to_heat.html
    * https://zhuanlan.zhihu.com/p/60683564
### Swift (物件儲存服務)
* 功用 :
    * 存取非結構性資料，如文件、網路內容、備份、影像和虛擬機快照
    * 透過 REST API 操作 (儲存、刪除、取得) 物件 (object)
    ::: info
    [結構化資料 vs 非結構化資料](https://ithelp.ithome.com.tw/articles/10200157)
    * 結構化資料 :
        * 資料可以被呈現在資料庫 table 的行、欄
        * 每筆資料都有規定的欄位、規定的格式
    * 非結構化資料 :
        * 形式自由且不遵循標準的格式規範，一團沒有組織的數據
        * 比如圖像、音檔、影片、電子郵件
        * 非結構化資料通常比結構化資料更大，佔用更多存儲空間
    :::
* 特色 : 
    * 可擴展性高 : 
        * 因應儲存空間需求 : 新增儲存點 (storage node)
        * 因應連線需求增加 : 新增伺服點 (proxy node)
    * 可靠度高 : 
        * 預設情況下，所有儲存在 Swift 的物件 (Object) 都會複製總共三個副本，分散於叢集 (cluster) 中
        * 每一次寫入資料時，都會確認是否也同時寫入其他兩個位置才會視為成功
* 架構 : 
    ![](https://i.imgur.com/7Cfi0R2.png)
    > [來源](https://read01.com/zh-tw/Pk6B4B.html#.ZDGrFXZBzGJ)
    * Proxy Server : 接收外部 HTTP 請求，把請求傳送到對應的 Object Server , Container Server , Account Server 處理
    * Ring : 記錄存儲對象與實體位置間的映射 (mapping)，分為 Object Ring , Container Ring 和 Account Ring
    * Object Server : 
        * 負責實際檔案的儲存，檔案是以二進位的方式儲存於磁碟中
        * 檔案路徑包含時間戳記 (timestamp)，讓 Swift 可以同時儲存和分辨不同版本的檔案
    * Container Server : 
        * 處理 Container 相關的 metadata 和 Container 所包含的 Object 資訊，也統計 Container 信息 (比如 Object 的數量，Container 的使用情況)
        * Container Server 並不知道 Object 存在哪，只知道 Container 裡有哪些 Object
    * Account Server : 
        * 處理與 Account 相關的 metadata & Account 內所包含的 Container 資訊
        * Account 是一堆 Container 的集合
    ![](https://i.imgur.com/skhFPn2.png)
    > [來源](https://platform.swiftstack.com/docs/introduction/openstack_swift.html)
* 服務
    * 為了確保每個節點之間的資料一致，swift 提供 Auditor , Replicator 和 Updater 服務
    * Auditor
        * 檢查 object , container 和 account 資料的完整性
        * 如果發現損壞 (例如 Bit rot），文件會被移到隔離區，Replicator 再從其他節點複製完整副本來替代
        ::: info
        Bit rot
        * 資料發生隨機位元翻轉的現象（0 變成 1 或者 1 變成 0）
        * 通常是因儲存媒介長期使用逐漸損壞而發生
        :::
    * Replicator
        * 確保其他 storage node 的資料和本地的資料一致
        * 如果其他 stoage node 的資料過舊或遺失，會把本地資料複製一份過去
        * 但如果是本地資料過舊或遺失，並不會把其他 storage node 的資料複製過來
    * Updater
        * 在故障或高負載時可能會更新失敗，此次的資料更新就會交給Updater 處理
* reference : 
    * https://docs.openstack.org/swift/latest/overview_architecture.html
    * https://platform.swiftstack.com/docs/introduction/openstack_swift.html
    * http://godleon.blogspot.com/2014/10/openstack-swift_14.html
    * https://ithelp.ithome.com.tw/articles/10092536
## 實作
### 用 Microstack 部署 Openstack
* 透過 Ubuntu Snap Packages 安裝
* Why Microstack?
    * Openstack 部署設定複雜 : Service 數量多且各自也有很多設定檔和參數，會安裝得很痛苦
    * Microstack 安裝簡單快速 : 只需要 2 個指令和大約 30 分鐘就能完成，和其他部署方式相比簡單很多
    * Upstream : MicroStack 安裝的 OpenStack 是上游未經修改的 OpenStack 程式碼，不用擔心有廠商自己加入的功能造成系統不穩
    * 完整 : 會把環境需要的 Keystone , Nova , Glance , Neutron , Cinder , Horizon 等基本服務都一起裝好
* 其他部署方式 : DevStack , TripleO , OpenStack Charms , OpenStack-Ansible , Kolla-Ansible , OpenStack-Helm
### 安裝 Microstack
1. 要求配置 : 
    ![](https://i.imgur.com/B7rKEMZ.png)
    > [來源](https://ubuntu.com/openstack/install)
2. 安裝指令 : 
`sudo snap install microstack --beta --devmode`  
    * `--beta` : 測試版的 channel。其他 channel 有 stable , candidate , edge
    * `--devmode` : 軟體對系統有完全的存取權限。其他有 strict , classic
3. 初始化 :
    * 會自動部署、設置設定檔和啟動 Openstack 服務
    * 指令 : `sudo microstack init --auto --control`
    * 完成後可以下 `microstack.openstack catalog list` 查看已安裝哪些 Openstack 的服務
### 操作 Openstack
* 瀏覽器打開 http://10.20.20.1，會看到登入介面
![](https://i.imgur.com/TJAPfrh.png)
* username 為 admin
* password 要在 terminal 下 `sudo snap get microstack config.credentials.keystone-password` 取得
![](https://i.imgur.com/qgjNrEL.png)
* 可以直接用介面操作或是用 terminal 以指令操作
* 新增虛擬機 : `microstack launch {映像檔名稱} --name {虛擬機名稱}`
::: info
cirros : 內建的映像檔，主要用來測試能不能連線之類的
:::
![](https://i.imgur.com/1gb7jhp.png)
* 查看目前虛擬機資訊 : `microstack.openstack server list`
![](https://i.imgur.com/bUzLLSf.png)
* ssh 到虛擬機 : `ssh -i /home/kenny/snap/microstack/common/.ssh/id_microstack cirros@10.20.20.80`
![](https://i.imgur.com/WJmMTcz.png)
* 啟動 microstack : `sudo snap enable microstack`
* 關閉 microstack : `sudo snap disable microstack`

### 建立虛擬機讓實體內網下其他主機連得到
![](https://i.imgur.com/KNoGyrJ.jpg)
* 做法
    * 建立一個連接虛擬網卡 (br-ex) 的虛擬外網，虛擬外網與實體網路同網段
    * 建立虛擬內網
    * 建立虛擬 router 連接虛擬內外網
    * 建立一個在虛擬內網下的虛擬機
    * 使用虛擬外網的 floating IP 對應到虛擬內網的虛擬機 IP
    * 橋接虛擬網卡到實體網卡
    * 用其他實體網路下的主機連線到 Openstack 的虛擬機
* 先查看內網網段和 gateway IP
![](https://i.imgur.com/UnIXi5d.png)
> MOLi_LEGACY 網段是 192.168.100.0/24，gateway 是 192.168.100.150
* 確認實體主機的 IP 位址
![](https://i.imgur.com/SCvYFGO.png)
> 裝 Openstack 主機的 IP 是 192.168.100.51
#### 1. 建立一個跟實體內網網段一樣的虛擬外網
> Admin -> Network -> Networks -> Create Network

![](https://i.imgur.com/qyzExCw.png)
> 照範例填入網路名稱、類型...
> Physical Network 要指定連到虛擬網卡 br-ex 的網路名稱

![](https://i.imgur.com/YBd99H8.png)
::: info
* micostack 中預設對應到 br-ex 的名稱是 physnet1 (已在一開始部署時用來建立虛擬網路 10.20.20.1/24，建議不要刪除，因為 Openstack 的服務都綁訂到這個網路上了)
* physnet1 不能重複使用，所以要新增一個 physnet2，並在設定裡添加physnet2 對應 br-ex
`sudo microstack.ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-ex,physnet2:br-ex"`
:::
> 建立子網路，網段和 gateway 要跟實體網路一樣

![](https://i.imgur.com/jFz83YL.png)

> 建立 IP 位址池範圍，可以用來作為分給虛擬機對外的 floating IP，要檢查不能跟其他實體主機 IP 相同
> DHCP 要關掉

![](https://i.imgur.com/Q0B7Jgq.png)

#### 2. 橋接虛擬網卡到實體網卡 (建議用 ethernet 比較不會踩坑:cry:)
```
sudo microstack.ovs-vsctl add-port br-ex 實體網卡名稱 //把虛擬網卡橋接到實體網卡
sudo ip addr flush dev 實體網卡名稱 //清掉實體網卡的 IP，避免跟虛擬網卡 IP 重複
sudo ip addr add 實體網卡IP/網段數字 dev br-ex //把原本實體網卡的 IP 位址加到虛擬網卡上
sudo ip link set br-ex up //啟用虛擬網卡
```
以我的主機為例
```
sudo microstack.ovs-vsctl add-port br-ex eno2
sudo ip addr flush dev eno2
sudo ip addr add 192.168.100.51/24 dev br-ex
sudo ip link set br-ex up
```
#### 3. 建立虛擬內網
> Admin -> Network -> Networks -> Create Network

![](https://i.imgur.com/qyzExCw.png)
> 照範例填入網路名稱、類型…

![](https://i.imgur.com/uMHiBDW.png)
> 虛擬內網網段可以自訂，不要跟實體網路一樣就好

![](https://i.imgur.com/ohhcCsQ.png)

> 開啟 DHCP

![](https://i.imgur.com/9Vn8gfS.png)

#### 4. 建立虛擬 router 連接虛擬內網和外網
> Admin -> Network -> Routers -> Create Router

![](https://i.imgur.com/2jUSSV3.png)
> 在虛擬外網上建立虛擬 router

![](https://i.imgur.com/56UiQLP.png)
> Project -> Network -> Network Topology -> 點剛才新增的 router -> Add Interface (要把虛擬 router 接到虛擬內網)

![](https://i.imgur.com/qgCuDB8.png)
> 選擇剛才建的虛擬內網

![](https://i.imgur.com/Wgmwb9t.png)

#### 5. 產生一個 floating IP
> Admin -> Network -> Floating IPs -> Allocate IP To Project

![](https://i.imgur.com/lYRw96d.png)
> 選擇從虛擬外網產生一個 floating IP

![](https://i.imgur.com/A7UVsIn.png)

#### 6. 在虛擬內網建立虛擬機
> Project -> Compute -> Instances -> Launch Instance

![](https://i.imgur.com/TY40hZR.png)
> 設定虛擬機的名稱、性能、映像檔、網路

![](https://i.imgur.com/5jAvEPT.png)
> microstack 預設只有測試用的 cirros 映像檔，需要其他映像檔要再下載

![](https://i.imgur.com/zlZkUFB.png)
> 設定主機性能配置

![](https://i.imgur.com/mlYHmID.png)
> 設定主機網路，要建在虛擬內網下，設定完這些就能建立虛擬機了

![](https://i.imgur.com/87wR91q.png)

#### 7. 配對 floating IP 到虛擬機的虛擬內網 IP
> Project -> Network -> Floating IPs -> 找到剛才產生的 floating IP -> Associate

![](https://i.imgur.com/5Si2D3w.png)
> 設定這個 floating IP 對應到虛擬機的虛擬內網 IP

![](https://i.imgur.com/t7BwWTb.png)

#### 8. 測試連線虛擬機
> 用其他主機 ping 虛擬機的 floating IP

![](https://i.imgur.com/B5TYift.png)
> 測試 ssh 連線
> 預設使用者是 cirros，密碼是 gocubsgo

![](https://i.imgur.com/d25faqT.png)
> 看到`$`就代表連線到虛擬機裡了！
### reference
* https://ithelp.ithome.com.tw/articles/10269737
* https://web.archive.org/web/20230202012610/https://connection.rnascimento.com/2021/03/08/openstack-single-node-microstack/