커스텀 백업 및 복원 로직 정의


Google Kubernetes Engine 클러스터에서 Backup for GKE 에이전트를 사용 설정하면 Backup for GKE가 새로운 종류의 Kubernetes 리소스인 ProtectedApplication을 도입하는 CustomResourceDefinition을 제공합니다.

ProtectedApplication 구성에는 다음 두 가지 활동이 포함됩니다.

ProtectedApplication 리소스는 애플리케이션 수준에서 백업 및 복원 로직을 맞춤설정할 때 이러한 기능을 제공합니다.

  • 더욱 세분화된 백업 및 복원 작업. ProtectedApplications가 없으면 백업 범위는 allNamespaces 또는 selectedNamespaces를 선택하여 Namespace 수준에 정의되어야 합니다. 네임스페이스 범위 리소스 복원에도 유사한 로직이 적용됩니다. ProtectedApplication 리소스를 만들면 Namespace의 리소스 하위 집합에 이름을 제공할 수 있습니다. 그런 다음 백업 범위(및 마찬가지로 복원)에 selectedApplications를 나열하여 해당 하위 집합을 백업 및 복원할 수 있습니다.

  • 다음을 포함하여 백업 또는 복원 프로세스의 세분화된 세부정보를 조정합니다.

    • 백업 중 선택한 볼륨을 건너뜁니다.

    • 애플리케이션 토폴로지를 백업 및 복원에 통합(예: 복제된 데이터베이스의 인스턴스 한 개만 백업하고 이를 사용하여 여러 인스턴스를 복원)

    • 볼륨 스냅샷 생성 전후의 사용자 정의 후크 실행. 예를 들어 스냅샷을 생성하기 전에 워크로드를 플러시하고 정지한 후 정지 해제를 수행하는 데 사용할 수 있습니다.

다른 Kubernetes 리소스와 마찬가지로 kubectl을 통해 ProtectedApplication을 만듭니다. 이러한 리소스는 완전히 선택사항입니다. 만약 ProtectedApplication 리소스가 없으면 Backup for GKE는 백업 범위 내 모든 볼륨에 대한 볼륨 백업을 만들고, 만들어지는 볼륨 백업은 장애 일관성을 갖게 되어 특정 시점에 디스크에 플러시되는 모든 쓰기가 캡처됩니다(부분 쓰기 아님) 그러나 일부 애플리케이션은 디스크에 플러시되지 않는 데이터를 메모리에 유지할 수 있으므로 애플리케이션이 장애 일관성이 있는 백업에서 성공적으로 복구할 수 있는지 여부는 애플리케이션 로직에 따라 달라집니다.

리소스 선택

ProtectedApplication 리소스를 빌드하는 첫 번째 단계는 애플리케이션의 일부로 포함할 동일한 Namespace의 다른 리소스를 식별하는 것입니다. BackupPlan 구성에서 selectedApplications 범위 옵션을 제공하는 경우 백업 또는 복원되는 리소스 집합입니다.

리소스는 라벨 선택기를 사용하여 식별됩니다. 이렇게 하려면 모든 리소스에 동일한 라벨을 지정(각 리소스의 metadata.label 필드 사용)해야 합니다. 이는 컨트롤러에서 자동으로 생성된 리소스에도 적용됩니다. 이렇게 자동 생성된 리소스는 해당 템플릿을 사용하여 라벨이 지정됩니다. 생성된 PodsPersistentVolumeClaims를 상위 리소스와 연결하는 데 이미 사용 중인 동일한 라벨을 다시 사용하는 것이 일반적입니다. 다음 예시에서는 Deployment 외에 다른 리소스에 app: nginx 라벨을 적용하는 방법을 보여줍니다.

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/v1alpha2
metadata:
  name: nginx
  namespace: webserver
spec:
  resourceSelection:
    type: Selector
    selector:
      matchLabels:
        app: nginx
  ...

조정 규칙 정의

