본문 바로가기
WIKI 기술 지식 베이스

부록 C - 백업용 공통 오브젝트 스토어

원문 보기 위키 갱신

CloudNativePG 백업 파일을 AWS S3, Azure Blob Storage, Google Cloud Storage에 저장하는 방법을 인증 방식별로 살펴볼게요. 각 프로바이더에 맞는 시크릿 생성과 클러스터 구성 예시를 정리했어요.

출처: 문서

본문

:::warning CloudNativePG 1.26부터 네이티브 Barman Cloud 지원은 더 이상 사용되지 않으며(deprecated), Barman Cloud Plugin이 이를 대신해요. 네이티브 통합은 당분간 기능하지만, 적절한 테스트 후 플러그인 기반 인터페이스로 점진적 마이그레이션을 시작할 것을 강력히 권장해요. Barman Cloud Plugin 문서에는 공통 오브젝트 스토어 사용 방법이 설명되어 있어요. :::

백업 파일을 Barman Cloud 인프라에서 지원되는 모든 서비스에 저장할 수 있어요:

지원되는 서비스의 호환 구현도 사용할 수 있어요.

필요한 설정은 선택한 스토리지 프로바이더에 따라 다르며 다음 섹션에서 다뤄요.

:::note 인증 방법 CloudNativePG는 barman-cloud가 지원하는 모든 인증 방법을 독립적으로 테스트하지 않아요. CloudNativePG의 책임은 제공된 자격 증명을 barman-cloud에 전달하는 것으로 제한되며, 이후 인증은 barman-cloud의 자체 구현에 따라 처리돼요. 사용자는 Barman Cloud 문서를 참고해 선택한 인증 방법이 지원되고 올바르게 구성되었는지 확인해야 해요. :::

AWS S3

AWS Simple Storage Service (S3)는 Amazon이 제공하는 매우 인기 있는 오브젝트 스토리지 서비스예요.

CloudNativePG 백업과 관련해 S3 버킷에 백업을 저장할 권한을 두 가지 방식으로 정의할 수 있어요:

  • CloudNativePG가 EKS에서 실행 중이라면 IRSA 인증 방법을 사용할 수 있어요
  • 또는 ACCESS_KEY_ID와 ACCESS_SECRET_KEY 자격 증명을 사용할 수 있어요

AWS Access key

환경에 대한 다음 정보가 필요해요:

  • ACCESS_KEY_ID: S3에 파일을 업로드하는 데 사용될 액세스 키의 ID

  • ACCESS_SECRET_KEY: 위 액세스 키의 시크릿 부분

  • ACCESS_SESSION_TOKEN: 필요한 경우 선택적인 세션 토큰

사용되는 액세스 키는 버킷에 파일을 업로드할 권한이 있어야 해요. 자격 증명으로 Kubernetes 시크릿을 만들어야 하며, 다음 명령으로 할 수 있어요:

kubectl create secret generic aws-creds \
  --from-literal=ACCESS_KEY_ID=<access key here> \
  --from-literal=ACCESS_SECRET_KEY=<secret key here>
# --from-literal=ACCESS_SESSION_TOKEN=<session token here> # if required

자격 증명은 Kubernetes 안에 저장되며, 설치에서 저장 중 암호화(encryption at rest)가 구성되어 있으면 암호화돼요.

시크릿이 생성되면 다음과 같이 클러스터를 구성할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "<destination path here>"
      s3Credentials:
        accessKeyId:
          name: aws-creds
          key: ACCESS_KEY_ID
        secretAccessKey:
          name: aws-creds
          key: ACCESS_SECRET_KEY

destination path는 인스턴스가 WAL 파일을 업로드할 수 있는 폴더를 가리키는 모든 URL일 수 있어요. 예: s3://BUCKET_NAME/path/to/folder.

Service Account용 IAM 역할 (IRSA)

IRSA를 사용하려면 Postgres 클러스터의 ServiceAccount에 annotation을 설정해야 해요.

CloudNativePG가 serviceAccountTemplate stanza로 이를 주입하도록 구성할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
[...]
spec:
  serviceAccountTemplate:
    metadata:
      annotations:
        eks.amazonaws.com/role-arn: arn:[...]
        [...]

S3 수명 주기 정책

