本頁說明如何在還原程序中使用轉換規則修改 Kubernetes 資源。轉換規則是為了改善先前的替代規則功能而推出。由於這些規則與替代規則不具回溯相容性,因此已淘汰的替代規則介面仍可使用。
如要查看替代規則的說明文件,請參閱「在還原期間修改資源」。
總覽
您可能基於下列原因,想在還原程序中修改 Kubernetes 資源:
您可能想使用其他儲存空間佈建工具建立 PersistentVolumeClaim (PVC)。舉例來說,您想從 Kubernetes 樹狀結構內建驅動程式遷移至 CSI 驅動程式。
您可能想以其他名稱還原命名空間。
您可能想新增、變更或刪除與標籤或 ConfigMap 鍵相關聯的值。
您可能想變更 Deployment 或 StatefulSet 中的副本數量。
Backup for GKE 提供稱為「轉換規則」的機制來進行這些變更,您可以選擇在 RestorePlan
中定義這些規則。
在還原程序中,轉換規則的運作方式如下:
規則會整理成排序清單。
所有要還原的資源 (
CustomResourceDefinition
資源除外,因為轉換不適用於這類資源) 會依序通過這份規則清單。每項規則都包含簡短說明、相符條件和資源編輯內容。
如果資源不符合規則的條件,系統會移至清單中的下一個規則,且不會修改資源。
如果資源符合規則的條件,系統會先將規則的編輯內容套用至資源,然後再移至清單中的下一個規則。
如果定義了多個規則,系統會根據先前規則修改的資源版本,評估每個規則的相符條件。
套用任何相符規則的編輯內容後,資源的最終版本就會在叢集中建立。
轉換規則參數
您需要提供下列資訊,才能建立轉換規則:
description
:轉換規則的簡短說明。resourceFilter
:這項篩選條件用於比對資源。如未提供resourceFilter
,所有資源都會符合這項規則。fieldActions
:這是要對符合resourceFilter
的資源進行的編輯清單。編輯內容會以排序過的動作清單形式提供。 這裡的順序很重要,因為一個動作的結果可能會影響清單中的下一個動作。如果任何動作失敗,整個還原程序就會失敗。
資源篩選條件 (resourceFilter
)
如要定義資源篩選器,請提供下列參數:
參數 | 必要 | 說明 |
---|---|---|
namespaces |
選用 | 這是命名空間清單。如要讓資源符合這項規則,資源必須是命名空間資源,且具有其中一個指定命名空間。如果未提供此參數的任何內容,則所有資源都會相符 (所有命名空間和叢集範圍的資源)。 |
groupKinds |
選用 |
這是 Kubernetes 資源 Group/Kind 元組的清單:
|
jsonPath |
選用 | 這是用於比對資源的 JSONPath 運算式。 |
JSONPath (jsonPath
)
JSONPath 運算式用於比對資源。 如果運算式的結果不為空,則視為資源相符。
假設有下列資源:
YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-cm
labels:
app: mysql
app.kubernetes.io/name: mysql
data:
primary.cnf: |
# Apply this config only on the primary.
[mysqld]
log-bin
replica.cnf: |
# Apply this config only on replicas.
[mysqld]
super-read-only
JSON
{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "mysql-cm",
"labels": {
"app": "mysql",
"app.kubernetes.io/name": "mysql"
}
},
"data": {
"primary.cnf": "# Apply this config only on the primary.\n[mysqld]\nlog-bin\n",
"replica.cnf": "# Apply this config only on replicas.\n[mysqld]\nsuper-read-only\n"
}
}
使用 JSONPath 運算式的範例:
Expression | 說明 | 結果 |
---|---|---|
.metadata[?(@.name == 'mysql-cm')] |
metadata 物件包含 name 鍵,且值為「mysql-cm」 |
[ |
.metadata.labels['app\.kubernetes\.io/name'] |
「app.kubernetes.io/name」鍵在 metadata.labels 下的字串值 |
[ |
.data['primary\.cnf'] |
data 底下索引鍵「primary.cnf」的物件值 |
[ |
.metadata[?(@.name =~ /^mysql-.*/i)] |
metadata 物件包含 name 鍵,且其值符合規則運算式「/^mysql-.*/i」。正斜線 / 用於分隔規則運算式模式。規則運算式結尾的 i 是不區分大小寫比對的標記。 |
[ |
只要 JSONPath 運算式的輸出內容不為空,對應的資源就會符合這項規則。
因此,.metadata[?(@.name == 'mysql-cm')]
和 .metadata[?(@.name == 'mysql-cm')].name
會產生相同的相符結果,也就是與 .metadata.name
為 "mysql-cm"
的資源相符。
在 JSONPath 中使用篩選器,比對 Google Cloud 控制台中的對應鍵時,需要使用 \
(反斜線) 逸出 .
(點)。如果使用 gcloud CLI 或 Terraform 語言,在 YAML 環境中提供 JSONPath,則需要 \\
(雙反斜線)。舉例來說,在 YAML 或 Terraform 中,.metadata.labels['app\.kubernetes\.io/name']
等同於 .metadata.labels['app\\.kubernetes\\.io/name']
。
建議您使用支援規則運算式的 JSONPath 評估工具,先測試運算式再使用。
您也可以使用 kubectl
驗證 JSONPath 運算式的結果。
如需更多範例,請參閱「JSONPath 支援」。
欄位動作 (fieldActions
)
欄位動作是根據 JSON Patch 建立模型,該模型定義了 JSON 文件結構,用於表示要套用至 JSON 文件的作業。如要定義欄位動作,請提供下列參數:
path
:這是 JSON 指標值,可參照要在目標資源中執行作業的位置。JSON 指標一律以/
(斜線) 開頭,屬性名稱 (鍵) 降至子項元素時,也會以/
(斜線) 分隔。op
:這是對資源執行的作業類型,支援五種作業:add
會根據path
參照的內容,將新物件或值插入指定的path
。remove
會從指定的path
中移除值。replace
會將指定path
的值替換為新值。move
會從位置移除值,並將其新增至指定的path
。copy
會將值從某個位置複製到指定的path
。
您可以使用下列 Pod 定義,查看各項作業的範例:
YAML
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
JSON
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nginx",
"namespace": "ns",
"labels": {
"app": "nginx"
}
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "nginx:latest",
"ports": [
{
"containerPort": 80
}
],
"env": [
{
"name": "PROTOCOL",
"value": "https"
}
],
"resources": {
"limits": {
"cpu": "250m",
"memory": "64Mi"
}
}
}
],
"initContainers": [
{
"name": "install",
"image": "busybox:stable",
"command": [
"wget",
"-O",
"/tmp/index.html",
"http://info.cern.ch"
]
}
]
}
}
新增
value
一律是 add
作業的必要條件,且必須是合法的 JSON 元素。
下列動作會將值為 "80"
的新環境變數 "PORT"
新增至 nginx
容器。
op: add
path: "/spec/containers/0/env/0"
value: >
{
"name": "PORT",
"value": "80"
}
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
- name: PORT # newly added
value: "80" # newly added
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
下列動作會將值新增至 Pod 的新標籤 app.kubernetes.io/name: nginx
。
op: add
path: "/metadata/labels/app.kubernetes.io~1name"
value: "nginx"
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
app.kubernetes.io/name: nginx # newly added
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
下列動作會取代 nginx
容器的映像檔,將其從 "nginx:latest"
變更為 "nginx:stable"
。
op: add
path: "/spec/containers/0/image"
value: nginx:stable
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable # replaced
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
移除
下列動作會移除 nginx
容器的資源需求。
op: remove
path: "/spec/containers/0/resources"
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
# resource requirements are removed
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
取代
value
是 replace
作業的必要元素,且必須是 JSON 元素。
下列動作會將 nginx
容器的映像檔從 nginx:latest
替換為 nginx:stable
。
op: replace
path: "/spec/containers/0/image"
value: nginx:stable
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable # replaced
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
移動
move
作業必須具備 fromPath
。
下列動作會從 nginx
容器移除環境變數,並將其新增至 install
init 容器。
op: move
fromPath: "/spec/containers/0/env"
path: "/spec/initContainers/0/env"
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# "env" is moved to "install" container
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
env: # moved "from" nginx container
- name: PROTOCOL
value: https
複製
copy
作業必須具備 fromPath
。
下列動作會將環境變數從 nginx
容器複製到 install
初始化容器。
op: copy
fromPath: "/spec/containers/0/env"
path: "/spec/initContainers/0/env"
原始
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
轉型完成
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ns
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
env:
- name: PROTOCOL
value: "https"
resources:
limits:
cpu: "250m"
memory: "64Mi"
initContainers:
- name: install
image: busybox:stable
command:
- wget
- "-O"
- "/tmp/index.html"
- http://info.cern.ch
env: # copy from "nginx" container
- name: PROTOCOL
value: https
如要進一步瞭解如何在 Google Cloud 控制台中定義轉換規則,請參閱「規劃一組還原作業」。
如要透過 gcloud CLI 定義轉換規則,請建立包含 transformationRules
YAML 陣列的檔案,並在 gcloud beta container backup-restore restore-plans create
指令中加入 --transformation-rules-file=
參數。
轉換規則範例
下列範例採用 gcloud CLI 或 Terraform 設定語言使用的 YAML 格式。
變更 PVC 的 StorageClass
這個範例會將所有還原的 PersistentVolumeClaim 資源中的 StorageClass 從 standard
變更為 premium-rwo
:
YAML
transformationRules:
- description: Change StorageClass in PVC from standard to premium-rwo
resourceFilter:
namespaces: []
jsonPath: ".spec[?(@.storageClassName == 'standard')]"
groupKinds:
- resourceGroup: ""
resourceKind: PersistentVolumeClaim
fieldActions:
- op: REPLACE
path: "/spec/storageClassName"
value: "premium-rwo"
Terraform
transformation_rules {
description = "Change StorageClass in PVC from standard to premium-rwo"
resource_filter {
json_path = ".spec[?(@.storageClassName == 'standard')]"
group_kinds {
resource_kind = "PersistentVolumeClaim"
}
}
field_actions {
op = "REPLACE"
path = "/spec/storageClassName"
value = "premium-rwo"
}
}
複製命名空間
這個範例會將命名空間從 Alpha 複製到 Beta,建立新的 "beta"
命名空間,並將 "alpha"
中的所有資源還原到新的 "beta"
命名空間。這個範例需要兩項轉換規則:一項適用於命名空間本身,另一項適用於命名空間內的資源。
YAML
transformationRules:
- description: Rename namespace name from alpha to beta
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name == 'alpha')]"
groupKinds:
- resourceGroup: ""
resourceKind: Namespace
fieldActions:
- op: REPLACE
path: "/metadata/name"
value: "beta"
- description: Clone all resources from namespace alpha to beta
resourceFilter:
namespaces: ["alpha"]
fieldActions:
- op: REPLACE
path: "/metadata/namespace"
value: "beta"
Terraform
transformation_rules {
description = "Rename namespace name from alpha to beta"
resource_filter {
json_path = ".metadata[?(@.name == 'alpha')]"
group_kinds {
resource_kind = "Namespace"
}
}
field_actions {
op = "REPLACE"
path = "/metadata/name"
value = "beta"
}
}
transformation_rules {
description = "Clone all resources from namespace alpha to beta"
resource_filter {
namespaces = ["alpha"]
}
field_actions {
op = "REPLACE"
path = "/metadata/namespace"
value = "beta"
}
}
在複製的命名空間中變更 PVC 的 StorageClass 和副本數量
這個範例會複製命名空間,然後對新命名空間中的資源套用一組變更:
將 PVC 上的 StorageClass 從
standard
變更為premium-rwo
將 Deployment
nginx
的備用資源數量變更為3
YAML
transformationRules:
- description: Rename the namespace from alpha to beta
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name == 'alpha')]"
groupKinds:
- resourceGroup: ""
resourceKind: Namespace
fieldActions:
- op: REPLACE
path: "/metadata/name"
value: "beta"
- description: Change all resources from namespace alpha to beta
resourceFilter:
namespaces: ["alpha"]
fieldActions:
- op: REPLACE
path: "/metadata/namespace"
value: "beta"
- description: Change the StorageClass on PVCs from standard to premium-rwo
resourceFilter:
namespaces: ["beta"]
jsonPath: ".spec[?(@.storageClassName == 'standard')]"
groupKinds:
- resourceGroup: ""
resourceKind: PersistentVolumeClaim
fieldActions:
- op: REPLACE
path: "/spec/storageClassName"
value: "premium-rwo"
- description: Change the replica count of the Deployment nginx from 7 to 3
resourceFilter:
namespaces: ["beta"]
jsonPath: ".metadata[?(@.name == 'nginx')]"
groupKinds:
- resourceGroup: apps
resourceKind: Deployment
fieldActions:
- op: REPLACE
path: "/spec/replicas"
value: "3"
Terraform
transformation_rules {
description = "Rename the namespace from alpha to beta"
resource_filter {
json_path = ".metadata[?(@.name == 'alpha')]"
group_kinds {
resource_kind = "Namespace"
}
}
field_actions {
op = "REPLACE"
path = "/metadata/name"
value = "beta"
}
}
transformation_rules {
description = "Change all resources from namespace alpha to beta"
resource_filter {
namespaces = ["alpha"]
}
field_actions {
op = "REPLACE"
path = "/metadata/namespace"
value = "beta"
}
}
transformation_rules {
description = "Change the StorageClass on PVCs from standard to premium-rwo"
resource_filter {
namespaces = ["beta"]
json_path = ".spec[?(@.storageClassName == 'standard')]"
group_kinds {
resource_kind = "PersistentVolumeClaim"
}
}
field_actions {
op = "REPLACE"
path = "/spec/storageClassName"
value = "premium-rwo"
}
}
transformation_rules {
description = "Change the replica count of the Deployment nginx from 7 to 3"
resource_filter {
namespaces = ["beta"]
json_path = ".metadata[?(@.name == 'nginx')]"
group_kinds {
resource_group = "apps"
resource_kind = "Deployment"
}
}
field_actions {
op = "REPLACE"
path = "/spec/replicas"
value = "3"
}
}
變更、插入及移除 ConfigMap 項目
這個範例會將命名空間 "mysql"
中包含標籤鍵 "app.kubernetes.io/name"
的 ConfigMap
修改為:
將項目
"endpoint"
的值變更為"192.0.2.127"
。插入新項目
"connection-timeout"
,值為"30s"
。移除以
"read-timeout"
為鍵的項目。
YAML
transformationRules:
- description: Change, insert, remove `ConfigMap` entres
resourceFilter:
namespaces: ["mysql"]
jsonPath: ".metadata.labels['app\\.kubernetes\\.io/name']"
groupKinds:
- resourceGroup: ""
resourceKind: ConfigMap
fieldActions:
- op: REPLACE
path: "/data/endpoint"
value: "192.0.2.127"
- op: ADD
path: "/data/connection-timeout"
value: "30s"
- op: REMOVE
path: "/data/read-timeout"
Terraform
transformation_rules {
description = "Change, insert, remove `ConfigMap` entres"
resource_filter {
namespaces = ["mysql"]
json_path = ".metadata.labels['app\\.kubernetes\\.io/name']"
group_kinds {
resource_kind = "ConfigMap"
}
}
field_actions {
op = "REPLACE"
path = "/data/endpoint"
value = "192.0.2.127"
}
field_actions {
op = "ADD"
path = "/data/connection-timeout"
value = "30s"
}
field_actions {
op = "REMOVE"
path = "/data/read-timeout"
}
}
為名稱開頭為「mysql-」mysql-的資源新增標籤 app.kubernetes.io/name
;
這個範例會將值為 mysql
的 app.kubernetes.io/name
標籤新增至名稱開頭為 mysql- 的所有資源:
YAML
transformationRules:
- description: Add a label to resources whose name starts with
resourceFilter:
namespaces: []
jsonPath: ".metadata[?(@.name =~ /^mysql-.*/i)]"
fieldActions:
- op: ADD
path: "/metadata/labels/app.kubernetes.io~1name"
value: "mysql"
Terraform
transformation_rules {
description = "Add a label to resources whose name starts with"
resource_filter {
json_path = ".metadata[?(@.name =~ /^mysql-.*/i)]"
}
field_actions {
op = "ADD"
path = "/metadata/labels/app.kubernetes.io~1name"
value = "mysql"
}
}
為 LoadBalancer 類型的 Service 指派靜態 IP 位址
這個範例會為命名空間 "nginx"
中的 Service "nginx-svc"
指派靜態 IP 位址:
YAML
transformationRules:
- description: Assign a static IP to Service nginx-svc
resourceFilter:
namespaces: ["nginx"]
jsonPath: ".metadata[?(@.name == 'nginx-svc')]"
groupKinds:
- resourceGroup: ""
resourceKind: Service
fieldActions:
- op: ADD
path: "/spec/loadBalancerIP"
value: "192.0.2.127"
Terraform
transformation_rules {
description = "Assign a static IP to Service nginx-svc"
resource_filter {
namespaces = ["nginx"]
json_path = ".metadata[?(@.name == 'nginx-svc')]"
group_kinds {
resource_kind = "Service"
}
}
field_actions {
op = "ADD"
path = "/spec/loadBalancerIP"
value = "192.0.2.127"
}
}