다음을 통해 공유


AKS에 고가용성 PostgreSQL 데이터베이스 배포

이 문서에서는 AKS에 고가용성 PostgreSQL 데이터베이스를 배포합니다.

중요함

오픈 소스 소프트웨어는 AKS 설명서와 샘플 전반에서 언급되어 있습니다. 배포하는 소프트웨어는 AKS 서비스 수준 계약, 제한된 보증 및 Azure 지원 제외됩니다. AKS와 함께 오픈 소스 기술을 사용하는 경우 각 커뮤니티 및 프로젝트 유지 관리자에서 사용할 수 있는 지원 옵션을 참조하여 계획을 개발합니다.

예를 들어 Ray GitHub 리포지 토리는 응답 시간, 목적 및 지원 수준에 따라 달라지는 여러 플랫폼을 설명합니다.

Microsoft는 AKS에 배포하는 오픈 소스 패키지를 빌드하는 역할을 담당합니다. 해당 책임에는 컨테이너 이미지의 이진 파일에 대한 제어와 함께 빌드, 스캔, 서명, 유효성 검사 및 핫픽스 프로세스의 완전한 소유권이 포함됩니다. 자세한 내용은 AKS의 취약성 관리AKS 지원 범위를 참조하세요.

부트스트랩 앱 사용자를 위한 비밀 만들기

  1. kubectl create secret 명령을 사용하여 부트스트랩 앱 사용자에 대한 대화형 로그인으로 PostgreSQL 배포의 유효성을 검사하기 위한 비밀을 생성합니다.

    PG_DATABASE_APPUSER_SECRET=$(echo -n | openssl rand -base64 16)
    
    kubectl create secret generic db-user-pass \
        --from-literal=username=app \
        --from-literal=password="${PG_DATABASE_APPUSER_SECRET}" \
        --namespace $PG_NAMESPACE \
        --context $AKS_PRIMARY_CLUSTER_NAME
    
  2. kubectl get 명령을 사용하여 비밀이 성공적으로 만들어졌는지 유효성을 검사합니다.

    kubectl get secret db-user-pass --namespace $PG_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
    

PostgreSQL 클러스터에 대한 환경 변수 설정

  • 다음 kubectl apply 명령을 사용하여 PostgreSQL 클러스터에 대한 환경 변수를 설정하려면 ConfigMap을 배포합니다.

    cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: cnpg-controller-manager-config
    data:
        ENABLE_AZURE_PVC_UPDATES: 'true'
    EOF
    

Prometheus PodMonitors 설치

Prometheus는 CNPG GitHub 샘플 리포지토리에 저장된 기본 녹음/녹화 규칙 집합을 사용하여 CNPG 인스턴스에 대한 PodMonitor를 만듭니다. 프로덕션 환경에서는 이러한 규칙이 필요에 따라 수정됩니다.

  1. helm repo add 명령을 사용하여 Prometheus Community Helm 리포지토리를 추가합니다.

    helm repo add prometheus-community \
        https://prometheus-community.github.io/helm-charts
    
  2. Prometheus Community Helm 리포지토리를 업그레이드하고 helm upgrade 플래그와 함께 --install 명령을 사용하여 기본 클러스터에 설치합니다.

    helm upgrade --install \
        --namespace $PG_NAMESPACE \
        -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/docs/src/samples/monitoring/kube-stack-config.yaml \
        prometheus-community \
        prometheus-community/kube-prometheus-stack \
        --kube-context=$AKS_PRIMARY_CLUSTER_NAME
    

페더레이션 자격 증명 만들기

이 섹션에서는 CNPG가 AKS 워크로드 ID를 사용하여 백업용 스토리지 계정 대상에 인증할 수 있도록 PostgreSQL 백업용 페더레이션된 ID 자격 증명을 만듭니다. CNPG 운영자는 CNPG 클러스터 배포 매니페스트에 사용된 클러스터와 동일한 이름으로 Kubernetes Service 계정을 만듭니다.

  1. az aks show 명령을 사용하여 클러스터의 OIDC 발급자 URL을 가져옵니다.

    export AKS_PRIMARY_CLUSTER_OIDC_ISSUER="$(az aks show \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --query "oidcIssuerProfile.issuerUrl" \
        --output tsv)"
    
  2. az identity federated-credential create 명령을 사용하여 페더레이션 ID 자격 증명을 만듭니다.

    az identity federated-credential create \
        --name $AKS_PRIMARY_CLUSTER_FED_CREDENTIAL_NAME \
        --identity-name $AKS_UAMI_CLUSTER_IDENTITY_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --issuer "${AKS_PRIMARY_CLUSTER_OIDC_ISSUER}" \
        --subject system:serviceaccount:"${PG_NAMESPACE}":"${PG_PRIMARY_CLUSTER_NAME}" \
        --audience api://AzureADTokenExchange
    