ProtectedApplication의 모든 리소스를 식별했으면 이러한 리소스의 하위 집합에 대한 자세한 조정 규칙을 정의할 수 있습니다. 이러한 규칙은 배포StatefulSet 두 가지 종류의 리소스에만 적용할 수 있으며 ProtectedApplicationcomponents 섹션에서 참조됩니다.

구성요소 개요

구성요소를 구성하려면 다음 작업을 수행합니다.

  • 이 구성요소에 백업 및 복원이 작동하는 방식에 대한 기본 전략을 선택합니다. 다음과 같은 세 가지 전략이 있습니다.

    • BackupAllRestoreAll - 구성요소의 모든 인스턴스와 연결된 볼륨을 백업하고 백업에서 모두 복원합니다.

    • BackupOneRestoreAll - 구성요소의 한 인스턴스에서만 볼륨을 백업하고 이러한 백업을 사용하여 모든 인스턴스를 복원합니다.

    • DumpAndLoad - 백업 시 애플리케이션에서 단일 볼륨으로 데이터를 내보내고 복원 시 해당 데이터를 애플리케이션으로 가져옵니다.

  • 백업 중 실행할 후크 정의(전략에 따라 복원할 수 있음). 후크는 특정 컨테이너에서 실행되는 명령어입니다.

  • 백업할 볼륨의 하위 집합 선택.

실행 후크

후크는 Backup for GKE가 백업 또는 복원 프로세스의 특정 단계에서 컨테이너에서 실행하는 셸 명령어입니다.

후크에는 4가지 유형이 있습니다.

  • pre hooks - 이 명령어는 볼륨이 백업되기 직전에 실행되며 일반적으로 메모리의 데이터를 디스크에 플러시한 후 애플리케이션을 정지하여 새로운 디스크 쓰기가 발생하지 않도록 합니다. 이러한 후크는 BackupAllRestoreAllBackupOneRestoreAll 전략에 사용됩니다.

  • post hooks - 이러한 명령어는 볼륨 백업 프로세스의 스냅샷 생성 단계 바로 다음(업로드 단계 전)의 볼륨 백업 프로세스 중에 실행됩니다. 일반적으로 스냅샷 생성 단계는 몇 초 정도 걸립니다. 일반적으로 애플리케이션 중단이 해제될 것으로 예상됩니다(즉, 정상적인 처리 및 디스크 쓰기를 허용). 이러한 후크는 BackupAllRestoreAll, BackupOneRestoreAll, DumpAndLoad 전략에 사용됩니다.

  • dump hooks - 이 명령어는 볼륨이 DumpAndLoad 전략에 백업되기 전에 실행되며 일반적으로 애플리케이션에서 지정된 백업 볼륨으로 데이터를 내보내야 합니다.

  • load hooks - 이러한 명령어는 DumpAndLoad 전략 사례에서 백업 볼륨이 복원된 후 복원 시 실행됩니다. 일반적으로 백업 볼륨에서 애플리케이션으로 데이터를 가져올 것으로 예상됩니다.

각 유형에 둘 이상의 후크를 제공할 수 있으며 Backup for GKE는 정의한 순서대로 실행합니다.

ProtectedApplication 사양의 구성요소 섹션의 일부로 후크를 정의합니다. 모든 후크 정의에는 동일하게 사용 가능한 필드가 있습니다.

  • name - 후크에 할당한 이름입니다.

  • container - (선택사항) 명령어를 실행할 컨테이너의 이름입니다. 컨테이너를 제공하지 않으면 Backup for GKE가 대상 Pod에 정의된 첫 번째 컨테이너에서 후크를 실행합니다.

  • command - 컨테이너로 전송되는 실제 명령어이며 단어 배열로 구성됩니다. 배열의 첫 번째 단어는 명령어의 경로이고 이후 단어는 명령어에 전달되는 인수입니다.

  • timeoutSeconds - (선택사항) 후크 실행이 취소되기 전까지의 시간입니다. 이 값을 제공하지 않으면 기본값은 30초입니다.

  • onError - (선택사항) 후크가 실패할 때 수행되는 동작입니다. Ignore 또는 Fail(기본값)로 설정할 수 있습니다. 이를 Fail로 설정하면 후크가 실패할 때 볼륨 백업이 실패합니다. 이를 Ignore로 설정하면 이 후크의 실패가 무시됩니다.

