自訂資源

自訂資源 是 Kubernetes API 的擴充功能。本頁討論何時將自訂資源新增至您的 Kubernetes 叢集,以及何時使用獨立服務。它描述了新增自訂資源的兩種方法,以及如何在它們之間做出選擇。

自訂資源

資源Kubernetes API 中的端點,用於儲存特定種類的 API 物件的集合;例如,內建的 pods 資源包含 Pod 物件的集合。

自訂資源 是 Kubernetes API 的擴充功能,不一定在預設 Kubernetes 安裝中提供。它代表特定 Kubernetes 安裝的自訂。然而,現在許多核心 Kubernetes 功能是使用自訂資源建置的,這使得 Kubernetes 更加模組化。

自訂資源可以透過動態註冊在執行中的叢集中出現和消失,而叢集管理員可以獨立於叢集本身來更新自訂資源。一旦安裝了自訂資源,使用者就可以使用 kubectl 建立和存取其物件,就像他們對內建資源(如 Pods)所做的那樣。

自訂控制器

單獨來看,自訂資源可讓您儲存和檢索結構化資料。當您將自訂資源與自訂控制器結合使用時,自訂資源會提供真正的宣告式 API

Kubernetes 宣告式 API 強制執行職責分離。您宣告資源的期望狀態。Kubernetes 控制器使 Kubernetes 物件的目前狀態與您宣告的期望狀態保持同步。這與命令式 API 相反,在命令式 API 中,您指示伺服器執行什麼操作。

您可以在執行中的叢集上部署和更新自訂控制器,而與叢集的生命週期無關。自訂控制器可以與任何種類的資源一起使用,但當與自訂資源結合使用時尤其有效。Operator 模式 結合了自訂資源和自訂控制器。您可以使用自訂控制器將特定應用程式的領域知識編碼到 Kubernetes API 的擴充功能中。

我應該將自訂資源新增到我的 Kubernetes 叢集中嗎?

在建立新的 API 時,請考慮是否要將您的 API 與 Kubernetes 叢集 API 聚合,還是讓您的 API 獨立運作。

如果符合以下情況,請考慮 API 聚合如果符合以下情況,則偏好獨立 API
您的 API 是宣告式的。您的 API 不符合宣告式模型。
您希望可以使用 kubectl 讀取和寫入新的類型。不需要 kubectl 支援
您希望在 Kubernetes UI(例如儀表板)中,與內建類型一起檢視新的類型。不需要 Kubernetes UI 支援。
您正在開發新的 API。您已經有一個程式可以提供您的 API 並且運作良好。
您願意接受 Kubernetes 對 REST 資源路徑施加的格式限制,例如 API 群組和命名空間。(請參閱 API 概述。)您需要有特定的 REST 路徑才能與已定義的 REST API 相容。
您的資源自然地限定於叢集或叢集的命名空間。叢集或命名空間範圍的資源不太適合;您需要控制資源路徑的細節。
您想要重複使用Kubernetes API 支援功能您不需要這些功能。

宣告式 API

在宣告式 API 中,通常

  • 您的 API 由相對少量的相對小的物件(資源)組成。
  • 這些物件定義應用程式或基礎架構的組態。
  • 物件更新的頻率相對較低。
  • 人類通常需要讀取和寫入物件。
  • 物件的主要操作是 CRUD 式的(建立、讀取、更新和刪除)。
  • 不需要跨物件的事務:API 代表期望狀態,而不是確切狀態。

命令式 API 不是宣告式的。您的 API 可能不是宣告式的跡象包括

  • 用戶端說「執行此操作」,然後在完成時收到同步回應。
  • 用戶端說「執行此操作」,然後收到操作 ID,並且必須檢查單獨的操作物件以確定請求是否完成。
  • 您談論遠端程序呼叫 (RPC)。
  • 直接儲存大量資料;例如,每個物件 > 幾 kB,或 > 數千個物件。
  • 需要高頻寬存取(持續每秒 10 個請求)。
  • 儲存終端使用者資料(例如影像、PII 等)或應用程式處理的其他大規模資料。
  • 物件的自然操作不是 CRUD 式的。
  • API 不容易建模為物件。
  • 您選擇使用操作 ID 或操作物件來表示待處理的操作。

