次の方法で共有


高可用性 PostgreSQL データベースを AKS にデプロイする

この記事では、高可用性 PostgreSQL データベースを AKS にデプロイします。

重要

オープンソース ソフトウェアは、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 コマンドを使用して、ConfigMap をデプロイして PostgreSQL クラスターの環境変数を設定します。

    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 インスタンスの PodMonitors を作成します。 運用環境では、これらのルールは必要に応じて変更されます。

  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
    

フェデレーション資格情報を作成する

このセクションでは、PostgreSQL バックアップ用のフェデレーション ID 資格情報を作成して、CNPG が AKS ワークロード ID を使用してバックアップ用のストレージ アカウントの保存先に対して認証できるようにします。 CNPG オペレーターは、CNPG クラスター配置マニフェストで使用されるクラスター名と同じ名前の Kubernetes サービス アカウントを作成します。

  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 クラスター インスタンスをホストするポッドにワークロード ID の依存関係を挿入する必要があることを示します。
topologySpreadConstraints ラベル "workload=postgres" がある、異なるゾーンと異なるノードを必要とします。
resources Guaranteed のQoS クラスを構成します。 運用環境では、これらの値は基になるノード VM の使用を最大化するための鍵であり、使用される Azure VM SKU によって異なります。
bootstrap CNPG 演算子に固有です。 空のアプリ データベースを使用して初期化します。
storage / walStorage CNPG 演算子に固有です。 データおよびログ ストレージ用の PersistentVolumeClaims (PVC) のストレージ テンプレートを定義します。 また、IOPS の増加に対してテーブルスペースをシャード アウトするストレージを指定することもできます。
replicationSlots CNPG 演算子に固有です。 高可用性のためにレプリケーション スロットを有効にします。
postgresql CNPG 演算子に固有です。 postgresql.confpg_hba.confpg_ident.conf config 用のマップの設定。
serviceAccountTemplate サービス アカウントを生成し、AKS フェデレーション ID 資格情報を UAMI にマップして、PostgreSQL インスタンスをホストするポッドから外部 Azure リソースへの AKS ワークロードの ID 認証を有効にするために必要なテンプレートが含まれています。
barmanObjectStore CNPG 演算子に固有です。 Azure Blob Storage オブジェクト ストアへの認証に AKS ワークロード ID を使用して、barman-cloud ツール スイートを構成します。

PostgreSQL のパフォーマンス パラメーター

PostgreSQL のパフォーマンスは、クラスターの基になるリソースによって大きく異なります。 次の表では、高パフォーマンスを実現するために主要なパラメーターを計算する方法に関するいくつかの推奨事項を示します。

プロパティ おすすめの値 定義
wal_compression lz4 指定したメソッドを使用して WAL ファイルで書き込まれたページ全体の書き込みを圧縮します
max_wal_size 6 GB チェックポイントをトリガーする 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% データ キャッシュの合計サイズに関するプランナーの想定を設定します
work_mem ノード メモリの 256分の1 クエリ ワークスペースに使用する最大メモリを設定します
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 つのインスタンスが指定されています。これは、各インスタンスを起動して、レプリケーションに参加させた後、実行中のポッドを表示すると検証できます。 3 つのインスタンスすべてがオンラインになってクラスターに参加するまでに時間がかかる場合があるため、しばらくお待ちください。

    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 を使用していて、ポッドがマルチアタッチ エラーで init 状態でスタックしている場合、失われたノード上のボリュームをまだ検索している可能性があります。 ポッドの実行が開始されると、データなしで新しいノードに新しいレプリカが作成され、CNPG で pgdata ディレクトリが見つからないため、ポッドは CrashLoopBackOff 状態になります。 これを解決するには、影響を受けるインスタンスを破棄し、新しいインスタンスを起動する必要があります。 次のコマンドを実行します。

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

Prometheus PodMonitor が実行されていることを検証する

CNPG オペレーターにより、Prometheus Community のインストール中に作成された記録規則を使用して、プライマリ インスタンスの 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
    ...
    

Managed Prometheus 用の Azure Monitor を使用している場合は、カスタム グループ名を使用して別のポッド モニターを追加する必要があります。 Managed Prometheus は、Prometheus コミュニティからカスタム リソース定義 (CRD) を取得しません。 グループ名を除けば、CRD は同じです。 これにより、Managed Prometheus のポッド モニターが、コミュニティ ポッド モニターを使用するポッド モニターと並んで存在できるようになります。 Managed Prometheus を使用していない場合は、これをスキップできます。 新しいポッド モニターを作成します。

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

ポッド モニターが作成されていることを確認します (グループ名の違いに注目してください)。

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 クラスターとポッド モニターをデプロイしたら、Azure Monitor ワークスペースで Azure portal を使用してメトリックを表示できます。

Azure Monitor ワークスペースのメトリックを示すスクリーンショット。

オプション B - Managed Grafana

あるいは、Postgres クラスターとポッド モニターをデプロイしたら、デプロイ スクリプトで作成された Managed Grafana インスタンスにメトリック ダッシュボードを作成して、Azure Monitor ワークスペースにエクスポートされたメトリックを視覚化できます。 Managed Grafana には、Azure portal からアクセスできます。 デプロイ スクリプトによって作成された Managed Grafana インスタンスに移動し、次のように [エンドポイント] リンクをクリックします。

Azure Managed Grafana インスタンスが表示されているスクリーンショット。

[エンドポイント] リンクをクリックすると、新しいブラウザー ウィンドウが開き、Managed Grafana インスタンスにダッシュボードを作成できます。 Azure Monitor データ ソースを構成する手順に従って、視覚化を追加し、Postgres クラスターからメトリックのダッシュボードを作成できます。 データ ソース接続を設定した後、メイン メニューで [データ ソース] オプションをクリックすると、次に示すように、一連のデータ ソース接続のデータ ソース オプションが表示されます。

データ ソース オプションを示すスクリーンショット。

[Managed Prometheus] オプションで、ダッシュボードをビルドするオプションをクリックしてダッシュボード エディターを開きます。 エディター ウィンドウが開いたら、[視覚化の追加] オプションをクリックし、[Managed Prometheus] オプションをクリックして Postgres クラスターからメトリックを参照します。 視覚化するメトリックを選択したら、[クエリの実行] ボタンをクリックして、次に示すように視覚化のデータをフェッチします。

コンストラクト ダッシュボードを示すスクリーンショット。

[保存] ボタンをクリックして、パネルをダッシュボードに追加します。 他のパネルを追加するには、ダッシュボード エディターの [追加] ボタンをクリックし、このプロセスを繰り返して他のメトリックを視覚化します。 メトリックの視覚化を追加すると、次のようになります。

ダッシュボードの保存を示すスクリーンショット。

保存アイコンをクリックしてダッシュボードを保存します。


次のステップ

共同作成者

Microsoft では、この記事を保持しています。 最初の寄稿者は次のとおりです。

  • Ken Kilty | プリンシパル TPM
  • Russell de Pina | プリンシパル TPM
  • Adrian Joian | シニア カスタマー エンジニア
  • Jenny Hayes | シニア コンテンツ開発者
  • Carol Smith | シニア コンテンツ開発者
  • Erin Schaffer |コンテンツ開発者 2
  • Adam Sharif | カスタマー エンジニア 2