애플리케이션에 ProtectedApplication 후크를 적용하기 전에 kubectl exec를 사용하여 명령어를 테스트해 후크가 예상대로 동작하는지 확인해야 합니다.

kubectl exec POD_NAME -- COMMAND

다음을 바꿉니다.

  • POD_NAME: ProtectedApplication 리소스가 포함된 포드의 이름입니다.
  • COMMAND: 컨테이너에서 실행할 명령어가 포함된 배열입니다(예: /sbin/fsfreeze, -f, /var/log/nginx).

백업할 볼륨의 하위 집합 선택

일부 경우에는 애플리케이션이 복원하고자 하지 않는 볼륨(예: 특정 로그 또는 스크래치 볼륨)에 쓰기를 수행할 수 있습니다. 볼륨 선택기를 사용하여 이러한 볼륨의 백업을 억제할 수 있습니다.

이 기능을 사용하려면 먼저 백업하려는 볼륨에 공통 라벨을 적용한 다음 백업을 원하지 않는 볼륨 에서 이 라벨을 제거합니다. 그런 후 다음과 같이 구성요소 정의에 volumeSelector 절을 포함합니다.

spec:
  ...
  components:
  ...
    strategy:
      ...
      volumeSelector:
        matchLabels:
          label_name: label_value

구성요소에 volumeSelector를 제공하면 지정된 라벨이 있는 볼륨만 백업 및 복원됩니다. 복원 시에는 볼륨 백업에서 복원되는 대신 다른 볼륨이 빈 상태로 프로비저닝됩니다.

전략: BackupAllRestoreAll

이는 가장 간단한 전략이며 백업 시 모든 구성요소 볼륨을 백업하고 복원 시 볼륨 백업에서 모두 복원합니다. 애플리케이션에서 Pods 간에 복제가 없을 때 이 방법이 가장 좋습니다.

이 전략은 다음 매개변수를 지원합니다.

  • backupPreHooks - (선택사항) 볼륨이 백업되기 직전에 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 구성요소의 모든 Pods에서 실행됩니다.

  • backupPostHooks - (선택사항) 볼륨 백업이 업로드 단계에 도달한 후 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 구성요소의 모든 Pods에서 실행됩니다.

  • volumeSelector - (선택사항) 백업할 볼륨의 하위 집합을 일치시키는 로직입니다.

이 예시에서는 로그 볼륨을 백업하기 전에 파일 시스템을 정지하고 백업 후 정지 해제하는 ProtectedApplication 리소스를 만듭니다.

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
metadata:
  name: nginx
  namespace: sales
spec:
  resourceSelection:
    type: Selector
    selector:
      matchLabels:
        app: nginx
  components:
  - name: nginx-app
    resourceKind: Deployment
    resourceNames: ["nginx"]
    strategy:
      type: BackupAllRestoreAll
      backupAllRestoreAll:
        backupPreHooks:
        - name: fsfreeze
          container: nginx
          command: [ /sbin/fsfreeze, -f, /var/log/nginx ]
        backupPostHooks:
        - name: fsunfreeze
          container: nginx
          command: [ /sbin/fsfreeze, -u, /var/log/nginx ]

전략: BackupOneAndRestoreAll

이 전략은 선택한 포드의 사본 하나를 백업합니다. 이 단일 사본이 복원 중 모든 포드를 복원하기 위한 소스입니다. 이 메서드는 스토리지 비용 및 백업 시간을 줄이는 데 도움이 됩니다. 이 전략은 구성 요소가 하나의 기본 PersistentVolumeClaim과 여러 개의 보조 PersistentVolumeClaims로 배포되는 고가용성 구성에서 사용됩니다.

