字數總計:0 個 | 閱讀時長:0 分鐘 |閱讀次數:

11.4 環境基礎設施管理

11.4.1 環境準備的4種狀態

  1. 蠻荒法
    • 以 "人腦 + 手工” 代表
    • 剛起步的專案,整體不複雜,用戶與客戶數量不多
      1. 開發人員自己就可以搞定所有的軟體部屬相關問題
      2. 所有環境準備相關的知識都在開發人員腦中,團隊核心與英雄
  2. 規範法
    • 以 "文檔" + "私有腳本" 代表的 規範化狀態
    • 隨著軟體服務的成功,用戶跟客戶數量變多,更多需求滿天飛過來,伺服器的數量也因此增長不少,環境維護工作變得多了起來
      1. 要求正式上線的部屬文件,通常會總結出一個環境部屬的準備說明書,由維運的人來執行
        • 例如 文檔可能有11個步驟,但每個步驟中又有許多子步驟。
        • 很多團隊是找不到這樣的環境說明文件,即使找到,可能也是無法使用過時的文件
      2. 要有規範化的上線部屬流程,此階段需要有個SOP文件,詳細紀錄每次的操作
      3. 利用私有化腳本,提升效率。每次的升級腳本都會重複之前一些動作
      • 現在仍然有非常多的企業處於圖中此種狀態 11.4.2 某金融企業的上線流程是意圖
      1. 流程通過 "人" 來維護,經常有遺漏
      2. 文檔通過 "EMAIL"追蹤,查找不方便
      3. 審查工作量大,由於手工工作量大,常有人繞過過程
      4. 自動化腳本不規範統一,而且經常出錯,導致部屬過程中斷
  3. 以辦公自動化為代表的 "標準化狀態"
    • 隨著軟體服務的越來越成功,公司也不斷的壯大,維運人員越來越多,生產部屬事件也多了起來
    • 無紙化的型態出現,原先使用office寫文件,轉為線上系統填寫
      1. 流程平台統一化,軟體開發與維運皆在同一平台上
      2. 部分內容標準統一
      3. 可以部份重用,減少工作量
      4. 審核工作變得容易,所有紀錄皆保留平台上
    • 但仍然有些許問題
      1. 系統操作變得複雜,有些仍需人工餐與
      2. 兩次上線部屬差異比對仍然困難,雖然開發人員可以複製上一份資料,但每個皆為獨立副本,很難進行比對查找
  4. 以受控式自動化腳本為代表的 "自動化狀態"
    • 此階段的自動化維運腳本有兩種型態
      1. 操作過程式為主
        • 符合原有的思考習慣,將原本的手工操作步驟轉為腳本語言即可
        • 靈活,想做甚麼操作,幾乎手工操作都可以辦到,不受任何約束
      2. 狀態聲明式為主
        • 可以明確知道,無論何種情況或誰來執行這個腳本,皆可以得到相同結果
        • 如果將此腳本放置 git倉庫,可通過diff功能,比對差異
        • 學習成本高,此DSL(Domain=Specific Language,領域專屬語言)用來描述環境部屬的專有操作與狀態
        • 腳本數量較多時,文件管理也存在相同儲存結構問題
        • 此時可使用一些工作來做為輔助 11.4.2 CICD管理工具
      • 工具運行模式可分兩種
        • 拉模式
          • 目標伺服器安裝 agent,保持與伺服器的連線與接受指令
        • 推模式
          • 不須安裝客戶端 agent,只需由伺服器遠端連線進行操作即可

11.4.2 領域專屬語言的應用

    • 以上說明的這些工具都定義了各自工具領域,此種語言可以描述出環境部屬狀態的文件。
    • 以 Puppet管理 apache2 服務為例來說明 11.4.3 Puppet管理apache2腳本範例
    • Ansible 語法範例 11.4.4 Ansible 部屬apache2腳本範例

