부록 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에 대해 다음 인증 방법을 지원해요:
- 연결 문자열(Connection String)
- 스토리지 계정 이름 + 스토리지 계정 액세스 키(Storage Account Access Key)
- 스토리지 계정 이름 + 스토리지 계정 SAS 토큰(Storage Account SAS Token)
- Azure AD 관리 ID(Azure AD Managed Identity)
- 기본 Azure 자격 증명(Default Azure Credentials)
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로 설정serviceAccountTemplatestanza에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 파일을 컨테이너 안에 만들어요. 즉 누군가 파드에 접근하면 버킷에 대한 쓰기 권한도 갖게 된다는 뜻이에요. :::