描述
內容簡介
►Kubernetes 控制面與節點組件的功能與結構
►Kubernetes API 的組、版本及資源定義 ►宣告式 API 與控制器模式的運作機制 ►Kubernetes 社區治理與貢獻開發流程 ►API Server 的結構、原理與原始碼解析 ►Kubernetes API 的屬性、方法與定義規範 ►Generic Server 與主 Server 的建構與運行邏輯 ►CRD 的定義、屬性驗證及版本轉換 ►聚合 Server 的設計、實現及功能擴展 ►聚合 Server 的部署、測試與問題排查方法 ►API Server Builder 的開發步驟與應用實例 ►使用 Kubebuilder 開發與測試 Kubernetes Operator
【內容簡介】 本書分為三大部分,從基礎概念到原始碼解析,再到實戰開發,逐步帶領讀者深入了解Kubernetes的運作原理與開發實踐。第一部分聚焦基礎知識,介紹Kubernetes的控制面與節點組件、API資源與版本管理,以及API Server的核心運作機制,包括請求過濾鏈、認證控制和控制器模式等關鍵內容,並涵蓋Kubernetes社區治理與開發流程,幫助讀者掌握如何參與開源專案。第二部分深入解析Kubernetes原始碼,涵蓋API Server的架構、命令列應用的實現,並詳細講解Generic Server與主Server的建構邏輯,包括Server啟動、配置、請求處理鏈的實現及認證控制,還探索了CRD定義、Webhook應用和API擴展的實現方法,揭示Kubernetes高度可擴展性的核心技術。第三部分則著重於實戰應用,展示如何開發聚合Server和Operator,並運用API Server Builder與Kubebuilder等工具完成從專案初始化到部署測試的完整流程,結合實際案例說明設計與實現Kubernetes自定義功能的高效方法。 |
作者簡介
|
目錄
基礎篇
1 Kubernetes 與API Server 概要 ▌1.1 Kubernetes 組件 1.1.1 控制面上的組件 1.1.2 節點上的組件 ▌1.2 Kubernetes API 基本概念 1.2.1 API 和API 物件 1.2.2 API 種類 1.2.3 API 組和版本 1.2.4 API 資源 ▌1.3 API Server 1.3.1 一個Web Server 1.3.2 服務於API 1.3.3 請求過濾鏈與認證控制 ▌1.4 宣告式API 和控制器模式 1.4.1 宣告式API 1.4.2 控制器和控制器模式 ▌1.5 本章小結
2 Kubernetes 專案 ▌2.1 Kubernetes 社區治理 2.1.1 特別興趣組 2.1.2 SIG 內的子專案小組 2.1.3 工作群組 ▌2.2 開發人員如何貢獻程式 2.2.1 開發流程 2.2.2 程式提交與合併流程 ▌2.3 原始程式碼下載與編譯 2.3.1 下載 2.3.2 本地編譯與運行 ▌2.4 本章小結
原始程式篇 3 API Server ▌3.1 Kubernetes 的專案結構 3.1.1 頂層目錄 3.1.2 staging 目錄 3.1.3 pkg 目錄 ▌3.2 Cobra 3.2.1 命令的格式規範 3.2.2 用Cobra 寫命令列應用 ▌3.3 整體結構 3.3.1 子Server 3.3.2 再談聚合器 ▌3.4 API Server 的建立與啟動 3.4.1 建立Cobra 命令 3.4.2 命令的核心邏輯 3.4.3 CreateServerChain() 函數 3.4.4 總結與展望 ▌3.5 本章小結
4 Kubernetes API ▌4.1 Kubernetes API 原始程式碼 4.1.1 內部版本和外部版本 4.1.2 API 的屬性 4.1.3 API 的方法與函數 4.1.4 API 定義與實現的約定 ▌4.2 內建 API ▌4.3 核心 API ▌4.4 程式生成 4.4.1 程式生成工作原理 4.4.2 程式生成範例 4.4.3 觸發程式生成 ▌4.5 本章小結
5 Generic Server ▌5.1 Go 語言實現Web Server ▌5.2 go-restful 5.2.1 go-restful 簡介 5.2.2 go-restful 中的核心概念 5.2.3 使用go-restful ▌5.3 OpenAPI 5.3.1 什麼是OpenAPI 5.3.2 Kubernetes 使用OpenAPI 規格說明 5.3.3 生成API OpenAPI 規格說明 5.3.4 Generic Server 與OpenAPI ▌5.4 Scheme 機制 5.4.1 登錄檔的內容 5.4.2 登錄檔的建構 ▌5.5 Generic Server 的建構 5.5.1 準備Server 運行配置 5.5.2 建立Server 實例 5.5.3 建構請求處理鏈 5.5.4 增加啟動和關閉鉤子函數 ▌5.6 Generic Server 的啟動 5.6.1 啟動準備 5.6.2 啟動 ▌5.7 API 的注入與請求回應 5.7.1 注入處理流程 5.7.2 WebService 及其Route 生成過程 5.7.3 回應對Kubernetes API 的HTTP 請求 ▌5.8 認證控制機制 5.8.1 什麼是認證控制 5.8.2 認證控制器 5.8.3 動態認證控制 ▌5.9 一個HTTP 請求的處理過程 ▌5.10 本章小結
6 主Server ▌6.1 主Server 的實現 6.1.1 填充登錄檔 6.1.2 準備Server 運行配置 6.1.3 建立主Server ▌6.2 主Server 的幾個控制器 6.2.1 ReplicaSet 控制器 6.2.2 Deployment 控制器 6.2.3 StatefulSet 控制器 6.2.4 Service Account 控制器 ▌6.3 主Server 的認證控制 6.3.1 運行選項和命令列參數 6.3.2 從運行選項到運行配置 6.3.3 從運行配置到Generic Server ▌6.4 API Server 的登入驗證機制 6.4.1 API Server 登入驗證基礎 6.4.2 API Server 的登入驗證策略 6.4.3 API Server 中建構登入認證機制 ▌6.5 本章小結
7 擴充Server ▌7.1 CustomResourceDefinition 介紹 7.1.1 CRD 的屬性 7.1.2 客製化API 屬性的定義與驗證 7.1.3 啟用Status 和Scale 子資源 7.1.4 版本轉換的Webhook ▌7.2 擴充Server 的實現 7.2.1 獨立模組 7.2.2 準備Server 運行配置 7.2.3 建立擴充Server 7.2.4 啟動擴充Server ▌7.3 擴充Server 中控制器的實現 7.3.1 發現控制器 7.3.2 名稱控制器 7.3.3 非結構化規格控制器 7.3.4 API 審核控制器 7.3.5 CRD 清理控制器 ▌7.4 本章小結
8 聚合器和聚合Server ▌8.1 聚合器與聚合Server 介紹 8.1.1 背景與目的 8.1.2 再談API Server 結構 ▌8.2 聚合器的實現 8.2.1 APIService 簡介 8.2.2 準備Server 運行配置 8.2.3 建立聚合器 8.2.4 啟動聚合器 8.2.5 聚合器代理轉發HTTP 請求 ▌8.3 聚合器中控制器的實現 8.3.1 自動註冊控制器與CRD 註冊控制器 8.3.2 APIService 註冊控制器 8.3.3 APIService 狀態監測控制器 ▌8.4 聚合Server 8.4.1 最靈活的擴充方式 8.4.2 聚合Server 的結構 8.4.3 委派登入認證 8.4.4 委派許可權認證 ▌8.5 本章小結
實戰篇 9 開發聚合 Server ▌9.1 目標 ▌9.2 聚合Server 的開發 9.2.1 建立專案 9.2.2 設計API 9.2.3 生成程式 9.2.4 填充登錄檔 9.2.5 資源存取 9.2.6 撰寫認證控制 9.2.7 增加Web Server 9.2.8 部署與測試 ▌9.3 相關控制器的開發 9.3.1 設計 9.3.2 實現 9.3.3 如何啟動 9.3.4 測試 ▌9.4 本章小結
10 API Server Builder 與Kubebuilder ▌10.1 controller-runtime 10.1.1 核心概念 10.1.2 工作機制 ▌10.2 API Server Builder 10.2.1 概覽 10.2.2 Builder 用法 ▌10.3 Kubebuilder 10.3.1 概覽 10.3.2 功能 10.3.3 開發步驟 ▌10.4 本章小結
11 API Server Builder 開發聚合Server ▌11.1 目標 ▌11.2 聚合Server 的開發 11.2.1 專案初始化 11.2.2 建立v1alpha1 版API 並實現 11.2.3 增加v1 版本API 並實現 ▌11.3 相關控制器的開發 ▌11.4 部署與測試 11.4.1 準備工作 11.4.2 製作鏡像 11.4.3 向叢集提交 11.4.4 測試 ▌11.5 本章小結
12 Kubebuilder 開發Operator ▌12.1 目標 ▌12.2 定義CRD 12.2.1 專案初始化 12.2.2 增加客製化API ▌12.3 相關控制器的開發 12.3.1 實現控制器 12.3.2 本地測試控制器 ▌12.4 認證控制Webhook 的開發 12.4.1 引入認證控制Webhook 12.4.2 實現控制邏輯 ▌12.5 部署至叢集並測試 12.5.1 製作鏡像 12.5.2 部署cert-manager 12.5.3 部署並測試 ▌12.6 本章小結 |
序
為什麼寫作本書
毫無疑問,雲端平台已成為企業應用的主流支撐平臺,雲端原生作為可最大化雲端平台資源使用率的一套軟體設計原則備受業界推崇。談雲端原生就繞不開Kubernetes,它是雲端原生應用的底座:容器技術的普及加速了單體應用的微服務化,微服務化是實現雲端原生諸多原則的前提條件,而微服務化必須解決服務編排問題,Kubernetes 就是為了解決這個問題而生的。眾所皆知Kubernetes源自Google 內部產品,其前身已歷經大規模應用的實踐考驗,又有大廠做後盾,一經推出便勢如破竹,統一了容器編排領域,成為事實上的標準。從應用層面講解Kubernetes 的書籍與資料已經十分豐富,這使捲動更新、系統自動伸縮、系統自愈等曾經時髦的概念及在Kubernetes 上的配置方式現如今早已深入人心,但作為軟體工程師,不僅可得益於Kubernetes 提供的這些能力,同樣可受益於它內部實現這些能力的方式,理解其精髓可顯著提高工程師的業務水準,而這就鮮有除原始程式之外的優秀資料了,本書希望在一定程度上彌補這方面的缺憾。筆者選取Kubernetes 的核心元件——API Server 進行原始程式碼講解,從程式等級拆解控制器模式、認證控制機制、登入鑑權機制、API Server 聚合機制等,力爭涵蓋API Server 所有核心邏輯。為了緩解理解原始程式的枯燥感,筆者增加數章擴充開發的實踐內容,也使學習與應用相輔相成。 帶領讀者體驗Go 語言魅力是寫作本書的另一個目的。 Go 語言誕生於2007 年,靈感來自一場C++ 新特性佈道會議中發生的討論,現如今已經走過17 個年頭。Go 語言的創立者大名鼎鼎,一位是C 語言建立者Ken Thompson,另一位是UNIX 的開發者Rob Pike,可以說Go 語言的起點相當高。這門新語言確實不辱使命,主流的容器引擎均是用Go 語言開發的,Kubernetes 作為容器編排的事實標準也使用Go 語言開發,單憑這兩項成就就足以證明其價值。 Go 語言在伺服器端應用程式開發、命令列工具程式開發等領域應用越來越廣,作為開發語言界的後起之秀,Go 語言具有後發優勢。以Go 語言開發的應用被編譯為目標平臺的本地應用,所以在效率上相對依賴虛擬機器的應用有優勢;它在語法上比C 語言簡單,記憶體管理也更出眾,具有好用性,而相對C++,Go 語言更簡單,使用者也不用操心指標帶來的安全問題。如果只看語法,則Go 語言是相對簡單的一門程式語言。若有C 語言基礎,則上手速度幾乎可以用小時計,但要充分發揮Go 語言的強悍能力則需對其有較為深入的理解和實踐。為了幫助開發者更進一步地使用它,Go 語言團隊撰寫了Effective Go 一文,舉出諸多使用的最佳實踐,這些最佳實踐在Kubernetes 的原始程式中被廣泛應用,這就使學習Kubernetes 原始程式成為提升Go 語言能力的一條路徑。
目標讀者 本書內容圍繞Kubernetes API Server 原始程式碼展開,力圖型分析清楚它的設計想法,其內容可以幫助以下幾類讀者。 1. 希望提升系統設計能力的開發者 他山之石,可以攻錯。 入門軟體開發並非難事,但要成為高階人才去主導大型系統設計卻實屬不易。優秀架構師在能夠遊刃有餘地揮灑創意之前均進行了常年累積。除了不斷更新技術知識、學習經典設計理論、在實踐中不斷摸索外,從成功專案中汲取養料也是常用的進階之道。Kubernetes 專案足夠成功,其社區成員已是百萬計。它聚數十萬優秀軟體開發人員之力於一點,每個原始檔案、每個函數均經過認真思考與審核,其中考量耐人尋味。從原始程式分碼析Kubernetes 的設計正是本書的立足點。 API Server 所應用的諸多設計實現為開發者提供了有益參考。例如控制器模式、認證控制機制、各種Webhook 機制、登入認證策略、請求過濾的實現、OpenAPI 服務說明的生成、Go 程式生成機制、以Generic Server 為底座的子Server 建構方式等。上述每項設計想法均可應用到其他專案,特別是用Go 語言開發的專案中。 本書中包含大量原始程式碼的講解,需要讀者具有基本的Go 語言語法知識;同時,當涉及Kubernetes 的基本概念和操作時本書不會深入講解,故需要讀者具備Kubernetes 的基礎知識。不過讀者閱讀本書前不必成為這些方面的專家。 2. Kubernetes 運行維護團隊成員、擴充開發人員 知其然且知其所以然始終是做好軟體運行維護工作的有力保證。了解Kubernetes 功能的具體實現可讓運行維護人員對系統能力有更深刻的認識,提升對潛在問題的預判能力,對已出現的故障迅速定位。相較於軟體開發工程師,運行維護工程師一般不具備很強的開發能力,所以探究原始程式會比較吃力。本書有條理地帶領讀者厘清API Server 各個組件的設計,降低了原始程式閱讀的門檻。 筆者始終認為Kubernetes 最強的一面恰恰是它最被忽視的高擴充能力。根據公開報導,科技大廠(如Google、AWS、微軟、字節跳動等)均有利用這些擴充能力做適合自身平臺的客製化。目前講解API Server 客製化的資料並不系統。本書希望將API Server 的客製化途徑講解清楚:既介紹擴充機制的原始程式碼實現,又講解如何利用擴充機制進行客製化開發,希望為擴充開發人員提供相應參考。 3. 希望提升Kubernetes 知識水準的從業者 由表及裡是領會任何技術的自然過程。隨著最近三年線上辦公的火爆,雲端平台的普及大大加速,Kubernetes 作為雲端應用的重要支撐工具已被廣泛應用,一批優秀的系統管理員在成長過程中開始產生深入了解Kubernetes 功能背後原理的需求。拿眾所皆知的捲動更新機制舉例,透過文件可以了解到其幾個參數的含義,但很拗口,並且難記,有不明就裡的感覺,但透過查看Deployment控制器原始程式碼,將這些參數映射到程式的幾個判斷敘述後,一切也就簡單明朗了。 4. Go 語言的使用者 Go 語言的使用者完全可以利用Kubernetes 專案來快速提升自己的專案能力。作為Kubernetes 中最核心也是最複雜的元件,API Server 的原始程式充分表現了Go 語言的多種最佳實踐。讀者會看到管道(channel)如何編織出複雜的Server 狀態轉換網,會看到優雅應用程式碼協同(Go Routine)的方式,也會學習到如何利用函數物件,以及諸多技術的應用方式。透過閱讀API Server 原始程式來提升自身Go 語言水準一舉多得。 5. 期望了解開放原始碼專案的開發者 開放原始碼在過去30 年裡極大地加速了軟體行業的繁榮,在主要的應用領域開放原始碼產品有著頂樑柱的作用,例如Linux、Android、Kubernetes、Cloud Foundry、Eclipse、PostgreSQL 等。軟體開放原始碼早已超出程式共用的範圍,成為一種無私、共同進步的精神象徵。許多軟體從業者以參與開放原始碼專案為榮。 本書在介紹原始程式的同時也展示了Kubernetes 的社區治理,讀者會看到這樣一個百萬人等級的社區角色如何設定,任務怎麼劃分,程式提交流程,品質保證手段。透過這些簡介,讀者可以獲得對開放原始碼專案管理的基礎,為參與其中打下基礎。如果聚焦API Server 這一較小領域,則讀者在本書的幫助下將掌握專案結構和核心程式邏輯,輔以一定量的自我學習便可參與其中。
致謝 特別感謝讀者花時間閱讀本書。本書的撰寫歷經坎坷。準備工作從2022 年便已開始,為了保證嚴謹,筆者翻閱了API Server 的所有原始檔案,讓每個基礎知識都能落實到程式並經得起推敲。寫作則貫穿2023 年一整年,這幾乎佔去了筆者工作之餘、教育兒女之外的所有閒置時間。筆者水準有限,書中仍有可能存在疏漏之處,期望讀者能給予諒解並不吝指正,感激不盡! 筆者深知如果沒有外部的幫助,則很難走到出版這一步,在此感謝所有人的付出。 首先特別感恩筆者所在公司和團隊所提供的機會,讓筆者在過去的多年裡有機會接觸雲端與Kubernetes,並能有深挖的時間。2023 年筆者團隊痛失棟樑,困難時刻團隊成員勇於擔當,共渡難關,讓這本書的寫作得以繼續。謹以此書紀念那位已逝去的同事。 其次感謝家人的付出,作為兩個孩子的父親,沒有家人的分擔是無法從照顧孩子的重任中分出時間寫作的,這本書的問世得益於你們的支援。 感謝清華大學出版社趙佳霓編輯,謝謝您在寫作前的提點、審核協助及校稿過程中的辛勤付出。 張海龍 |