이 전략은 다음 매개변수를 지원합니다.

  • backupTargetName - (필수) 데이터를 백업하는 데 사용할 배포 또는 StatefulSet를 지정합니다. 최상의 백업 포드가 자동으로 선택됩니다. 고가용성 구성에서는 이를 애플리케이션 복제본 중 하나로 설정하는 것이 좋습니다.

  • backupPreHooks - (선택사항) 볼륨이 백업되기 직전에 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 선택된 백업 Pod에서만 실행됩니다.

  • backupPostHooks - (선택사항) 볼륨 백업이 업로드 단계에 도달한 후 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 선택된 백업 Pod에서만 실행됩니다.

  • volumeSelector - (선택사항) 백업할 볼륨의 하위 집합을 일치시키는 로직입니다.

구성요소가 여러 개의 배포 또는 StatefulSet로 구성된 경우 모든 리소스의 PersistentVolume 구조가 동일해야 합니다. 즉, 다음 규칙을 따라야 합니다.

  • 모든 배포 또는 StatefulSet에 사용되는 PersistentVolumeClaims 수가 동일해야 합니다.
  • 동일한 색인에 있는 PersistentVolumeClaims의 목적이 동일해야 합니다. StatefulSet의 경우 색인이 volumeClaimTemplate에 정의됩니다. 배포의 경우 색인이 Volumes에 정의되고 모든 비영구 볼륨을 건너뜁니다.
  • 애플리케이션 구성요소가 배포로 구성된 경우 각 배포는 정확히 하나의 복제본을 포함해야 합니다.

이러한 조건들을 고려하면 백업에 여러 개의 볼륨 집합을 선택할 수 있지만 각 볼륨 집합에서 하나의 볼륨만 선택됩니다.

이 예시에서는 기본 StatefulSet 하나와 보조 StatefulSet 하나로 이뤄진 구조를 가정해서 보조 StatefulSet에 있는 한 포드의 볼륨 백업과 다른 모든 볼륨에 대한 복원을 보여줍니다.

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
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 - (필수) 데이터를 백업하는 데 사용할 배포 또는 StatefulSet를 지정합니다. 최상의 백업 포드가 자동으로 선택됩니다. 고가용성 구성에서는 이를 애플리케이션 복제본 중 하나로 설정하는 것이 좋습니다.

  • loadTarget - (필수) 데이터를 로드하는 데 사용할 배포 또는 StatefulSet를 지정합니다. 최상의 백업 포드가 자동으로 선택됩니다. 로드 대상은 덤프 대상과 동일할 필요가 없습니다.

  • dumpHooks - (필수) 전용 백업 볼륨을 채우기 위해 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 선택된 덤프 Pod에서만 실행됩니다.

  • backupPostHooks - (선택사항) 볼륨 백업이 업로드 단계에 도달한 후 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 선택된 덤프 Pod에서만 실행됩니다.

  • loadHooks - (필수) 애플리케이션 시작 후 복원된 볼륨에서 데이터를 로드하기 위해 실행되는 후크의 순서가 지정된 목록입니다. 이러한 명령어는 선택된 로드 Pod에서만 실행됩니다.

  • volumeSelector - (필수) 단일 볼륨을 ('덤프' 볼륨) 백업 및 복원과 일치시키기 위한 로직입니다. 단일 볼륨만 일치해야 하지만 다른 전략에서 사용하는 백업할 볼륨 하위 집합과 동일한 방식으로 구성합니다.

애플리케이션이 배포로 구성된 경우 각 배포는 정확히 하나의 복제본을 포함해야 합니다.

이 예시에서는 하나의 기본 StatefulSet와 보조 StatefulSet에 전용 PersistentVolumeClaims가 있는 아키텍처를 가정하고 DumpAndLoad 전략을 보여줍니다.

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
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/v1alpha2
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>

다음 단계