Barman Cloud는 S3에 오브젝트를 쓴 다음, Barman Cloud 보존 정책이 삭제할 때까지 업데이트하지 않아요. S3 수명 주기 정책에 대한 권장 접근 방식은 Barman 보존 정책보다 며칠 더 길게 오브젝트의 현재 버전을 만료시키고, 오브젝트 버전 관리(versioning)를 활성화하며, 며칠 후 비현재 버전을 만료시키는 것이에요. 이러한 정책은 우발적 삭제를 방지하고, CloudNativePG 워크로드가 S3에서 오브젝트를 삭제할 수 있으면서도 오브젝트를 영구 삭제할 권한은 부여하지 않도록 권한을 제한할 수 있게 해줘요.

기타 S3 호환 오브젝트 스토리지 프로바이더

MinIO나 Linode Object Storage 같은 S3 호환 오브젝트 스토리지를 사용하는 경우, 기본 S3 대신 엔드포인트를 지정할 수 있어요.

이 예시에서는 us-east1 리전의 Linode bucket을 사용해요.

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "s3://bucket/"
      endpointURL: "https://us-east1.linodeobjects.com"
      s3Credentials:
        [...]

Digital Ocean Spaces를 사용하는 경우 Path-style 구문을 사용해야 해요. 이 예시에서는 SFO3 리전의 Digital Ocean Spaces bucket을 사용해요.

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "s3://[your-bucket-name]/[your-backup-folder]/"
      endpointURL: "https://sfo3.digitaloceanspaces.com"
      s3Credentials:
        [...]

:::note Amazon S3 Data Integrity Protections의 boto3 구현에 대한 최근 변경 사항은 x-amz-content-sha256 오류를 유발할 수 있어요. 이 문제가 발생하면 spec.env를 통해 클러스터 레벨에서 특정 환경 변수를 설정하는 다음 해결 방법을 적용할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  env:
    - name: AWS_REQUEST_CHECKSUM_CALCULATION
      value: when_required
    - name: AWS_RESPONSE_CHECKSUM_VALIDATION
      value: when_required

:::

프라이빗 CA로 오브젝트 스토리지 사용하기

프라이빗 CA로 서명된 인증서를 사용하는 오브젝트 스토리지 프로바이더를 구성한다고 가정해 볼게요. 예를 들어 HTTPS를 통한 MinIO 사용 같은 경우예요. 이 경우 Barman이 인증서를 올바르게 검증할 수 있도록 barmanObjectStore 안에 CA 번들을 포함하는 시크릿을 가리키는 endpointCA 옵션을 설정해야 해요. 인증 파일로 시크릿을 만드는 방법에 대한 지침은 certificates 문서에서 찾을 수 있어요. 시크릿을 만든 후 다음 예시처럼 endpointCA를 채울 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  [...]
  backup:
    barmanObjectStore:
      endpointURL: <myEndpointURL>
      endpointCA:
        name: my-ca-secret
        key: ca.crt

:::note 인스턴스가 ConfigMap과 시크릿을 자동으로 리로드하게 하려면, Secrets/ConfigMaps에 cnpg.io/reload 키의 레이블을 추가할 수 있어요. 그렇지 않으면 kubectl cnpg reload 하위 명령으로 인스턴스를 리로드해야 해요. :::

Azure Blob Storage

Azure Blob Storage는 Microsoft가 제공하는 오브젝트 스토리지 서비스예요.

CloudNativePG는 Azure Blob Storage에 대해 다음 인증 방법을 지원해요:

Azure AD Managed Identity를 사용하면 자격 증명을 Kubernetes 시크릿에 저장하지 않고, 다음과 같이 inheritFromAzureAD를 추가한 Cluster 구성을 가질 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "<destination path here>"
      azureCredentials:
        inheritFromAzureAD: true

대안으로 기본 Azure 자격 증명(Default Azure Credentials) 인증 메커니즘을 사용할 수 있어요. 이는 환경 변수, 관리 ID, Azure CLI 자격 증명을 포함한 여러 인증 방법을 지원해 원활한 인증 경험을 제공해요. 다음과 같이 useDefaultAzureCredentials 플래그를 추가하세요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "<destination path here>"
      azureCredentials:
        useDefaultAzureCredentials: true

반면 스토리지 계정 액세스 키 또는 스토리지 계정 SAS 토큰을 모두 사용하려면, 필요할 때만 데이터 항목을 추가해 자격 증명을 Kubernetes 시크릿 안에 저장해야 해요. 다음 명령이 이를 수행해요:

