基于 Kubernetes 的基础设施即代码
11 月 9、10 號兩天,.NET 社區第一次以“.NET 大會”為品牌在上海召開了第一屆峰會,現場與會者達到 600 人規模。大會的第 1 天是各類演講分享,第 2 天有多個動手實踐課。張善友隊長、?劉騰飛?和我一起策劃了基于 Kubernetes 的 .NET Core 微服務和 CI/CD 動手實踐工作坊,一共有現場 30 多位,外加線上 200 多位人士參與了這個工作坊。
在基于 Kubernetes 的 .NET Core 微服務和 CI/CD 動手實踐工作坊中,我們使用一系列腳本,盡可能地對所有環境的安裝和配置工作進行了自動化。工作坊中的每一個與會者都只要按照說明,執行幾個腳本,就可以自動地準備好自己的一整套 CI/CD 和微服務部署基礎設施,
“基礎設施即代碼”指的是,使用代碼描述所有基礎設施的安裝和配置過程,包括這些基礎設施軟件的各項設置和日常使用數據,都要使用代碼進行描述。從而享受基于代碼的版本管理和自動化執行等能力。這一概念強調,不僅軟件本身的生產(持續集成即代碼)和部署過程(持續部署即代碼)可由代碼來描述,用于托管并運行軟件的基礎設施(即服務器環境本身)的創建和配置過程也要能以代碼的方式描述并維護。
概要介紹
在工作坊中,現場參與的每個人,都基于提前準備好的 Kubernetes 集群搭建了可供開發用的 Git 服務器和 CI/CD 工具體系,并成功部署了微服務。工作坊還帶著與會者體驗了將 .NET Core 應用從 IDE 代碼開發、把代碼提交到 Git 服務器,經過 CI/CD 自動編譯、發布容器鏡像,并最終自動部署到 Kubernetes 平臺的完整過程。
支持這一過程的基礎設施的整體示意圖為:
具體實現代碼、腳本和配置,都在這個 GitHub 倉庫:https://github.com/netconf-cn2019-workshop/dev-services/?其中各個微服務,請回到上一級別,自行下載。
整個代碼庫的結構如下:
| 123456789 10 11 12 13 14 15 16 17 | . ├── cicd-infra # 存放 CI/CD 軟件部署代碼的目錄 │?? ├── cicd-installer.yaml # 用于 CI/CD 軟件的初始化配置 │?? ├── gogs.yaml # 安裝 Gogs 的 Kubernetes 配置 │?? ├── jenkins.yaml # 安裝 Jenkins 的 Kubernetes 配置 │?? ├── nexus.yaml # 安裝 Nexus 的 Kubernetes 配置 │?? ├── sonarqube.yaml # 安裝 Sonarqube 的 Kubernetes 配置 │?? └── vars # 定義安裝 CI/CD 軟件過程中的變量 ├── provision-cicd.sh # 啟動安裝 CI/CD 軟件的腳本文件 ├── provision-infra.sh # 啟動安裝微服務公用基礎設施的腳本文件 ├── provision-services.sh # 啟動安裝微服務的腳本文件 ├── service-infra # 存放微服務公用基礎設施部署代碼的目錄 │?? └── infra.yaml # 用于安裝微服務公用基礎設施的 Kubernetes 配置 ├── services # 存放微服務部署代碼的目錄 │?? ├── service-list # 定義部署的微服務及其鏡像版本的變量 │?? └── vars # 定義安裝微服務過程中使用的變量 └── tmpl.sh # 讀入變量值并將其應用到使用變量的文件 |
本文,我們概要地探討這整個過程的原理和大致步驟。還有兩篇文章分別介紹?CI/CD 部分及微服務部署部分的實現原理。
CI/CD 軟件
一般來說,一個典型的團隊 CI/CD 基礎設施包含下列內容:
代碼服務器,用于存儲各個產品的源代碼,以及日常工作中使用的各類腳本和配置。
持續集成軟件,用于自動地對產品源代碼進行一系列自動化處理,比如安裝依賴、編譯、單元測試、格式檢查等,并最終產生可以直接運行的二進制格式軟件。
制成品產物(發布物)存儲軟件,用于存儲最終生成的二進制格式軟件。
容器注冊表,用于存儲軟件的容器鏡像(包含二進制格式軟件、軟件依賴的操作系統和第三方軟件與配置等內容)的存儲軟件。
基本上,社區中關于這些軟件的選用已經有了一些“偏好” 。基于社區的偏好,我們在工作坊中做了這樣一些選擇:
| 代碼服務器 | 國人開發的優秀 Git 服務器軟件?Gogs |
| 持續集成軟件 | 廣為使用的?Jenkins |
| 發布物存儲軟件 | 廣為使用的?Nexus |
| 容器注冊表 | Coding 制品庫容器鏡像服務 |
由于要在 Kubernetes 集群中安裝,所以上述這些軟件,我們都需要使用它們的容器版本。容器注冊表的安裝和配置比較麻煩,為了簡化工作坊現場的流程,所以我們選用現成的外部容器注冊表服務。
CI/CD 軟件的安裝過程在腳本文件?provision-cicd.sh?中,這是一個 Bash 腳本文件。這個腳本文件既可用于 CI/CD 軟件的部署(deploy),也可以用于整個工作坊環境的清理(delete)。當以部署模式(deploy)運行時,腳本會首先在 Kubernetes 集群上創建多個命名空間(namespace),并在?cicd?命名空間中依次啟動安裝 Jenkins、Nexus、Gogs 和 Sonarqube 等軟件,最后會在 cicd 命名空間中啟動一個初始化腳本(cicd-installer)。cicd-installer 初始化腳本將負責等待軟件完成安裝,并向它們導入必要的初始化數據。
在安裝過程中,會用到一些“變量”,比如表示當前用戶的?deploy_suffix?等。在我們為各個軟件編寫的 Kubernetes 安裝文件(.yaml)中的相應位置上均引用了變量。而在?provision-cicd.sh?腳本文件中,在執行?kubectl apply?之前,它借助?tmpl.sh?腳本文件完成變量的填充,變量的值聲明在?cicd-infra/vars?文件中。這也要求,在部署之前,工作坊的參與者需要提前編輯這個變量文件,確保其中的各個值都是正確的。
微服務的部署
微服務的部署分成了兩部分:微服務公用基礎設施和各個微服務本身。之所以要分成兩個部分,是因為對于特定的部署環境(如 dev)來說,公用基礎設施只需要部署一次;而各個微服務則有可能隨著代碼的持續更新而需要經常部署。
微服務公用基礎設施
工作坊的微服務依賴一些公用的基礎軟件,比如 Redis 緩存服務和 SqlServer 數據庫服務。
這些基礎設施的安裝過程在腳本文件?provision-infra.sh?中,這也是一個 Bash 腳本文件。它的原理很簡單,而且微服務基礎設施的安裝過程沒有變量。所以,它直接在在相應部署環境對應的命令空間(如 dev)執行?kubectl apply ./service-infra/infra.yaml?就完成了安裝。安裝動作之后,腳本會等待安裝完成,確保數據庫處于運行狀態之后,再執行數據庫表結構的初始化操作,并向其中導入種子數據。
微服務的部署
各個微服務的部署本來應該是相當直觀的,不過由于涉及到微服務的容器版本,所以實際過程卻要稍微麻煩一點。
微服務的部署腳本文件是?provision-services.sh?中,這又是一個 Bash 腳本文件。腳本會從?services/service-list?文件中讀入要部署的微服務的信息(容器鏡像名稱及標簽),并逐個調用對應微服務所在項目目錄中的?k8s.yaml?文件來執行部署。在部署過程中,也會涉及前面講過的類似的變量處理過程,即讀入?services/vars?文件,用于為微服務部署過程提供變量值。所以,同樣,工作坊的參與者需要提前編輯這個變量文件,確保其中的各個值都是正確的。
由于將待部署的微服務列表使用單獨的配置文件?services/service-list,因此不管是手工執行腳本部署,或是工作坊中練習的使用 CI 進行自動化部署,都可以通過編輯這個文件來指定要部署的微服務列表和版本。
環境初始化
在工作坊中,我們實現了一種“預配置”的效果。也就是,當工作坊與會者打開剛剛安裝完成的 Jenkins 之后,會發現微服務的流水線已經創建完成了;當他們打開 Gogs 時,會發現上面已經預置了各個微服務的代碼倉庫。實際上,諸如此類的始化工作還有很多。而且,最重要的是,這些初始化工作也是由代碼來描述的。
在工作坊的準備過程中,為了實現自動完成這些初始配置工作,我們結合使用了多種技術。這里先簡單列舉其中用到的幾種技術,后面另外會寫文章重點解讀特定環節的實現原理:
Jenkins 的預置流水線是用 Jenkins 寫入配置文件實現的
Gogs 的預置代碼倉庫是用 Gogs 的 RESTful API 導入的
Nexus 修改內置密碼是用基于 RESTful API 的腳本接口完成的
SqlServer 的表結構是通過直接在 Pod 上執行指定的命令行程序實現的
通過結合使用這些技術,我們不光用 yaml 文件描述了這些軟件的安裝過程,還能夠以代碼的方式描述在這些軟件上需要完成的配置。
總結
整個工作坊的基礎環境就是由這幾個部分構成的,各個部分都是使用代碼來描述的。這里所講的代碼包含各種類型的代碼,有供 Kubernetes 集群用的 yaml 文件,有 Bash 腳本文件,還有變量文件等。這些代碼文件都有兩個特點:
都是文本文件,可以由源代碼版本管理工具管理
都以某種形式參與到自動化的執行過程中
符合這兩個特點,最終部署出一個“基于 Kubernetes 的基礎設施環境”,也就實現了基于 Kubernetes 的基礎設施即代碼。
事實證明,這個實踐為可靠地重復創建工作坊環境提供了充分的保障,為工作坊的順利舉辦和后期持續優化建立了不錯的基礎。
原文地址:https://blog.jijiechen.com/post/infrastructure-as-code-on-kubernetes/
總結
以上是生活随笔為你收集整理的基于 Kubernetes 的基础设施即代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【好文】为什么必须学好.Net Core
- 下一篇: 原创 | 为什么年终奖是一个彻头彻尾的职