11.4.3 環境基礎設施即代碼

  • 現在,已將環境基礎設施一系列準備工作以腳本描述出來,也能通過自動化方式來執行。
    • 好處 1. 無論哪個環境出問題,皆能快速構建出全新的環境 1. 只要有權限,任何人皆可完成任務 1. 任何對環境修改都可以被記錄與審核 1. 對不同環境來說,將腳本對比即可知道差異,不需再登入至伺服器
    • 為了更進一步的優化,版本管理應該要有 1. 操作系統名稱的版本號、補丁號與系統配置訊息 1. 依賴軟體包的所有版本號與設置的內容 1. 需與應用程式連線的版本號與設定檔內容

11.5 軟體配置項的管理

11.5.1 二進制與配置項的分離

  • 一個應用程式通常程式碼與可執行檔是分開的,一旦編譯完成,此編譯執行檔就不會更改
  • 編譯建置過程中,可能會有依賴其他套件包,通常套件包與編譯完成的執行檔是為分開的,但這兩項為必須,因而可視為不可分割的一環 11.5.1 二進制與配置項的分離示意
  • 二進制執行檔部屬時需與套件包的各版本完全相同

11.5.2 配置信息的版本管理

  • 編譯執行檔時根據內容不同會設置各種設定檔
    1. 環境配置項(environment configuration)
      • 網域、ip、api port、web port ...等
    2. 應用配置項(application configuration)
      • 初始資料(帳密、通用資料...等)
      • VM資源設置
      • DB連線資料
      • Log紀錄相關設定
    3. 商務配置項(bussiness configuration)
      • 預設值設定檔
      • 某些商業邏輯計算設定 11.5.2 配置的分類
    • 使用資料夾來區分不同開發環境的設定檔 11.5.3 靜態配置與產品代碼同源

11.5.3 配置項的儲存組織方式

  • 儲存配置方法很多,最簡單的為使用純文字來記錄
  • 可針對不同環境寫不同設置
  • 編譯時將根據不同環境自動載入配置檔 11.5.4 配置文件示意圖

11.5.4 配置飄移與治理

  • 隨著生產環境發展,某些設定檔會偏移原先預期的設定,通常是由臨時修改測試所引起的
  • 一段時間必須做校正回歸,否則將常出現不穩定狀態,甚至當機
  • 好的配置可以解決飄移問題,也可避免人為操作上的遺漏

11.6 不可變基礎設施與應用

11.6.1 實現不可變基礎設施

  1. 物理主機鏡象技術 與 虛擬機鏡象技術
    • 這兩種技術都可以提供環境準備效率
    • 將上線的服務一模一樣分為兩份,同時部屬至不同地方
    • 虛擬機除了可鏡象分離腳本外也可動態分配系統資源
  2. Docker容器技術
    • 容器化特性可使部屬軟體部分大幅降低難度與成本

11.6.2 雲原生應用

  • 雲端服務PAAS,可讓部屬人員使用 git push 即可完成部屬動作,只需等待建置完成後的結果
  • PAAS先驅 Heroku 提出了 雲原生應用12要素
    1. 一套基本代碼多環境部屬
    2. 顯示聲明依賴關係
    3. 在環境中儲存配置
    4. 把後端服務當作附加資源
    5. 嚴格分離建置、發佈與運行
    6. 應用程式本身應該是一個或多個無狀態進程,進程之間沒有資料共享
    7. 通過端口綁定提供服務
    8. 通過進程模型進行擴展
    9. 快速啟動與優雅終止
    10. 盡可能讓開發環境、預生產環境與生產環境等價
    11. 日誌作為事件流
    12. 將管理/管理任務作為一次性進程運行

11.6.3 優勢與挑戰

  • 優勢
    1. 簡化維運工作
    2. 部屬流程自行產生文件
    3. 持續部屬不停機,故障更少
    4. 減少錯誤與威脅
    5. 多類環境基礎設施的一致性
    6. 杜絕了"配置飄移"
    7. 被測試的即是被使用的
  • 相對代價的挑戰
    1. 為不可變基礎設施建立一套自動化,初期成本較高
    2. 生產環境突發狀況,修復時間可能稍長
    3. 對大規模軟體服務來說,大檔案鏡象發佈至多台伺服器會消耗大量的網路資源,時間也會消耗不少
    4. 有狀態儲存軟體服務不容易被直接替換