我應該使用 ConfigMap 還是自訂資源?

如果符合以下任何一項,請使用 ConfigMap

  • 存在現有的、文件完善的組態檔格式,例如 mysql.cnfpom.xml
  • 您想要將整個組態放入 ConfigMap 的一個鍵中。
  • 組態檔的主要用途是讓在叢集上的 Pod 中執行的程式取用該檔案以配置自身。
  • 檔案的消費者偏好透過 Pod 中的檔案或 Pod 中的環境變數來取用,而不是透過 Kubernetes API。
  • 當檔案更新時,您想要透過 Deployment 等執行滾動更新。

如果以下大多數情況適用,請使用自訂資源(CRD 或 Aggregated API)

  • 您想要使用 Kubernetes 用戶端程式庫和 CLI 來建立和更新新的資源。
  • 您想要來自 kubectl 的頂層支援;例如,kubectl get my-object object-name
  • 您想要建立新的自動化,以監看新物件的更新,然後 CRUD 其他物件,或反之亦然。
  • 您想要編寫自動化來處理物件的更新。
  • 您想要使用 Kubernetes API 慣例,例如 .spec.status.metadata
  • 您希望物件是對受控資源集合的抽象,或是其他資源的摘要。

新增自訂資源

Kubernetes 提供兩種將自訂資源新增到叢集的方法

  • CRD 很簡單,無需任何程式設計即可建立。
  • API 聚合 需要程式設計,但允許對 API 行為進行更多控制,例如資料的儲存方式以及 API 版本之間的轉換。

Kubernetes 提供這兩個選項來滿足不同使用者的需求,以便易用性和彈性都不會受到影響。

聚合 API 是位於主要 API 伺服器後面的從屬 API 伺服器,主要 API 伺服器充當代理。這種安排稱為 API 聚合 (AA)。對於使用者來說,Kubernetes API 似乎已擴充。

CRD 允許使用者建立新的資源類型,而無需新增另一個 API 伺服器。您不需要了解 API 聚合即可使用 CRD。

無論它們是如何安裝的,新的資源都被稱為自訂資源,以區別於內建的 Kubernetes 資源(如 Pod)。

CustomResourceDefinitions

CustomResourceDefinition API 資源允許您定義自訂資源。定義 CRD 物件會建立一個新的自訂資源,其中包含您指定的名稱和綱要。Kubernetes API 服務並處理自訂資源的儲存。CRD 物件本身的名稱必須是有效的 DNS 子網域名稱,該名稱衍生自定義的資源名稱及其 API 群組;請參閱如何建立 CRD 以取得更多詳細資訊。此外,種類/資源由 CRD 定義的物件名稱也必須是有效的 DNS 子網域名稱。

這使您無需編寫自己的 API 伺服器來處理自訂資源,但實作的通用性意味著您的彈性不如API 伺服器聚合

請參閱 自訂控制器範例,以了解如何註冊新的自訂資源、使用新資源類型的執行個體,以及使用控制器來處理事件的範例。

API 伺服器聚合

通常,Kubernetes API 中的每個資源都需要程式碼來處理 REST 請求並管理物件的持久儲存。主要的 Kubernetes API 伺服器處理內建資源,例如 podservice,也可以透過 CRD 通用地處理自訂資源。

聚合層 允許您透過編寫和部署自己的 API 伺服器,為自訂資源提供特殊化的實作。主要 API 伺服器將針對您處理的自訂資源的請求委派給您的 API 伺服器,使其可供所有用戶端使用。

選擇新增自訂資源的方法

CRD 更易於使用。聚合 API 更具彈性。選擇最符合您需求的方法。

通常,如果符合以下情況,CRD 是不錯的選擇

  • 您只有少數欄位
  • 您在公司內部使用該資源,或作為小型開放原始碼專案的一部分(而不是商業產品)

比較易用性

CRD 比聚合 API 更容易建立。

