Kubernetes 提供豐富的擴充套件機制,允許開發者根據自身需求調整和擴充叢集功能。本文將探討 Kubernetes 的生命週期擴充套件、動態准入控制以及自定義 API 資源的實作方式和應用場景。透過 Webhook 技術,我們可以將自定義邏輯注入 Kubernetes 的生命週期事件中,例如在 Pod 建立時進行驗證。准入控制器則扮演著守門員的角色,確保只有符合特定條件的請求才能被 Kubernetes 接受。此外,Kubernetes 還支援自定義資源定義(CRD),讓開發者能夠定義新的資源型別,並透過 Operator 模式實作更複雜的應用程式管理。這些擴充套件機制共同構成了 Kubernetes 強大的擴充套件體系,使其能夠適應各種不同的應用場景。
Kubernetes 擴充套件:自定義生命週期與 API 擴充
Kubernetes 提供多種擴充套件機制,讓使用者能夠根據特定需求調整叢集功能。這些擴充套件包括自定義生命週期管理、動態准入控制(Admission Controller)以及新增自定義 API 資源。本文將探討這些擴充套件技術的實作方法、操作考量和實際應用案例。
生命週期擴充套件的操作考量
在擴充套件 Kubernetes 生命週期時,需要考慮兩大操作複雜性:
Webhook 處理服務的執行:根據 Webhook 處理器的佈署位置(雲端 FaaS、叢集內 FaaS 或自建 Web 服務),操作負責人需監控其應用層可靠性,避免傳回 500 錯誤。
自定義程式碼注入 API 伺服器關鍵路徑:若自定義准入控制器出現當機或傳回 500 錯誤,將導致所有相關 API 請求失敗,嚴重影響叢集運作。因此,需謹慎監控並規劃,以避免未預期的後果。
實作:准入控制器的 JavaScript 範例
以下是一個簡單的 JavaScript 服務,用於實作 Pod 的准入控制:
const http = require('http');
const isValid = (pod) => {
// 在此實作 Pod 驗證邏輯
};
const server = http.createServer((request, response) => {
var json = '';
request.on('data', (data) => {
json += data;
});
request.on('end', () => {
var admissionReview = JSON.parse(json);
var pod = admissionReview.request.object;
var review = {
kind: 'AdmissionReview',
apiVersion: 'admission/v1beta1',
response: {
allowed: isValid(pod)
}
};
response.end(JSON.stringify(review));
});
});
server.listen(8080, (err) => {
if (err) {
return console.log('准入控制器啟動失敗', err);
}
console.log('准入控制器已啟動並執行。');
});
程式碼解析:
建立 HTTP 伺服器:使用 Node.js 的
http模組建立一個 HTTP 伺服器,監聽 8080 連線埠。處理 AdmissionReview 請求:伺服器接收到 HTTP POST 請求後,解析 JSON 內容,提取 Pod 物件並進行驗證。
回傳驗證結果:根據
isValid函式的驗證結果,建構AdmissionReview回應物件,並將結果以 JSON 格式回傳。
向 Kubernetes 註冊動態准入控制器
要註冊上述准入控制器,需建立 ValidatingWebhookConfiguration 物件:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: my-admission-controller
webhooks:
- name: my-web-hook
rules:
# 為 v1/pod 的建立操作註冊
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
clientConfig:
service:
# 將請求傳送到 kube-system 名稱空間中的 'my-admission-controller-service' 服務
namespace: kube-system
name: my-admission-controller-service
設定解析:
註冊 Webhook:指定 Webhook 名稱及適用規則(例如,對
v1/pod資源的CREATE操作進行准入控制)。服務組態:指定處理 Webhook 請求的 Kubernetes 服務名稱及名稱空間。
新增自定義 API 至 Kubernetes
除了擴充套件現有 API,Kubernetes 還允許新增完全自定義的 API 資源型別。這使得使用者能夠在叢集中引入新的功能和物件,而無需修改核心 Kubernetes 程式碼。
自定義 API 的應用場景
自定義 API 可用於多種場景,例如為在 Kubernetes 上執行的 FaaS(Function as a Service)平台新增函式管理 API。這樣不僅能利用 Kubernetes 現有的授權、認證和錯誤處理機制,還能使新功能無縫整合至現有的 Kubernetes 生態系統中。
Kubernetes 自定義資源擴充套件
Kubernetes 的自定義資源擴充套件(API Extensions)為使用者提供了彈性地擴充叢集功能的方式。在許多情況下,使用者甚至不會注意到他們正在使用 API 擴充套件。另一個流行的使用案例是 CoreOS 推廣的 Operator 模式。透過 Operator,一個新的 API 物件被引入叢集,以代表某個軟體的操作者(例如資料函式倉管理員)。當使用者建立一個新的 MySQLDatabase 物件時,Operator 會使用這個 API 物件來例項化一個新的 MySQL 資料函式庫,包括適當的監控和線上監督,以自動保持資料函式庫正確執行。
自定義資源定義和聚合 API 伺服器
由於 API 的生命週期和擴充套件過程在技術上很複雜,Kubernetes 實際上實作了兩種不同的機制來向 Kubernetes API 新增新型別。第一種是自定義資源定義(CustomResourceDefinitions),它涉及使用 Kubernetes API 本身來向 Kubernetes 新增新型別。所有的儲存和 API 服務都與新的自定義型別相關聯,由 Kubernetes 本身處理。因此,自定義資源定義是擴充套件 Kubernetes API 伺服器最簡單的方法。然而,由於 Kubernetes 處理所有的擴充套件性,這些 API 存在一些限制。例如,很難對透過自定義資源定義新增的 API 進行驗證和預設;然而,可以透過將自定義資源定義與自定義准入控制器結合來實作這一點。
自定義資源定義的架構
實作自定義資源定義有幾個不同的步驟。首先是建立 CustomResourceDefinition 物件本身。自定義資源是具有新型別定義的內建 Kubernetes 物件。在建立 CustomResourceDefinition 之後,Kubernetes API 伺服器會在 API 網頁伺服器中程式設計一個新的 API 群組和資源路徑,以及新的處理程式,它們知道如何從 Kubernetes 儲存中序列化(serialize)和反序列化(deserialize)這些新的自定義資源。如果您只想要一個簡單的 CRUD(建立、讀取、更新、刪除)API,這可能就足夠了。但在大多數情況下,您希望在使用者建立新的自定義物件例項時實際執行某些操作。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mydatabases.stable.example.com
spec:
group: stable.example.com
versions:
v1
scope: Namespaced
names:
plural: mydatabases
singular: mydatabase
kind: MyDatabase
shortNames:
- md
內容解密:
apiVersion和kind定義了這個物件是 Kubernetes 的CustomResourceDefinition。metadata.name指定了自定義資源定義的名稱。spec.group和spec.versions定義了這個自定義資源的 API 群組和版本。spec.scope指定了這個自定義資源是名稱空間範圍還是叢集範圍。spec.names定義了這個自定義資源的複數、單數、類別和縮寫名稱。
安裝自定義資源定義
與所有擴充套件一樣,管理這些自定義資源所需的程式碼都在 Kubernetes 叢集本身上執行。自定義資源控制器被封裝為容器映像,並使用 Kubernetes API 物件安裝在叢集上。由於自定義資源是一種更複雜的擴充套件,一般來說,Kubernetes 組態由多個物件組成,封裝成一個單獨的 YAML 檔案。在許多情況下,這些檔案可以從提供擴充套件的開源專案或軟體供應商獲得。或者,它們可以透過套件管理器(如 Helm)安裝。與所有其他擴充套件一樣,自定義資源 API 擴充套件的監控、維護和刪除都使用 Kubernetes API 進行。
自定義資源的操作考慮
自定義資源的操作考慮通常與其他擴充套件相同。您正在向叢集新增一個應用程式,使用者將依賴它,並且需要對其進行監控和管理。此外,如果您的擴充套件還使用准入控制器,則同樣適用於准入控制器的操作問題。然而,除了前面描述的複雜性之外,自定義資源定義還有額外的複雜性——它們使用與所有內建 Kubernetes API 物件相關聯的相同儲存。因此,透過在 API 伺服器中使用自定義資源儲存過大和/或過多的物件,可能會影響您的 API 伺服器和叢集操作。
Kubernetes 的設計原則與核心元件
Kubernetes 的設計遵循 Unix 的模組化哲學,強調 API 驅動的互動。核心元件包括:
API 伺服器
- 負責處理 API 請求,是叢集的入口點。
- 管理 API 的存取、發現和擴充。
etcd
- 用於儲存叢集的所有狀態資訊。
- 需要定期備份以確保叢集的可靠性。
控制器管理器
- 負責執行各種控制器,如副本控制器、節點控制器等。
- 確保叢集的期望狀態與實際狀態一致。
排程器
- 負責將 Pod 分配到合適的節點上。
- 根據資源需求、親和性等策略進行排程。
Kubernetes 的擴充與客製化
Kubernetes 提供了多種擴充機制,包括:
自定義資源定義(CRDs):允許使用者定義自己的資源型別。
- 安裝與操作考量:
- 需要正確組態 CRD 的架構。
- 確保控制迴圈的正確實作。
- 安裝與操作考量:
聚合 API 伺服器:允許使用者擴充 Kubernetes API。
- 使用案例:
- 為特定應用程式提供自定義 API。
- 與現有的 Kubernetes 工具鏈整合。
- 使用案例:
叢集助手與叢集守護程式:用於擴充叢集功能。
- 叢集助手:提供額外的管理功能,如自動化任務。
- 叢集守護程式:執行在每個節點上,提供特定的服務。
安全與存取控制
Kubernetes 提供了多種安全機制,包括:
認證(Authentication):
- 使用 X.509 使用者端憑證、靜態 Token、OIDC Token 等方法進行認證。
- 組態
kubeconfig檔案以管理認證資訊。
授權(Authorization):
- 使用 RBAC(Role-Based Access Control)進行細粒度的存取控制。
- 定義 Role 和 ClusterRole 以控制資源的存取許可權。
准入控制(Admission Control):
- 使用動態准入控制器進行請求驗證和修改。
- 組態
ValidatingAdmissionWebhook和MutatingAdmissionWebhook以實作自定義邏輯。
監控與日誌管理
Kubernetes 提供了多種監控和日誌管理工具,包括:
監控工具:
- 使用 Prometheus 和 Grafana 進行叢集監控。
- 組態
ServiceMonitor和PodMonitor以收集指標資料。
日誌管理:
- 使用 Fluentd 和 Elasticsearch 進行日誌收集和分析。
- 組態
DaemonSet以在每個節點上執行日誌代理。
災難復原與高用性
Kubernetes 提供了多種機制來確保叢集的高用性和災難復原能力,包括:
etcd 備份:
- 定期備份 etcd 資料以防止資料遺失。
- 使用 Ark 等工具進行備份和還原。
應用資料復原:
- 使用持久化儲存(如 Persistent Volumes)來儲存應用資料。
- 組態備份和還原策略以確保資料的安全性。
Kubernetes 系統架構與核心元件深入解析
Kubernetes 架構設計理念
Kubernetes 的設計核心建立在多年的容器協調經驗與技術累積之上,其架構設計融合了多項重要的系統設計原則。首先,Kubernetes 採用微服務架構,將系統功能模組化,每個元件負責特定的任務,這種設計方式大大提高了系統的可擴充套件性和維護性。
設計概念與原則
宣告式組態(Declarative Configuration)
Kubernetes 採用宣告式組態而非命令式組態,使用者只需定義系統的期望狀態,Kubernetes 便會自動調整以達到該狀態。這種設計極大地簡化了系統管理,降低了操作複雜度。模組化與可擴充套件性
Kubernetes 的元件設計遵循 Unix 哲學中的模組化原則,各元件之間鬆耦合,便於獨立開發與維護。同時,Kubernetes 提供了多種擴充套件機制,如自定義資源(Custom Resources)和動態准入控制器(Dynamic Admission Controllers),允許使用者根據需求對系統進行擴充套件和定製。狀態協調(Reconciliation Loops)
Kubernetes 的核心控制迴路不斷檢測系統的當前狀態與期望狀態之間的差異,並採取相應的調節措施,使系統趨向期望狀態。這種機制確保了系統的穩定性和一致性。
Kubernetes 核心元件解析
Kubernetes 的架構由多個關鍵元件組成,這些元件共同協作以實作容器的排程、執行和管理。
API 伺服器(API Server)
API 伺服器是 Kubernetes 的核心元件之一,負責處理所有的 API 請求。它提供了 RESTful 風格的介面,用於管理 Kubernetes 資源,如 Pod、Service 和 Deployment 等。API 伺服器還負責請求的驗證、授權和處理,是整個叢集的控制平面入口。
排程器(Scheduler)
排程器負責根據資源需求、策略約束等因素,將新建立的 Pod 排程到合適的節點上執行。排程器透過預選和優選兩個階段,選擇最優的節點來執行 Pod。使用者還可以自定義排程策略,以滿足特定的應用需求。
控制器管理器(Controller Manager)
控制器管理器執行多個控制器程式,這些控制器負責維護叢集的期望狀態。例如,ReplicaSet 控制器確保指定數量的 Pod 副本正在執行;Deployment 控制器管理應用程式的滾動更新和回復操作。
kubelet 與容器執行時
kubelet 是執行在每個節點上的代理程式,負責管理節點上的容器執行時,如 Docker 或 containerd。kubelet 與 API 伺服器通訊,取得 Pod 的組態資訊,並確保容器按照預期執行。
網路與服務發現
Kubernetes 的網路模型根據扁平化的網路結構,要求每個 Pod 都能與其他 Pod 直接通訊,無需 NAT。為了實作這一目標,Kubernetes 支援多種網路外掛,如 Calico、Flannel 和 Cilium 等。
服務發現機制
Kubernetes 提供了多種服務發現機制,包括 DNS 和環境變數。Service 資源透過 DNS 或環境變數的方式,將服務名稱解析為具體的 IP 地址,方便應用程式之間的通訊。
儲存管理
Kubernetes 支援多種儲存型別,包括持久性儲存區(Persistent Volumes, PV)、儲存類別(Storage Classes)等。這些儲存資源可以動態地分配給 Pod 使用,確保資料的永續性和可靠性。
安全與認證授權
Kubernetes 提供了完善的安全機制,包括認證、授權和准入控制等。使用者可以透過 X.509 證書、靜態 Token 或 OIDC 等方式進行身分驗證。同時,Kubernetes 支援根據角色的存取控制(RBAC),允許管理員精細地控制使用者對資源的存取許可權。
監控與日誌管理
有效的監控和日誌管理對於維護 Kubernetes 叢集的穩定執行至關重要。Kubernetes 支援 Prometheus、Grafana 等監控工具,用於收集叢集和應用的效能指標。同時,透過 Fluentd、ELK Stack 等工具,可以對叢集日誌進行集中收集和分析。
災難還原與備份
為了確保業務連續性,Kubernetes 叢集需要具備災難還原能力。使用者可以透過定期的快照備份、ETCD 資料備份等方式,保護叢集資料的安全。此外,還可以結合 Velero 等工具,實作叢集級別的備份與還原。
作者簡介
Brendan Burns 是 Kubernetes 開源容器管理平台的共同創始人,目前在微軟擔任傑出工程師,負責 Azure Resource Manager 和 Azure Container Service 團隊。在加入微軟之前,他是 Google Cloud Platform 的高階員工工程師。在從事雲端工作之前,他開發了協助 Google 搜尋引擎的網頁搜尋後端系統。他曾在紐約 Schenectady 的 Union College 擔任電腦科學教授。Brendan 在麻省大學阿默斯特分校獲得電腦科學博士學位,並在 Williams College 獲得學士學位。
Craig Tracey 在過去的 20 年中一直致力於建立推動網際網路運作的基礎設施。在此期間,他開發了從核心裝置驅動程式到大規模雲端儲存服務,甚至是一些分散式運算平台。如今,作為 Heptio 的軟體工程師轉型為現場工程師,Craig 透過程式碼教學,幫助組織加速採用 Kubernetes,並教授雲端原生架構的原理。
Craig 目前居住在麻薩諸塞州波士頓,閒暇時喜歡打冰球,並熱衷於探索歐洲。Craig 在普羅維登斯學院獲得電腦科學學士學位。
書籍封面動物
《Managing Kubernetes》一書的封面動物是紫色海盤車(Uraster violacea)。這種海星主要分佈在大不列顛的海岸邊,其顏色多變,從鮮橙色到深紅色不等,並帶有藍色斑點,這些斑點朝向末端與較暖的顏色融合,形成絢麗的紫色。一般觀察到的紫色海盤車長度約為四到五英寸,與常見的海星一樣,它們具有廣泛的雜食性飲食,包括海藻、海綿、蝸牛、雙殼貝類別和其他小型植物與生物。
封面圖片來自 Edward Forbes 的《A History of British Starfish and other Animals of the Class Echinodermata》。封面字型分別為 URW Typewriter 和 Guardian Sans,正文字型是 Adobe Minion Pro,標題字型是 Adobe Myriad Condensed,而程式碼字型則是 Dalton Maag 的 Ubuntu Mono。