在雲端原生應用程式開發中,有效管理和組合雲端資源至關重要。Crossplane 提供了 Composition 作為一個強大的工具,實作更精細的資源組態和管理。本文將以 PostgreSQL 資料函式庫在 Google Cloud 上的組態為例,探討 Composition 的進階用法,包含如何透過 Composition Selector 進行資源客製化,如何管理資料函式庫連線資訊,以及如何根據不同的雲端供應商(例如 AWS、Azure 和 Google Cloud)調整組態。透過 Composition,開發者可以根據不同的環境或應用程式需求選擇不同的組態,簡化組態流程並提升效率。同時,Crossplane Secret 的使用也確保了連線資訊的安全性和易用性。透過本文的實戰,讀者將能夠更有效地運用 Crossplane Composition,精準組態和管理雲端資源。
擺脫 CRD 的束縛:使用 CompositeResourceDefinition 開發靈活雲端資源組態
在雲端原生應用開發中,CustomResourceDefinition (CRD) 提供了一種擴充套件 Kubernetes API 的強大方式。但當我們需要更進一步,設計跨越多個雲端服務的複合資源時,CompositeResourceDefinition 就成為更合適的選擇。
CompositeResourceDefinition 本質上與建立 CRD 非常相似,但它允許我們定義更高階別的抽象,將多個底層資源組合在一起。這使得使用者可以像操作單一資源一樣管理複雜的雲端服務組合。
讓我們來看看如何利用 CompositeResourceDefinition 的額外特性,修改現有的定義。
kubectl apply --filename compositions/sql-v3/definition.yaml
透過 PatchSet 最佳化資源組態
在定義了 CompositeResourceDefinition 之後,我們可以修改 Composition 來利用這些變更。Composition 定義瞭如何將複合資源轉換為底層的受管資源。
以下是一個修改後的 Composition 範例,展示瞭如何使用 patchSets 來簡化組態:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
spec:
patchSets:
- name: metadata
patches:
- fromFieldPath: metadata.annotations
toFieldPath: metadata.annotations
- fromFieldPath: spec.id
toFieldPath: metadata.name
resources:
- name: sql
patches:
- type: PatchSet
patchSetName: metadata
- fromFieldPath: spec.parameters.version
toFieldPath: spec.forProvider.databaseVersion
transforms:
- type: string
string:
fmt: POSTGRES_%s
- fromFieldPath: spec.parameters.size
toFieldPath: spec.forProvider.settings[0].tier
transforms:
- type: map
map:
small: db-custom-1-3840
medium: db-custom-16-61440
large: db-custom-64-245760
內容解密:
spec.patchSets: 定義了一組可重複使用的patches,例如metadata,用於將metadata.annotations從複合資源傳播到受管資源。fromFieldPath和toFieldPath: 定義了資料從複合資源到受管資源的路徑。spec.id: 一個自定義欄位,用於指定資料函式庫資源的唯一識別符。
移除硬編碼,擁抱靈活性
在先前的版本中,spec.resources[0].base.spec.forProvider.rootPasswordSecretRef.name 包含了硬編碼的值 my-db-password。但密碼的名稱應該根據複合資源的名稱,並加上 -password 字尾。因此,我們移除了硬編碼的值,並將在後續步驟中使用更靈活的方法。
類別似地,spec.resources[0].base.spec.forProvider.databaseVersion 也被設定為硬編碼的值 POSTGRES_13。這個值應該由使用者在 version 欄位中指定。tier 欄位也被移除,並將被 size 欄位取代。
使用轉換器適應不同雲平台的特性
不同雲端平台對於資源組態的要求可能有所不同。例如,Google Cloud 要求 PostgreSQL 版本以 POSTGRES_13 的格式指定,而使用者可能更傾向於使用 13 這樣的簡潔格式。
為了適應這種差異,我們可以使用 transforms 來轉換輸入值。例如,以下組態將使用者輸入的版本號轉換為 Google Cloud 要求的格式:
- fromFieldPath: spec.parameters.version
toFieldPath: spec.forProvider.databaseVersion
transforms:
- type: string
string:
fmt: POSTGRES_%s
內容解密:
transforms.type: string: 指定轉換型別為字串格式化。string.fmt: POSTGRES_%s: 定義字串格式,其中%s將被spec.parameters.version的值取代。
另一個常見的需求是將使用者友好的值(例如 small、medium、large)對映到雲端平台特定的值。這可以使用 transforms.type: map 來實作:
- fromFieldPath: spec.parameters.size
toFieldPath: spec.forProvider.settings[0].tier
transforms:
- type: map
map:
small: db-custom-1-3840
medium: db-custom-16-61440
large: db-custom-64-245760
內容解密:
transforms.type: map: 指定轉換型別為對映。map: 定義輸入值到輸出值的對映關係。
在 AWS 或 Azure 上,您會看到類別似的對映,但具有不同的值,因為它們根據這些雲端平台提供的尺寸。
應用修改後的 Composition
在完成修改後,我們可以應用這些變更:
kubectl apply --filename compositions/sql-v3
整合新功能到 Composite Resource
最後,我們可以將這些新功能整合到我們使用的 Composite Resource 中。玄貓將在後續的文章中展示如何更新 Composite Resource 以利用這些新功能。
總之,CompositeResourceDefinition 和 Composition 提供了一種強大而靈活的方式來管理雲端資源。透過使用 patchSets 和 transforms,我們可以簡化組態,並適應不同雲端平台的特性,為使用者提供更友好的體驗。
Crossplane Composition:客製化雲端資源組態的進階
在雲端原生應用程式開發中,Crossplane 提供了一種強大的方式來管理和組合雲端資源。本文將探討 Crossplane Composition 的進階用法,包括如何透過 Composition 自定義資源組態、管理連線資訊,以及如何根據不同的雲端供應商進行調整。
透過 Composition Selector 實作雲端資源客製化
Composition Selector 允許我們根據標籤來選擇不同的 Composition,從而實作更細緻的資源客製化。例如,我們可以根據不同的環境(開發、測試、生產)或不同的應用程式需求,選擇不同的 Composition。
以下是一個 Composition 的範例,它定義了一個 PostgreSQL 資料函式庫在 Google Cloud 上的組態:
apiVersion: devopstoolkitseries.com/v1alpha1
kind: SQL
metadata:
name: my-db
annotations:
organization: DevOps Toolkit
author: 玄貓 <blackcat@example.com>
spec:
id: my-db
compositionSelector:
matchLabels:
provider: google
db: postgresql
parameters:
version: "13"
size: small
在這個範例中,compositionSelector 定義了兩個標籤:provider: google 和 db: postgresql。這表示只有同時具有這兩個標籤的 Composition 才會被選中。
此外,我們還增加了 metadata.annotations,以便測試我們定義的補丁是否生效。spec.id、spec.parameters.version 和 spec.parameters.size 欄位也被增加進來。
這個設定檔可以被翻譯成:「給我一個在 Google Cloud 上的 PostgreSQL 伺服器,版本是 13,大小是 small,而與我不需要知道 Google Cloud 中哪些節點被歸類別為 small。」
使用者可以更自由地指定重要的內容,而無需處理底層細節和雲端供應商的複雜性。
如果使用 Azure,你會注意到我們將名稱從 my-db 更改為 my-db-2。Azure 不允許對某些資源(如 SQL)重複使用名稱,即使這些資源已被刪除。因此,spec.id 更改為 my-db-2。否則,由於我們已經有 my-db 並將其刪除,因此使用相同的名稱建立一個新的 my-db 將會失敗。
應用 Composite Resource 並追蹤進度
讓我們應用 Composite Resource…
kubectl apply --filename examples/$HYPERSCALER-sql-v3.yaml
…並追蹤進度。
crossplane beta trace sql my-db
以下是輸出的範例(為了簡潔起見,已截斷):
NAME SYNCED READY STATUS
SQL/my-db True False Creating...
├─ DatabaseInstance/my-db True False Creating
└─ User/my-db False False ReconcileError:...
這些資源最終會準備就緒,在等待的同時,我們可以進行一些觀察。
首先,受管資源的名稱現在是 my-db。不再有自動產生的字尾。我們得到這個變更,是因為其中一個補丁確保資源的名稱與我們增加到定義中的新 spec.id 欄位的值相同。使用自動產生的字尾是一個好的做法,可以幫助我們避免衝突,但我喜歡我的資源具有「正確」的名稱,因此我們忽略了「最佳實踐」。
接下來,我們將檢查增加到 Composite Resource 的註解是否確實已增加到受管資源。為此,我們將使用受管資源的完整名稱建立一個環境變數 XR…
# 將 `[...]` 替換為受管資源的完整名稱。
export XR=[...]
…並將該資源輸出為 YAML。
kubectl get $XR --output yaml
以下是輸出的範例(為了簡潔起見,已截斷):
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
metadata:
annotations:
author: 玄貓 <blackcat@example.com>
...
organization: DevOps Toolkit
...
我們可以看到,受管資源確實已使用來自 Composite Resource 的註解進行修補。
你可以隨意確認是否也應用了其他補丁,或者 просто trust me when I say that they all did. 我們指定的大小和版本已應用於相關資源。
管理連線資訊:Crossplane Secret 的妙用
現在 PostgreSQL 伺服器已啟動並執行,我們需要弄清楚如何連線到它。否則,擁有一個無法使用的資料函式庫有什麼意義?
Crossplane 可以將受管資源產生的所有金鑰合併到一個 Kubernetes Secret 中。我們只需要告訴它將該 Secret 放在哪裡。
讓我們看一下 Composition 的修改版本。
cat compositions/sql-v4/$HYPERSCALER.yaml
以下是輸出的範例(為了簡潔起見,已截斷):
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
...
spec:
writeConnectionSecretsToNamespace: crossplane-system
...
resources:
- name: sql
base:
apiVersion: sql.gcp.upbound.io/v1beta1
kind: DatabaseInstance
spec:
...
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
...
- fromFieldPath: spec.id
toFieldPath: spec.writeConnectionSecretToRef.name
...
首先,我們透過 spec.writeConnectionSecretsToNamespace 告訴 Crossplane 將包含透過受管資源產生的所有機密和連線資訊的 Secret 儲存在 crossplane-system 名稱空間中。將該欄位視為 Secret 的預設位置,可以針對特定資源覆寫。
更重要的是,我們透過 spec.resources[0].base.spec.writeConnectionSecretToRef.namespace 值覆寫將儲存 Secret 的名稱空間。這並非真正必要,因為該值 (crossplane-system) 與我們透過 spec.writeConnectionSecretsToNamespace 設定的值相同,但我想展示我們可以從該特定資源覆寫 Secret 的名稱空間。當我們切換到名稱空間範圍的資源時,該功能將變得重要。
最後,由於所有 SQL Secret 都具有相同的名稱將會很愚蠢,因此我們使用修補將該資源的 spec.writeConnectionSecretToRef.name 的值設定為 Composite Resource 中 spec.id 的值。
現在,讓我們應用 Compositions…
kubectl apply --filename compositions/sql-v4
…並輸出 crossplane-system 名稱空間中的 Secrets。
kubectl --namespace crossplane-system get secrets
以下是輸出的範例(為了簡潔起見,已截斷):
NAME TYPE DATA AGE
...
my-db connection.crossplane.io/v1alpha1 10 13s
my-db-password Opaque 1 8m24s
...
我們可以看到,除了我們建立的 my-db-password Secret 作為提供初始密碼的方式之外,現在還有 my-db,它應該包含有關如何連線到資料函式庫伺服器的所有資訊。
由於如果你使用 AWS 或 Google Cloud,資料函式庫和 Secret 都稱為 my-db,或者如果你使用 Azure,則稱為 my-db- 加上時間戳記字尾,因此演示存在一些複雜情況。為了減輕這種差異,我們將資料函式庫的名稱儲存到環境變數中。