고가용성 PostgreSQL 클러스터 배포

이 섹션에서는 CNPG 클러스터 CRD(사용자 지정 리소스 정의)를 사용하여 고가용성 PostgreSQL 클러스터를 배포합니다.

클러스터 CRD 매개 변수

다음 표에는 클러스터 CRD에 대한 YAML 배포 매니페스트에 설정된 주요 속성이 간략하게 설명되어 있습니다.

속성 정의
inheritedMetadata CNPG 운영자에게만 해당됩니다. 메타데이터는 클러스터와 관련된 모든 개체에 상속됩니다.
annotations: service.beta.kubernetes.io/azure-dns-label-name 읽기-쓰기 및 읽기 전용 Postgres 클러스터 엔드포인트를 노출할 때 사용되는 DNS 레이블입니다.
labels: azure.workload.identity/use: "true" AKS가 PostgreSQL 클러스터 인스턴스를 호스팅하는 Pod에 워크로드 ID 종속성을 삽입해야 함을 나타냅니다.
topologySpreadConstraints 레이블이 "workload=postgres"인 다른 영역과 다른 노드가 필요합니다.
resources 보장의 QoS(서비스 품질) 클래스를 구성합니다. 프로덕션 환경에서 이러한 값은 기본 노드 VM의 사용량을 최대화하는 데 중요하며 사용되는 Azure VM SKU에 따라 달라집니다.
bootstrap CNPG 운영자에게만 해당됩니다. 빈 앱 데이터베이스로 초기화합니다.
storage / walStorage CNPG 운영자에게만 해당됩니다. 데이터 및 로그 스토리지를 위한 PVC(PertantVolumeClaim)용 스토리지 템플릿을 정의합니다. IOP를 증가시키기 위해 분할할 테이블스페이스용 스토리지를 지정할 수도 있습니다.
replicationSlots CNPG 운영자에게만 해당됩니다. 고가용성을 위해 복제 슬롯을 사용하도록 설정합니다.
postgresql CNPG 운영자에게만 해당됩니다. postgresql.conf, pg_hba.confpg_ident.conf config에 대한 맵 설정입니다.
serviceAccountTemplate 서비스 계정을 생성하고 AKS 페더레이션된 ID 자격 증명을 UAMI에 매핑하여 PostgreSQL 인스턴스를 호스팅하는 Pod에서 외부 Azure 리소스로 AKS 워크로드 ID 인증을 사용하도록 설정하는 데 필요한 템플릿이 포함되어 있습니다.
barmanObjectStore CNPG 운영자에게만 해당됩니다. Azure Blob Storage 개체 저장소에 대한 인증을 위해 AKS 워크로드 ID를 사용하여 barman-cloud 도구 모음을 구성합니다.

PostgreSQL 성능 매개 변수

PostgreSQL 성능은 클러스터의 기본 리소스에 따라 크게 달라집니다. 다음 표에서는 고성능을 위해 주요 매개 변수를 계산하는 방법에 대한 몇 가지 제안을 제공합니다.

속성 권장 값 정의
wal_compression lz4 지정된 방법을 사용하여 WAL 파일 내에 기록된 전체 페이지 쓰기를 압축합니다.
max_wal_size 6GB 검사점을 트리거하는 WAL 크기 설정
checkpoint_timeout 15분 자동 WAL 검사점 사이의 최대 시간 설정
checkpoint_flush_after 2 MB 이전에 수행한 쓰기가 디스크에 플러시된 후의 페이지 수
wal_writer_flush_after 2 MB 플러시를 트리거하는 WAL 기록기에 의해 작성된 WAL의 양입니다.
min_wal_size 4GB WAL을 축소할 최소 크기를 설정합니다.
shared_buffers 노드 메모리의 25% 서버에서 사용하는 공유 메모리 버퍼 수를 설정합니다.
effective_cache_size 노드 메모리의 75% 데이터 캐시의 총 크기에 대한 Planner의 가정을 설정합니다.
work_mem 노드 메모리의 1/256 부분 쿼리 작업 영역에 사용할 최대 메모리 설정
maintenance_work_mem 노드 메모리의 6.25% 유지 관리 작업에 사용할 최대 메모리 설정
autovacuum_vacuum_cost_limit 2400 자동 진공을 위해 내핑 전에 사용 가능한 진공 비용 금액
random_page_cost 1.1 계획 도구가 디스크 페이지를 비순차적으로 가져오는 데 들 것으로 예상되는 비용을 설정합니다.
effective_io_concurrency 64 디스크 하위 시스템이 효율적으로 처리할 수 있는 동시 요청 수
maintenance_io_concurrency 64 유지 관리 작업에 사용되는 "effective_io_concurrency" 변형

