在 Kubernetes 環境中,管理資料函式庫和其結構描述常常需要繁瑣的設定。本文將示範如何使用 Crossplane 的組合函式簡化這個流程。首先,我們利用 Go 範本函式根據複合資源的定義動態產生 AtlasSchema 資源,讓 Crossplane 能夠自動建立和管理資料函式庫結構描述。接著,我們引入 Auto-Ready 函式,它能自動偵測受管資源的狀態,並將其同步到複合資源,解決先前版本中複合資源狀態不同步的問題。透過這些技術,我們可以更有效率地管理資料函式庫,同時降低設定的複雜度。
透過組合函式擴充套件 Crossplane:資料函式庫與模式管理
在先前的設定中,我們成功將兩個資料函式庫(db-01 和 db-02)新增到伺服器。然而,目前存在一個問題,需要先離開 psql CLI 和容器才能解決。
追蹤 Claim 發現問題
透過執行 Claim 的追蹤,我們發現 SQL 複合資源的狀態顯示為「Creating」,即使資料函式庫資源實際上已經可用。這是因為 Go 範本函式無法提供資源的狀態,導致父資源無法正確判斷子資源的可用性。這個問題需要後續修正。
crossplane beta trace sqlclaim my-db --namespace a-team
輸出(已截斷):
NAME SYNCED READY STATUS
SQLClaim/my-db (a-team) True False Waiting: ...resource...
└─ SQL/my-db-rmwkj True False Creating: ...resources: my-db-...-db-01,\
my-db-...-db-02
├─ ResourceGroup/my-db-... True True Available
├─ FirewallRule/my-db-... True True Available
├─ Server/my-db-... True True Available
├─ Database/my-db-...-db-01 True True Available
├─ Database/my-db-...-db-02 True True Available
└─ ProviderConfig/my-db-... - -
整合 Atlas Operator 管理資料函式庫模式
為了讓 Crossplane 能夠管理資料函式庫模式,玄貓(BlackCat)使用 Atlas Operator。這個 Operator 已經透過設定指令碼佈署。
以下是如何更新 Composite Resource Definition 以支援模式管理:
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: sqls.devopstoolkitseries.com
spec:
...
versions:
...
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
...
parameters:
type: object
properties:
...
schemas:
description: Database schema. Atlas operator...
type: array
items:
type: object
properties:
database:
description: The name of the database...
type: string
sql:
description: The SQL to apply.
type: string
required:
- version
required:
- parameters
在這個定義中,玄貓(BlackCat)新增了一個名為 schemas 的陣列,用於儲存資料函式庫模式。每個模式物件包含 database 欄位(指定模式應套用的資料函式庫名稱)和 sql 欄位(包含 SQL 陳述式)。
套用更新後的 Composite Resource Definition:
kubectl apply --filename compositions/sql-v10/definition.yaml
修改 Composition 以應用 AtlasSchema
接下來,玄貓(BlackCat)修改了 Composition,以使用 Go 範本函式來應用 AtlasSchema 資源。
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: azure-postgresql
...
spec:
...
pipeline:
...
- functionRef:
name: upbound-function-go-templating
step: schema
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline: |
{{ range .observed.composite.resource.spec.parameters.schemas }}
---
apiVersion: kubernetes.crossplane.io/v1alpha1
kind: Object
metadata:
name: {{ $.observed.composite.resource.spec.id }}-schema-{{ .database }}
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: {{ $.observed.composite.resource.spec.id }}-{{ .database }}
spec:
providerConfigRef:
name: {{ $.observed.composite.resource.spec.id }}-sql
forProvider:
manifest:
apiVersion: db.atlasgo.io/v1alpha1
kind: AtlasSchema
metadata:
name: {{ $.observed.composite.resource.spec.id }}-{{ .database }}
namespace: {{ $.observed.composite.resource.spec.claimRef.namespace }}
toFieldPath: spec.credentials.connectionSecretRef.namespace
spec:
credentials:
scheme: postgres
hostFrom:
secretKeyRef:
key: endpoint
name: {{ $.observed.composite.resource.spec.id }}
port: 5432
userFrom:
secretKeyRef:
key: username
name: {{ $.observed.composite.resource.spec.id }}
passwordFrom:
secretKeyRef:
key: password
name: {{ $.observed.composite.resource.spec.id }}
database: {{ .database }}
parameters:
sslmode: disable
schema:
sql: "{{ .sql }}"
{{ end }}
這個 Composition 新增了一個步驟,使用 Go 範本函式迭代 schemas 欄位中的所有專案。對於每個專案,它都會建立一個新的 Object 資源,該資源使用來自 Secret 的身份驗證資料來套用 AtlasSchema。schema 欄位使用在 Composite Resource Definition 中定義的 schemas[].sql 欄位填充。
套用更新後的 Composition:
kubectl apply --filename compositions/sql-v10/$HYPERSCALER.yaml
在 Claim 中指定模式
為了實際應用模式,玄貓(BlackCat)需要在 Claim 中指定它們。
以下是一個更新後的 Composite Claim 範例:
apiVersion: devopstoolkitseries.com/v1alpha1
kind: SQLClaim
...
spec:
...
parameters:
...
schemas:
- database: db-01
sql: |
create table videos (
id varchar(50) not null,
description text,
primary key (id)
)
在這個範例中,玄貓(BlackCat)指定了一個模式,該模式將在 db-01 資料函式庫中建立一個名為 videos 的表。
為資料函式庫加入結構描述:組合函式
我們已經新增了一個包含一個專案的結構描述。資料函式庫 db-01 的 SQL 設定是用於建立 videos 和 comments 資料表。請不要對這些 create table 陳述式感到困惑。
Atlas Operator 會建立一個暫時的資料函式庫,建立這些資料表,然後將結構描述與「真實」的伺服器進行比較,並套用差異。在這個例子中,它會建立這兩個資料表。但如果之後我們修改其中一個資料表,或是新增一個資料表,它也會套用這些差異。這非常棒,建議您自行深入研究,或者觀看這個影片。
總而言之,一個結構描述會被套用到 db-01,而 db-02 則不會有結構描述,因為我們沒有指定任何結構描述。
讓我們套用修改後的複合宣告…
kubectl --namespace a-team apply \
--filename examples/$HYPERSCALER-sql-v10.yaml
…並檢索 atlasschemas。
kubectl --namespace a-team get atlasschemas
輸出如下(為了簡潔起見,已截斷):
NAME READY REASON
my-db-...-db-01 False GettingDevDB
我們可以看到 atlasschema 已經被建立。
我們可以透過建立一個包含 psql 客戶端的 Pod 來確認複合資源是否完成了它應該做的事情…
kubectl run postgresql-client --rm -ti --restart='Never' \
--image docker.io/bitnami/postgresql:16 \
--env PGPASSWORD=$PGPASSWORD --env PGHOST=$PGHOST \
--env PGUSER=$PGUSER --command -- sh
內容解密:
這段程式碼建立一個名為 postgresql-client 的 Pod,使用 bitnami/postgresql:16 映像檔。它設定了連線到 PostgreSQL 資料函式庫所需的環境變數,然後啟動一個 shell 供使用者互動。
…使用伺服器連線 psql…
psql --host $PGHOST -U $PGUSER -d postgres -p 5432
內容解密:
這行程式碼使用 psql 命令列工具連線到 PostgreSQL 資料函式庫。它使用先前設定的環境變數來指定主機、使用者名稱、資料函式庫名稱和連線埠。
…切換到 db-01 資料函式庫…
\c db-01
內容解密:
\c 是 psql 中的一個指令,用於變更目前連線的資料函式庫。在這個例子中,它將連線切換到 db-01 資料函式庫。
…並列出所有資料表。
\dt
輸出如下:
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | comments | table | postgres
public | videos | table | postgres
(2 rows)
兩個資料表都已建立。
我們可以透過輸出 videos 資料表的結構描述來進一步確認。
\d videos
輸出如下:
Table "public.videos"
Column | Type | Collation | Nullable | Default
-------------+-----------------------+-----------+----------+---------
id | character varying(50) | | not null |
description | text | | |
Indexes:
"videos_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "comments" CONSTRAINT "fk_videos" FOREIGN KEY (video_id) REFERENCES videos\
(id)
我們可以看到 videos 資料表包含我們指定的欄位,並且它正在參考 comments 資料表。
一切似乎都運作正常,所以讓我們離開 psql…
exit
…以及 Pod。
exit
解決複合資源狀態的問題:Auto-Ready 函式
現在我們剩下一個問題要解決。我們需要讓複合資源理解透過 Go 樣板函式建立的受管資源的「真實」狀態。
讓我們再次追蹤複合宣告。
crossplane beta trace sqlclaim my-db --namespace a-team
輸出如下(為了簡潔起見,已截斷):
NAME SYNCED READY STATUS
SQLClaim/my-db (a-team) True False Waiting: ...resource claim is waiti\
ng...
└─ SQL/my-db-rmwkj True False Creating: ...y-db-...-db-02, and my\
-db-...-schema-db-01
├─ ResourceGroup/my-db-... True True Available
├─ FirewallRule/my-db-... True True Available
├─ Server/my-db-... True True Available
├─ Object/my-db-...-schema-db-01 True True Available
├─ ProviderConfig/my-db-...-sql - -
├─ Database/my-db-...-db-01 True True Available
├─ Database/my-db-...-db-02 True True Available
└─ ProviderConfig/my-db-... - -
我們可以看到,Database 以及包含結構描述的 Object 受管資源都是 Available,但 SQL 複合資源仍然認為這三個受管資源正在被建立 (Creating)。
玄貓認為,我們可以用幾種方式解決這個問題,其中一種方式是最簡單的。既然玄貓很懶,我們就選擇最簡單和最快的方式。我們將使用另一個組合函式。
這是套件資訊清單。
cat providers/function-auto-ready.yaml
輸出如下:
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: upbound-function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1
這次我們新增了 function-auto-ready 函式,它有一個非常簡單的目的:自動偵測已準備好的組合資源,並更新它們的狀態。由於每個步驟中的函式都會收到(除其他事項外)之前步驟中組裝的所有組合資源,如果我們將該函式作為最後一個步驟,它就能夠評估到目前為止組裝的所有組合資源,並更新狀態。這是一個函式如何解決不一定像 Go 樣板那樣典型的任務的例子。
讓我們套用這個套件…
kubectl apply --filename providers/function-auto-ready.yaml
…並看看修改後的組合版本。
cat compositions/sql-v11/$HYPERSCALER.yaml
輸出如下(為了簡潔起見,已截斷):
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
...
spec:
...
pipeline:
...
- functionRef:
name: upbound-function-auto-ready
step: automatically-detect-ready-composed-resources
這很簡單。automatically-detect-ready-composed-resources 甚至沒有定義輸入。該函式不需要任何額外資訊,除了到目前為止組裝的所有組合資源的清單。每個函式都會收到它們,無論它們是否需要額外輸入。
讓我們看看它是否有效,方法是套用新版本的組合…
kubectl apply --filename compositions/sql-v11/$HYPERSCALER.yaml
…並追蹤宣告。
crossplane beta trace sqlclaim my-db --namespace a-team
玄貓總結:
這段內容涵蓋瞭如何使用 Crossplane 的組合函式來建立和管理資料函式庫結構描述,以及如何使用 function-auto-ready 函式來自動更新複合資源的狀態。透過這些技術,我們可以更輕鬆地管理複雜的雲端基礎架構,並確保資源的狀態與實際情況保持一致。
組合函式:開發更強大的 Crossplane 應用
在 Kubernetes 的世界裡,Crossplane 讓我們能夠以宣告式的方式管理雲端資源。為了進一步提升 Crossplane 的能力,我們可以利用組合函式(Composition Functions)。這些函式就像是樂高積木,讓我們能將複雜的組態邏輯拆解成可重用的模組。
從狀態觀察到自動偵測:組合函式的演進
在前一篇文章中,我們透過觀察資源的狀態來判斷 SQL 複合資源是否可用。現在,我們將更進一步,使用自動偵測函式(Auto-Detect Function)來自動將受管資源的狀態傳播到複合資源。
以下是 SQL 複合資源的狀態範例:
NAME SYNCED READY STATUS
SQLClaim/my-db (a-team) True True Available
└─ SQL/my-db-rmwkj True True Available
├─ ResourceGroup/my-db-... True True Available
├─ FirewallRule/my-db-... True True Available
├─ Server/my-db-... True True Available
├─ Object/my-db-...-schema-db-01 True True Available
├─ ProviderConfig/my-db-...-sql - -
├─ Database/my-db-...-db-01 True True Available
├─ Database/my-db-...-db-02 True True Available
└─ ProviderConfig/my-db-... - -
這次,SQL 複合資源的狀態是 Available。新加入的自動偵測函式正確地將受管資源的狀態傳播到複合資源。
組合函式如何運作?
我們在控制平面叢集佈署了三個函式:
- 修補與轉換函式(Patch and Transform Function): 用於執行修補和轉換操作。
- Go 範本函式(Go Templating Function): 用於執行 Go 範本。
- 自動就緒函式(Auto-Ready Function): 用於確保資源的狀態正確。
接著,我們應用了設定為以 Pipeline 模式執行的組合,包含四個步驟:
- 修補與轉換: 第一步使用修補與轉換函式來處理不需要特殊處理的資源。複合資源(XR)將所有資源傳送到此函式,函式會傳回修補後的相同資源。
- Go 範本: 第二步使用 Go 範本函式。它將範本傳送到此函式,該範本會疊代資料函式庫清單以及所有先前組裝的資源。此函式將資料函式庫新增到資源清單,並將所有資源傳回給複合資源。
- 修補與轉換(再次): 第三步再次使用修補與轉換函式。它將輸入(範本)與所有先前組裝的資源一起傳送,此函式將 Schema 新增到資源清單,並將所有資源傳回給複合資源。
- 自動就緒: 最後一步使用自動就緒函式,此函式沒有輸入,因此只會接收先前組裝的資源,並傳回具有正確狀態的資源。
執行完所有步驟後,每個步驟都會修改資源的狀態,複合資源(XR)會建立、更新或刪除受管資源(MR)。
組合函式:Crossplane 的核心動力
幾乎所有繁重的工作都由函式完成,而複合資源則作為 Pipeline 步驟的協調者,透過傳送輸入並預期資源作為輸出來呼叫函式。
封裝與推播組態包
現在我們已經完成了組合和複合資源定義的改進,接下來該將所有內容封裝並將新版本推播到 Registry,以便其他人可以輕鬆使用我們正在建構的 Database-as-a-Service 的改進版本。
但在建構套件之前,我們需要對上一章中建立的組態進行一些變更。
讓我們看看組態的更新版本。
apiVersion: meta.pkg.crossplane.io/v1
kind: Configuration
...
spec:
...
dependsOn:
...
- provider: crossplane/provider-sql
version: ">=v0.5.0"
- function: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform
version: ">=v0.1.4"
- function: xpkg.upbound.io/crossplane-contrib/function-go-templating
version: ">=v0.4.0"
- function: xpkg.upbound.io/crossplane-contrib/function-auto-ready
version: ">=v0.2.1"
...
我們使用組態來定義它所依賴的 Provider。因此,每次我們佈署組態包時都會佈署這些 Provider。這些 Provider 被定義為 provider,我們應該對函式執行相同的操作。它們也是組態的依賴項。
將函式新增為依賴項與 Provider 相同。唯一的區別是我們需要使用 function 而不是 provider。這就是全部,所以讓我們建構一個新版本的組態包。
我不會詳細介紹後續步驟,因為它們與我們在上一章中探索的步驟相同。相反,我們將快速瀏覽已經知道的內容。
我們將進入包含組合、複合資源定義和組態的目錄,…
cd compositions/sql-v11
…並建構組態包。
crossplane xpkg build
接下來,我們將使用 Registry 使用者名稱建立 UP_USER 環境變數,…
export UP_USER=[...]
…登入,…
crossplane xpkg login --username $UP_USER
…推播套件,…
crossplane xpkg push xpkg.upbound.io/$UP_USER/dot-sql:v0.0.11
…從檔案系統中移除它,…
rm dot-sql-*.xpkg
…然後回到儲存函式庫的根目錄。
cd ../../
就是這樣。新版本的組態包已在 Registry 中,任何人都可以使用它。
我們改進了 Database-as-a-Service 的功能,而沒有增加終端使用者的複雜性,只是在複合資源定義中新增了一些額外的欄位。從使用者的角度來看,我們所做的事情都不相關。他們所要做的就是繼續建立、更新和刪除複合宣告。他們需要處理大約 10 行 YAML。複雜性增加了,但仍然是「隱藏的」。至少從建立宣告的終端使用者的角度來看,複雜性仍然是一個實作細節。
我們尚未探索如何建構自己的函式。到目前為止,我們使用的所有函式都是公開的。我們充當函式使用者,而不是函式建構者。
總有一天,沒有任何公開可用的函式能滿足我們的需求。當那一天到來時,我們會希望使用我們自己的邏輯來建構我們自己的函式。然而,那一天不是今天。
本章幾乎結束了。剩下的就是摧毀一切。
摧毀一切
你知道該怎麼做。
讓指令碼可執行,…
chmod +x destroy/04-functions.sh
…執行它,…
./destroy/04-functions.sh
待辦事項:快轉
…然後離開 Nix Shell。
exit
結束?
這不是結束。隨著 Crossplane 繼續發展,我將繼續為本章新增章節。如果你從 LeanPub 取得本章,你將收到下載本章更新版本的通知。從 Amazon 購買的電子書版本也應該如此。如果你從 Amazon 取得「死樹」(印刷)版本,那就是這個格式。但是,你可以在 LinkedIn 或 Twitter 上傳送訊息給我,我會回覆你,並提供從 LeanPub 免費下載電子書的連結(並在更新時收到通知)。
最後,請訂閱 https://youtube.com/@DevOpsToolkit。你可以在該頻道上找到源源不斷的影片,其中許多影片都與 Crossplane 相關。