kubectl create secret generic azure-creds \
  --from-literal=AZURE_STORAGE_ACCOUNT=<storage account name> \
  --from-literal=AZURE_STORAGE_KEY=<storage account key> \
  --from-literal=AZURE_STORAGE_SAS_TOKEN=<SAS token> \
  --from-literal=AZURE_STORAGE_CONNECTION_STRING=<connection string>

자격 증명은 사용 중인 Kubernetes 클러스터에서 이 기능이 활성화되어 있으면 저장 중 암호화돼요.

앞선 시크릿이 주어지면, 제공된 자격 증명을 클러스터 구성에 주입할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "<destination path here>"
      azureCredentials:
        connectionString:
          name: azure-creds
          key: AZURE_CONNECTION_STRING
        storageAccount:
          name: azure-creds
          key: AZURE_STORAGE_ACCOUNT
        storageKey:
          name: azure-creds
          key: AZURE_STORAGE_KEY
        storageSasToken:
          name: azure-creds
          key: AZURE_STORAGE_SAS_TOKEN

Azure Blob Storage를 사용할 때 destinationPath는 다음 구조를 충족해요:

<http|https>://<account-name>.<service-name>.core.windows.net/<resource-path>

여기서 <resource-path>는 <container>/<blob>이에요. 계정 이름은 스토리지 계정 이름이라고도 불리며, 사용되는 호스트 이름에 포함돼요.

기타 Azure Blob Storage 호환 프로바이더

Azure Blob Storage API의 다른 구현을 사용한다면 destinationPath는 다음 구조를 가져요:

<http|https>://<local-machine-address>:<port>/<account-name>/<resource-path>

이 경우 <account-name>은 경로의 첫 번째 구성 요소예요.

Azure Storage Emulator나 Azurite를 통해 Azure 지원을 테스트하는 경우 이는 필수예요.

Google Cloud Storage

현재 CloudNativePG 오퍼레이터는 Google Cloud Storage에 대해 두 가지 인증 방법을 지원해요:

  • 첫 번째는 파드가 Google Kubernetes Engine 클러스터 안에서 실행된다고 가정해요
  • 두 번째는 환경 변수 GOOGLE_APPLICATION_CREDENTIALS를 활용해요

Google Kubernetes Engine 안에서 실행하기

Google Kubernetes Engine 안에서 실행하면 자격 증명을 설정하지 않고도 Workload Identity에만 의존하도록 백업을 구성할 수 있어요. 특히 다음을 해야 해요:

  • .spec.backup.barmanObjectStore.googleCredentials.gkeEnvironment를 true로 설정
  • serviceAccountTemplate stanza에 iam.gke.io/gcp-service-account 어노테이션 설정

다음 예시를 참고로 사용하세요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  [...]
  backup:
    barmanObjectStore:
      destinationPath: "gs://<destination path here>"
      googleCredentials:
        gkeEnvironment: true

  serviceAccountTemplate:
    metadata:
      annotations:
        iam.gke.io/gcp-service-account:  [...].iam.gserviceaccount.com
        [...]

인증 사용하기

Google의 지침을 따르면 인증에 필요한 모든 정보를 포함한 JSON 파일을 얻게 돼요.

JSON 파일의 내용은 다음 명령으로 만들 수 있는 Secret을 사용해 제공해야 해요:

kubectl create secret generic backup-creds --from-file=gcsCredentials=gcs_credentials_file.json

이렇게 하면 backup-creds라는 이름의 Secret이 생성되며, yaml 파일에서 다음과 같이 사용할 수 있어요:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
[...]
spec:
  backup:
    barmanObjectStore:
      destinationPath: "gs://<destination path here>"
      googleCredentials:
        applicationCredentials:
          name: backup-creds
          key: gcsCredentials

이제 오퍼레이터는 자격 증명을 사용해 Google Cloud Storage에 인증해요.

:::info[Important] 이러한 방식의 인증은 Google Cloud Storage 버킷에 접근하는 데 필요한 모든 정보를 가진 JSON 파일을 컨테이너 안에 만들어요. 즉 누군가 파드에 접근하면 버킷에 대한 쓰기 권한도 갖게 된다는 뜻이에요. :::

더 알아보기 (Learn more)