11.7 資料的版本管理

每個軟體都需要處理資料,對資料進行版本管理是一件比較困難的事情,但是我們可以通過對其中一部分內容進行版本管理,來提高產品之間的合作效率。例如: 加快測試環境的建立,提高自動化測試使用案例的執行可靠性。

11.7.1 資料庫結構變更

當你使用關聯式資料庫系統,當軟體部署頻率變高,同時參與軟體開發的人員變多時,就應該對資料庫進行版本管理。除審計(Audit)管理和問題訂位外,對資料庫的版本管理在開發和自動化測試中也是非常有效地。

下圖為通過Flyway或Liquibase這類工具進行資料庫的升級或降級操作。搭配CI/CD工具的在執行Pipeline時,進行資料庫的管理。 11-21 通過腳本保存關聯式資料庫的Schema變更

當我們把資料庫結構的變動腳本放到原始碼倉庫後,在執行自動化測試時,可以很方便地得到一個乾淨的初始化資料庫版本。當發布給客戶的歷史版本出現Bug時,為了訂位問題,我們可以很快的對資料庫進行清空然後重建到特定的資料庫版本。

11.7.2 Binary文件

對於二進制文件的版本管理,就不能使用原始碼版本控制系統了。此時可以通過類似FTP、遠端檔案系統進行管理。

💡 這邊推薦MINIO系統服務來管理,他支援二進制的檔案版本管理,非常方便,參考MINIO Versioning

當某公司內有一個大檔案儲存系統時,你可以將大尺寸檔案上傳到系統中時,它會返回一個URI,將URI放到一個文字檔案內容中,然後將文件檔內容納入到Git版本控制。這樣就將資料與產品原始碼版本進行統一的版本管理了。此時URL就是一個引用,而大檔案儲存系統就相當於一個儲存資料並進行版本管理的共享倉庫,這種方式對於測試資料管理是非常方便的。

另外一種狀況,當應用程式的啟動或運行需要仰賴一組資料檔案時,例如: 資料庫連線字串,我們可以先將資料庫連線字串進行演算法加密,當作一份二進制文件,然後將解密的演算法腳本加入到Git資料庫版本控管中,在程式執行時,將二進制文件進行載入後,在執行解密的演算法後,再進行資料庫的連線。

資料庫版本補充

請參考Appendix 01 Database Version Control

11.8 需求與原始碼的版本關聯

由11-1圖中,程式碼、軟體包、環境都進行管理了,但我們想要對程式碼與需求項目進行關聯時,應該如何處理呢?

我們可以將需求內容進行文件化,並與對應的軟體包版本進行關聯,如果需求顆粒度要更細的管理,也可以將管理平台中的每個需求項目ID(或缺陷管理系統的缺陷ID)與程式碼進行關聯。例如: 再每次向程式碼倉庫提交程式碼時,將需求項目的ID,做為提交註解的一部分,並將這種關聯訊息進行展開出來。下圖是Mingle工具中的關聯參考

Mingle的SaaS從2019/7/31號開始已經停止服務。參考官網。你可以使用其他替代工具,例如: jira、Asana 、TFS等等。

11-22 工具Mingle與程式碼倉庫的關聯式意圖

11.9 小結

良好的軟體管理是打造持續交付Pipeline、加速驗證壞環節的基礎。

本章節主要有三個核心管理。

  1. 對一切進行版本管理
  2. 共享唯一來源
  3. 標準化與自動化

可以透過下面5個問題來驗證檢查你是否對一切都做了版本管理。下列5個問題是否都有放入到版本控制系統中呢?

  1. 產品原始碼和測試程式碼
  2. 軟體應用的配置訊息
  3. 各類環境的系統配置
  4. 自動化的建置和部署腳本
  5. 軟體包是否進行版本管理

另外可以利用下列兩個問題來檢查軟體管理是否做得足夠好。

  1. 可以透過原始碼倉庫的專案,一鍵式地建構出完整軟體包嗎?
  2. 在沒有他人的幫助下,任何團隊成員都可以一鍵式自動化搭建出一套應用軟體系統,用於體驗產品新功能嗎?