CRD聚合 API
不需要程式設計。使用者可以為 CRD 控制器選擇任何語言。需要程式設計以及建置二進位檔和映像檔。
無需執行額外服務;CRD 由 API 伺服器處理。需要建立且可能失敗的額外服務。
建立 CRD 後無需持續支援。任何錯誤修正都會作為正常 Kubernetes Master 升級的一部分進行擷取。可能需要定期從上游擷取錯誤修正,並重建和更新聚合 API 伺服器。
無需處理 API 的多個版本;例如,當您控制此資源的用戶端時,您可以使其與 API 同步升級。您需要處理 API 的多個版本;例如,當開發要與世界分享的擴充功能時。

進階功能和彈性

聚合 API 提供更進階的 API 功能以及其他功能的自訂,例如,儲存層。

功能描述CRD聚合 API
驗證協助使用者防止錯誤,並允許您獨立於用戶端來發展 API。當有許多無法同時更新的用戶端時,這些功能最有用。是。大多數驗證可以使用 OpenAPI v3.0 驗證在 CRD 中指定。CRDValidationRatcheting 功能閘道允許忽略使用 OpenAPI 指定的失敗驗證(如果資源的失敗部分未變更)。任何其他驗證都透過新增 Validating Webhook 來支援。是,任意驗證檢查
預設值請參閱上方是,可以透過 OpenAPI v3.0 驗證 default 關鍵字(1.17 版中為 GA),或透過 Mutating Webhook(雖然這在從 etcd 讀取舊物件時不會執行)。
多版本允許透過兩個 API 版本提供相同的物件。可以幫助簡化 API 變更,例如重新命名欄位。如果您控制用戶端版本,則不太重要。
自訂儲存如果您需要具有不同效能模式的儲存(例如,時間序列資料庫而不是鍵值儲存)或用於安全性的隔離(例如,敏感資訊的加密等)
自訂業務邏輯在建立、讀取、更新或刪除物件時執行任意檢查或動作是,使用 Webhooks
Scale 子資源允許 HorizontalPodAutoscaler 和 PodDisruptionBudget 等系統與您的新資源互動
Status 子資源允許細緻的存取控制,使用者寫入 spec 區段,而控制器寫入 status 區段。允許在自訂資源資料變更時遞增物件 Generation(需要在資源中具有單獨的 spec 和 status 區段)
其他子資源新增 CRUD 以外的操作,例如「logs」或「exec」。
strategic-merge-patch新的端點支援使用 Content-Type: application/strategic-merge-patch+json 的 PATCH。適用於更新可能在本地和伺服器端都修改過的物件。如需更多資訊,請參閱「使用 kubectl patch 就地更新 API 物件」
Protocol Buffers新的資源支援想要使用 Protocol Buffers 的用戶端
OpenAPI 綱要是否有 OpenAPI (swagger) 綱要可用於可以從伺服器動態擷取的類型?是否透過確保僅設定允許的欄位來保護使用者免於拼錯欄位名稱?是否強制執行類型(換句話說,不要將 int 放入 string 欄位?)是,基於 OpenAPI v3.0 驗證 綱要(1.16 版中為 GA)。
執行個體名稱此擴充機制是否對以此方式定義的種類/資源的物件名稱施加任何限制?是,此類物件的名稱必須是有效的 DNS 子網域名稱。

通用功能

當您建立自訂資源時,無論是透過 CRD 還是 AA,與在 Kubernetes 平台外部實作相比,您都可以獲得 API 的許多功能

功能功能
CRUD新的端點透過 HTTP 和 kubectl 支援 CRUD 基本操作
Watch新的端點透過 HTTP 支援 Kubernetes Watch 操作
探索kubectl 和儀表板等用戶端會自動在您的資源上提供清單、顯示和欄位編輯操作
json-patch新的端點支援使用 Content-Type: application/json-patch+json 的 PATCH
merge-patch新的端點支援使用 Content-Type: application/merge-patch+json 的 PATCH
HTTPS新的端點使用 HTTPS
內建身份驗證對擴充功能的存取使用核心 API 伺服器(聚合層)進行身份驗證
內建授權對擴充功能的存取可以重複使用核心 API 伺服器使用的授權;例如,RBAC。
Finalizers封鎖擴充資源的刪除,直到外部清理完成。
Admission Webhooks在任何建立/更新/刪除操作期間,設定預設值並驗證擴充資源。
UI/CLI 顯示Kubectl、儀表板可以顯示擴充資源。
未設定與空值用戶端可以區分未設定的欄位和零值的欄位。
用戶端程式庫產生Kubernetes 提供通用用戶端程式庫,以及產生特定類型用戶端程式庫的工具。
標籤和註解跨物件的通用中繼資料,工具知道如何為核心和自訂資源編輯這些中繼資料。