PostgreSQL 배포

  1. kubectl apply 명령을 사용하여 클러스터 CRD로 PostgreSQL 클러스터를 배포합니다.

    cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -v 9 -f -
    apiVersion: postgresql.cnpg.io/v1
    kind: Cluster
    metadata:
      name: $PG_PRIMARY_CLUSTER_NAME
    spec:
      inheritedMetadata:
        annotations:
          service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX
        labels:
          azure.workload.identity/use: "true"
    
      instances: 3
      startDelay: 30
      stopDelay: 30
      minSyncReplicas: 1
      maxSyncReplicas: 1
      replicationSlots:
        highAvailability:
          enabled: true
        updateInterval: 30
    
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            cnpg.io/cluster: $PG_PRIMARY_CLUSTER_NAME
    
      affinity:
        nodeSelector:
          workload: postgres
    
      resources:
        requests:
          memory: '8Gi'
          cpu: 2
        limits:
          memory: '8Gi'
          cpu: 2
    
      bootstrap:
        initdb:
          database: appdb
          owner: app
          secret:
            name: db-user-pass
          dataChecksums: true
    
      storage:
        size: 32Gi
        pvcTemplate:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 32Gi
          storageClassName: $POSTGRES_STORAGE_CLASS
    
      walStorage:
        size: 32Gi
        pvcTemplate:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 32Gi
          storageClassName: $POSTGRES_STORAGE_CLASS
    
      monitoring:
        enablePodMonitor: true
    
      postgresql:
        parameters:
          wal_compression: lz4
          max_wal_size: 6GB
          checkpoint_timeout: 15min
          checkpoint_flush_after: 2MB
          wal_writer_flush_after: 2MB
          min_wal_size: 4GB
          shared_buffers: 4GB
          effective_cache_size: 12GB
          work_mem: 62MB
          maintenance_work_mem: 1GB
          autovacuum_vacuum_cost_limit: "2400"
          random_page_cost: "1.1"
          effective_io_concurrency: "64"
          maintenance_io_concurrency: "64"
        pg_hba:
          - host all all all scram-sha-256
    
      serviceAccountTemplate:
        metadata:
          annotations:
            azure.workload.identity/client-id: "$AKS_UAMI_WORKLOAD_CLIENTID"
          labels:
            azure.workload.identity/use: "true"
    
      backup:
        barmanObjectStore:
          destinationPath: "https://${PG_PRIMARY_STORAGE_ACCOUNT_NAME}.blob.core.windows.net/backups"
          azureCredentials:
            inheritFromAzureAD: true
        retentionPolicy: '7d'
    EOF
    
  1. kubectl get 명령을 사용하여 기본 PostgreSQL 클러스터가 성공적으로 만들어졌는지 유효성을 검사합니다. CNPG 클러스터 CRD는 3개의 인스턴스를 지정했으며, 각 인스턴스가 복제를 위해 실행되고 조인되면 실행 중인 Pod를 확인하여 유효성을 검사할 수 있습니다. 세 인스턴스가 모두 온라인 상태가 되어 클러스터에 참가하는 데 시간이 걸릴 수 있으므로 인내심을 가지고 기다립니다.

    kubectl get pods --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME
    

    예제 출력

    NAME                         READY   STATUS    RESTARTS   AGE
    pg-primary-cnpg-r8c7unrw-1   1/1     Running   0          4m25s
    pg-primary-cnpg-r8c7unrw-2   1/1     Running   0          3m33s
    pg-primary-cnpg-r8c7unrw-3   1/1     Running   0          2m49s
    

중요함

Azure Container Storage에서 로컬 NVMe를 사용 중이고, Pod가 다중 연결 오류로 인하여 init 상태에서 중단되었다면, 그 원인은 손실된 노드에서 볼륨을 아직 찾고 있을 가능성이 높습니다. Pod가 실행되기 시작하면, 새 복제본이 데이터 없이 새 노드에 만들어졌고 CNPG가 pgdata 디렉터리를 찾을 수 없기 때문에, 그것은 CrashLoopBackOff 상태가 됩니다. 이 문제를 해결하려면 영향을 받는 인스턴스를 삭제하고 새 인스턴스를 가져와야 합니다. 다음 명령을 실행합니다.

kubectl cnpg destroy [cnpg-cluster-name] [instance-number]  

Prometheus PodMonitor가 실행 중인지 유효성 검사

CNPG 운영자는 Prometheus 커뮤니티 설치 중에 만들어진 기록 규칙을 사용하여 주 인스턴스용 PodMonitor를 자동으로 만듭니다.

  1. kubectl get 명령을 사용하여 PodMonitor가 실행 중인지 유효성을 검사합니다.

    kubectl --namespace $PG_NAMESPACE \
        --context $AKS_PRIMARY_CLUSTER_NAME \
        get podmonitors.monitoring.coreos.com \
        $PG_PRIMARY_CLUSTER_NAME \
        --output yaml
    

    예제 출력

     kind: PodMonitor
     metadata:
      annotations:
        cnpg.io/operatorVersion: 1.23.1
    ...
    

