在 Google Kubernetes Engine 叢集中啟用 Backup for GKE 代理程式後,Backup for GKE 會提供 CustomResourceDefinition
,其中會導入一種新的 Kubernetes 資源:ProtectedApplication
。
撰寫 ProtectedApplication
包含三項活動:
選取要備份及還原的資源集,做為應用程式的一部分。
驗證
ProtectedApplication
,檢查是否已準備好備份。
在應用程式層級自訂備份和還原邏輯時,ProtectedApplication
資源可提供下列功能:
更精細的備份和還原作業。如不使用
ProtectedApplications
,您必須在Namespace
層級定義備份範圍 (選取 allNamespaces 或 selectedNamespaces)。命名空間資源還原也適用類似的邏輯。建立ProtectedApplication
資源後,您就能為Namespace
中的部分資源提供名稱。然後在備份範圍中列出 selectedApplications,即可備份及還原該子集 (同樣適用於還原)。協調備份或還原程序的細部作業,包括:
備份時略過所選磁碟區。
將應用程式拓撲納入備份和還原作業 (例如只備份複製資料庫的一個執行個體,並用來還原多個執行個體)。
在磁碟區建立快照前後,執行使用者定義的掛鉤。舉例來說,您可以使用這些掛鉤,在建立快照前排清並停止工作負載,然後在建立快照後取消停止。
您可以使用 kubectl
建立 ProtectedApplication
,方式與建立其他 Kubernetes 資源相同。
這些都是選填。如果沒有 ProtectedApplication
資源,Backup for GKE 會為備份範圍內的所有磁碟區建立磁碟區備份,且產生的磁碟區備份會保持當機一致性,也就是擷取特定時間點排清至磁碟的所有寫入作業 (即沒有部分寫入作業)。不過,部分應用程式可能會將資料保留在記憶體中,而不會清除至磁碟,因此應用程式是否能從當機一致性備份成功復原,取決於應用程式邏輯。
選取資源
建構 ProtectedApplication
資源的第一步,是找出要納入應用程式的相同 Namespace
中的其他資源。如果您在 BackupPlan
設定中提供 selectedApplications 範圍選項,系統就會備份或還原這組資源。
資源是使用標籤選取器識別。如要使用這項功能,您必須為所有資源加上相同標籤 (使用每個資源中的 metadata.label
欄位)。請注意,這也適用於控制器自動建立的資源。這些自動建立的資源會使用對應的範本標示。請注意,您通常會重複使用已有的標籤,將產生的 Pods
和 PersistentVolumeClaims
與父項資源建立關聯。
使用注意事項包括:
- 如要保護會建立子資源的資源,父項資源 (例如
StatefulSet
、Deployment
或DaemonSet
) 和子資源 (例如Pod
或PersistentVolumeClaim
) 都必須具有ProtectedApplication
的Selector
欄位中使用的標籤。 - 如果
ProtectedApplication
參照的部分資源是由運算子自動建立,您也應在ProtectedApplication
選取器中加入運算子的自訂資源。這有助於避免還原時發生競爭情況,因為當運算子嘗試建立資源時,系統會同時從備份還原資源。
以下範例說明如何將 app: nginx
標籤套用至 Deployment
以外的其他資源。
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-vars
namespace: webserver
labels:
app: nginx
data:
...
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-logs
namespace: webserver
labels:
app: nginx
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
storageClassName: standard-rwo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: webserver
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: nginx-logs
persistentVolumeClaim:
claimName: nginx-logs
containers:
...
將所選標籤套用至所有目標資源 (以及產生其他資源的範本) 後,您就可以從 ProtectedApplication
參照這些資源。例如:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: webserver
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
...
定義自動化調度管理規則
找出 ProtectedApplication
中的所有資源後,您可以選擇為部分資源定義詳細的協調規則。這些規則可能只適用於兩類資源:
部署作業和 StatefulSets,並在 ProtectedApplication
的 components
區段中參照。
元件總覽
設定元件時,請執行下列操作:
選取備份和還原這個元件的基本策略。共有三種策略可供選擇:
BackupAllRestoreAll
- 備份與元件所有執行個體相關聯的磁碟區,並從備份還原所有磁碟區。BackupOneRestoreAll
- 僅從元件的一個執行個體備份磁碟區,並使用這些備份還原所有執行個體。DumpAndLoad
- 在備份時將資料從應用程式匯出至單一磁碟區,並在還原時將該資料匯入應用程式。
定義在備份期間執行的執行掛鉤 (可能也會在還原期間執行,視策略而定)。Hook 是在特定容器中執行的指令。
執行掛鉤
在備份或還原程序的特定階段,GKE 備份服務會在容器中執行 Shell 指令,這就是所謂的「掛鉤」。
有四種不同類型的 Hook:
pre hooks
- 這些指令會在備份磁碟區前執行,一般預期會將記憶體中的所有資料排清至磁碟,然後讓應用程式進入靜止狀態,以免發生新的磁碟寫入作業。這些掛鉤用於BackupAllRestoreAll
和BackupOneRestoreAll
策略。post hooks
- 這些指令會在磁碟區備份程序中執行,時間點是磁碟區備份程序的 SNAPSHOTTING 步驟完成後,以及 UPLOADING 步驟開始前。一般來說,SNAPSHOTTING 步驟只需要幾秒鐘。 這類事件通常會解除應用程式的暫停狀態 (即允許正常處理程序和磁碟寫入作業繼續進行)。這些掛鉤會用於BackupAllRestoreAll
、BackupOneRestoreAll
和DumpAndLoad
策略。dump hooks
- 這些指令會在DumpAndLoad
策略備份磁碟區之前執行,一般預期會將應用程式中的資料匯出至指定的備份磁碟區。load hooks
- 這些指令會在備份磁碟區還原後,於還原時間執行 (適用於DumpAndLoad
策略)。一般來說,他們會將備份磁碟區的資料匯入應用程式。
您可以為每種類型提供多個勾點,Backup for GKE 會按照您定義的順序執行這些勾點。
您可以在 ProtectedApplication
規格的元件部分定義 Hook。所有掛鉤定義都有相同的可用欄位:
name
:您指派給 Hook 的名稱。container
- (選用) 要在其中執行指令的容器名稱。如未提供容器,Backup for GKE 會在為目標Pod
定義的第一個容器中執行掛鉤。command
:這是傳送至容器的實際指令,以字詞陣列的形式建構。陣列中的第一個字是指令路徑,後續的字則是要傳遞給指令的引數。timeoutSeconds
- (選用) 中止執行前等待的時間。如果您未提供這個選項,系統會預設為 30 秒。onError
- (選用) 勾點失敗時採取的行為。可以設為Ignore
或Fail
(預設)。 如果將此值設為Fail
,當其中一個掛鉤失敗時,磁碟區備份作業就會失敗。如果將此值設為Ignore
,系統會忽略這個 Hook 的失敗情形。
將 ProtectedApplication
勾點套用至應用程式前,請先使用 kubectl exec
測試指令,確保勾點行為符合預期:
kubectl exec POD_NAME -- COMMAND
更改下列內容:
POD_NAME
:包含ProtectedApplication
資源的 Pod 名稱。COMMAND
:包含要在容器中執行的指令的陣列。
選取要備份的磁碟區子集
有時應用程式會寫入不需還原的磁碟區 (例如特定記錄或暫存磁碟區)。您可以使用磁碟區選取器,禁止備份這些磁碟區。
如要使用這項功能,請先將通用標籤套用至要備份的磁碟區PersistentVolumeClaim
資源。此外,如要避免備份磁碟區的 PersistentVolumeClaim
資源,請務必關閉這個標籤。然後,在元件定義中加入 volumeSelector
子句,如下所示:
spec:
...
components:
...
strategy:
...
volumeSelector:
matchLabels:
label_name: label_value
如果您為元件提供 volumeSelector
,則只有 PersistentVolumeClaim
資源具有指定標籤的磁碟區會備份及還原。還原時,系統會佈建其他磁碟區,但不會從磁碟區備份還原,而是佈建為空白磁碟區。
策略:BackupAllRestoreAll
這是最簡單的策略,可在備份時備份所有元件的磁碟區,並在還原時從磁碟區備份還原所有元件。如果應用程式在 Pods
之間沒有任何複寫作業,這是最佳選擇。
這項策略支援下列參數:
backupPreHooks
- (選用) 勾點的排序清單,會在備份磁碟區前執行。這些指令會在元件中的所有Pods
上執行。backupPostHooks
- (選用) hook 的排序清單,會在磁碟區備份達到 UPLOADING 階段後執行。這些指令會在元件中的所有Pods
上執行。volumeSelector
- (選用) 將部分磁碟區與備份項目比對的邏輯。
這個範例會建立 ProtectedApplication
資源,在備份記錄磁碟區前先停止檔案系統,備份完成後再繼續執行:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: sales
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
components:
- name: nginx-app
resourceKind: Deployment
resourceNames: ["nginx-deployment"]
strategy:
type: BackupAllRestoreAll
backupAllRestoreAll:
backupPreHooks:
- name: freeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to flush data to disk before snapshot
# and freeze the application from further changes.
echo "Freezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
backupPostHooks:
- name: unfreeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to unfreeze the application.
echo "Unfreezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
策略:BackupOneAndRestoreAll
這項策略會備份所選 Pod 的副本。這個單一副本是還原期間所有 Pod 的還原來源。這個方法有助於降低儲存成本和備份時間。當元件部署一個主要 PersistentVolumeClaim
和多個次要 PersistentVolumeClaims
時,這項策略適用於高可用性設定。
這項策略支援下列參數:
backupTargetName
- (必要) 指定要用來備份資料的 Deployment 或 StatefulSet。系統會自動選取最適合備份的 Pod。在高可用性設定中,建議您將此值設為其中一個應用程式副本。backupPreHooks
- (選用) 勾點的排序清單,會在備份磁碟區前執行。這些指令只會在選取的備份Pod
上執行。backupPostHooks
- (選用) hook 的排序清單,會在磁碟區備份達到 UPLOADING 階段後執行。這些指令只會在選取的備份Pod
上執行。volumeSelector
- (選用) 將部分磁碟區與備份項目比對的邏輯。
如果元件設定了多個 Deployment 或 StatefulSet,所有資源都必須具有相同的 PersistentVolume 結構,也就是必須遵守下列規則:
- 所有部署或 StatefulSet 使用的
PersistentVolumeClaims
數量必須相同。 - 相同索引中的
PersistentVolumeClaims
必須具有相同用途。如果是 StatefulSet,索引會在volumeClaimTemplate
中定義。如果是 Deployment,索引會在Volumes
中定義,且系統會略過所有非永久磁碟區。 - 如果應用程式元件包含部署項目,則每個部署項目都必須有一個副本。
考量到這些因素,您可以選取多個磁碟區集進行備份, 但每個磁碟區集只會選取一個磁碟區。
假設架構為一個主要 StatefulSet 和一個次要 StatefulSet,以下範例會顯示次要 StatefulSet 中一個 Pod 的磁碟區備份作業,以及所有其他磁碟區的還原作業:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: BackupOneRestoreAll
backupOneRestoreAll:
backupTargetName: mariadb-secondary
backupPreHooks:
- name: quiesce
container: mariadb
command: [...]
backupPostHooks:
- name: unquiesce
container: mariadb
command: [...]
策略:DumpAndLoad
這項策略會使用專屬磁碟區進行備份和還原程序,且需要專屬的 PersistentVolumeClaim
連接至儲存傾印資料的元件。
這項策略支援下列參數:
dumpTarget
- (必要) 指定要用來備份資料的 Deployment 或 StatefulSet。系統會自動選取最適合備份的 Pod。在高可用性設定中,建議您將此值設為其中一個應用程式副本。loadTarget
- (必要) 指定應使用哪個 Deployment 或 StatefulSet 載入資料。系統會自動選取最適合備份的 Pod。載入目標不必與傾印目標相同。dumpHooks
- (必要) hook 的排序清單,用於執行填入專屬備份磁碟區的作業。這些指令只會在所選傾印Pod
上執行。backupPostHooks
- (選用) hook 的排序清單,會在磁碟區備份達到 UPLOADING 階段後執行。這些指令只會在選取的傾印Pod
上執行。loadHooks
- (必要) hook 的排序清單,應用程式啟動後會執行這些 hook,從還原的磁碟區載入資料。這些指令只會在所選負載Pod
上執行。volumeSelector
- (必要) 將單一磁碟區與備份和還原 (「傾印」磁碟區) 相符的邏輯。雖然這項設定只能比對單一磁碟區,但設定方式與其他策略使用的備份磁碟區子集相同。
如果應用程式包含部署項目,每個部署項目都必須有一個副本。
假設架構為一個主要 StatefulSet 和一個次要 StatefulSet,且主要和次要 StatefulSet 都有專屬的 PersistentVolumeClaims
,這個範例會顯示 DumpAndLoad
策略:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb-dump
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: DumpAndLoad
dumpAndLoad:
loadTarget: mariadb-primary
dumpTarget: mariadb-secondary
dumpHooks:
- name: db_dump
container: mariadb
command:
- bash
- "-c"
- |
mysqldump -u root --all-databases > /backup/mysql_backup.dump
loadHooks:
- name: db_load
container: mariadb
command:
- bash
- "-c"
- |
mysql -u root < /backup/mysql_backup.sql
volumeSelector:
matchLabels:
gkebackup.gke.io/backup: dedicated-volume
確認 ProtectedApplication
是否可備份
如要檢查 ProtectedApplication
是否已準備好備份,請執行下列指令:
kubectl describe protectedapplication APPLICATION_NAME
將 APPLICATION_NAME
替換為應用程式名稱。
如果準備就緒,應用程式說明會顯示 Ready to backup
狀態為 true
,如下例所示:
% kubectl describe protectedapplication nginx
Name: nginx
Namespace: default
API Version: gkebackup.gke.io/v1
Kind: ProtectedApplication
Metadata:
UID: 90c04a86-9dcd-48f2-abbf-5d84f979b2c2
Spec:
Components:
Name: nginx
Resource Kind: Deployment
Resource Names:
nginx
Strategy:
Backup All Restore All:
Backup Pre Hooks:
Command:
/sbin/fsfreeze
-f
/var/log/nginx
Container: nginx
Name: freeze
Backup Post Hooks:
Command:
/sbin/fsfreeze
-u
/var/log/nginx
Container: nginx
Name: unfreeze
Type: BackupAllRestoreAll
Resource Selection:
Selector:
Match Labels:
app: nginx
Type: Selector
Status:
Ready To Backup: true
Events: <none>
後續步驟
- 進一步瞭解如何規劃備份作業集。