準備安裝自訂資源

在將自訂資源新增到叢集之前,需要注意以下幾點。

第三方程式碼和新的故障點

雖然建立 CRD 不會自動新增任何新的故障點(例如,透過導致第三方程式碼在您的 API 伺服器上執行),但套件(例如 Charts)或其他安裝套件通常包含 CRD 以及實作新自訂資源業務邏輯的第三方程式碼的 Deployment。

安裝聚合 API 伺服器始終涉及執行新的 Deployment。

儲存

自訂資源消耗儲存空間的方式與 ConfigMap 相同。建立過多的自訂資源可能會使 API 伺服器的儲存空間過載。

聚合 API 伺服器可能使用與主要 API 伺服器相同的儲存,在這種情況下,相同的警告適用。

身份驗證、授權和稽核

CRD 始終使用與 API 伺服器的內建資源相同的身份驗證、授權和稽核日誌記錄。

如果您使用 RBAC 進行授權,則大多數 RBAC 角色將不會授予對新資源的存取權(叢集管理員角色或使用萬用字元規則建立的任何角色除外)。您需要明確授予對新資源的存取權。CRD 和聚合 API 通常與它們新增的類型的新角色定義捆綁在一起。

聚合 API 伺服器可能會或可能不會使用與主要 API 伺服器相同的身份驗證、授權和稽核。

存取自訂資源

Kubernetes 用戶端程式庫可用於存取自訂資源。並非所有用戶端程式庫都支援自訂資源。GoPython 用戶端程式庫支援。

當您新增自訂資源時,可以使用以下方式存取它

  • kubectl
  • Kubernetes 動態用戶端。
  • 您編寫的 REST 用戶端。
  • 使用 Kubernetes 用戶端產生工具產生的用戶端(產生一個用戶端是一項進階任務,但某些專案可能會提供一個與 CRD 或 AA 一起提供的用戶端)。

自訂資源欄位選擇器

欄位選擇器 允許用戶端根據一個或多個資源欄位的值來選擇自訂資源。

所有自訂資源都支援 metadata.namemetadata.namespace 欄位選擇器。

CustomResourceDefinition 中宣告的欄位,如果包含在 CustomResourceDefinitionspec.versions[*].selectableFields 欄位中,也可以與欄位選擇器一起使用。

自訂資源的可選欄位

功能狀態: Kubernetes v1.32 [stable] (預設啟用:true)

CustomResourceDefinitionspec.versions[*].selectableFields 欄位可用於宣告自訂資源中的哪些其他欄位可以用於欄位選擇器。

以下範例新增 .spec.color.spec.size 欄位作為可選欄位。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: shirts.stable.example.com
spec:
  group: stable.example.com
  scope: Namespaced
  names:
    plural: shirts
    singular: shirt
    kind: Shirt
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              color:
                type: string
              size:
                type: string
    selectableFields:
    - jsonPath: .spec.color
    - jsonPath: .spec.size
    additionalPrinterColumns:
    - jsonPath: .spec.color
      name: Color
      type: string
    - jsonPath: .spec.size
      name: Size
      type: string

然後可以使用欄位選擇器來僅取得 colorblue 的資源

kubectl get shirts.stable.example.com --field-selector spec.color=blue

輸出應為

NAME       COLOR  SIZE
example1   blue   S
example2   blue   M

下一步

上次修改時間:2024 年 10 月 31 日 星期四 10:47 AM PST:移除穩定功能的功能閘道資訊,將詳細資訊新增至欄位選擇器文件 (2b996e4434)