관리되는 Prometheus용 Azure Monitor를 사용하는 경우 사용자 지정 그룹 이름을 사용하여 다른 Pod 모니터를 추가해야 합니다. 관리형 Prometheus는 Prometheus 커뮤니티의 CRD(사용자 정의 리소스 정의)를 적용하지 않습니다. 그룹 이름 외에 CRD는 동일합니다. 이를 통해 관리형 Prometheus의 파드 모니터가 공동체 파드 모니터를 사용하는 모니터와 나란히 존재할 수 있습니다. 관리되는 Prometheus를 사용하지 않는 경우 이 단계를 건너뛸 수 있습니다. 새 Pod 모니터를 만듭니다.

cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -f -
apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: cnpg-cluster-metrics-managed-prometheus
  namespace: ${PG_NAMESPACE}
  labels:
    azure.workload.identity/use: "true"
    cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
spec:
  selector:
    matchLabels:
      azure.workload.identity/use: "true"
      cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
  podMetricsEndpoints:
    - port: metrics
EOF

Pod 모니터가 만들어졌는지 확인합니다(그룹 이름 차이에 유의해야 함).

kubectl --namespace $PG_NAMESPACE \
    --context $AKS_PRIMARY_CLUSTER_NAME \
    get podmonitors.azmonitoring.coreos.com \
    -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME \
    -o yaml

옵션 A - Azure Monitor 작업 영역

Postgres 클러스터와 Pod 모니터를 배포한 후에는 Azure Monitor 작업 영역에서 Azure Portal을 사용하여 메트릭을 볼 수 있습니다.

Azure Monitor 작업 영역의 메트릭을 보여 주는 스크린샷.

옵션 B - 관리형 Grafana

또는 Postgres 클러스터 및 Pod 모니터를 배포한 후 배포 스크립트로 만들어진 Managed Grafana 인스턴스에 메트릭 대시보드를 만들어 Azure Monitor 작업 영역으로 내보낸 메트릭을 시각화할 수 있습니다. Azure Portal을 통해 Managed Grafana에 액세스할 수 있습니다. 배포 스크립트에서 만들어진 Managed Grafana 인스턴스로 이동하고 여기에 표시된 대로 엔드포인트 링크를 클릭합니다.

Azure Managed Grafana 인스턴스를 보여 주는 스크린샷.

엔드포인트 링크를 클릭하면 Managed Grafana 인스턴스에서 대시보드를 만들 수 있는 새 브라우저 창이 열립니다. Azure Monitor 데이터 원본 구성 지침에 따라 시각화를 추가하여 Postgres 클러스터에서 메트릭 대시보드를 만들 수 있습니다. 데이터 원본 연결을 설정한 후 기본 메뉴에서 데이터 원본 옵션을 클릭하면 다음과 같이 데이터 원본 연결에 대한 데이터 원본 옵션 집합이 표시됩니다.

데이터 원본 옵션을 보여 주는 스크린샷.

관리되는 Prometheus 옵션에서 대시보드 빌드 옵션을 클릭하여 대시보드 편집기를 엽니다. 편집기 창이 열리면 시각화 추가 옵션을 클릭한 다음 관리되는 Prometheus 옵션을 클릭하여 Postgres 클러스터에서 메트릭을 찾습니다. 시각화할 메트릭을 선택한 후 쿼리 실행 단추를 클릭하여 여기에 표시된 대로 시각화에 대한 데이터를 가져옵니다.

구문 대시보드를 보여 주는 스크린샷.

저장 단추를 클릭하여 대시보드에 패널을 추가합니다. 대시보드 편집기에서 추가 단추를 클릭하고 이 프로세스를 반복하여 다른 메트릭을 시각화함으로써 다른 패널을 추가할 수 있습니다. 메트릭 시각화를 추가하면 다음과 같은 모습이 됩니다.

저장 대시보드를 보여 주는 스크린샷.

대시보드를 저장하려면 저장 아이콘을 클릭합니다.


다음 단계

기여자

Microsoft는 이 문서를 유지 관리합니다. 다음 기여자는 원래 그것을 썼다:

  • Ken Kilty | 수석 TPM
  • Russell de Pina | 수석 TPM
  • Adrian Joian | 선임 고객 엔지니어
  • Jenny Hayes | 선임 콘텐츠 개발자
  • Carol Smith | 선임 콘텐츠 개발자
  • Erin Schaffer | 콘텐츠 개발자 2
  • Adam Sharif | 고객 엔지니어 2