AlloyDB Omni Kubernetes オペレーターのトラブルシューティング

ドキュメントのバージョンを選択します。

このページでは、AlloyDB Omni Kubernetes オペレーターに関する問題を解決する方法について説明します。

デバッグ情報を収集する

以下のセクションでは、デバッグ用のログと構成を収集する方法について説明します。

オペレーター Pod からログを取得する

オペレーター Pod からログを取得するには、次のコマンドを実行します。

kubectl logs deployments/fleet-controller-manager -c manager -n alloydb-omni-system
kubectl logs deployments/local-controller-manager -c manager -n alloydb-omni-system

データベース Pod のログを取得する

データベース Pod のログを取得するには、次のコマンドを実行します。

kubectl logs al-<id-instance-name>-0 -n db
kubectl logs -l alloydbomni.internal.dbadmin.goog/dbcluster=dbcluster-name -c database -n db

次のログは、データベースのヘルスチェックが成功した例です。

I1106 16:17:28.826188      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:28.826295      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"
I1106 16:17:34.810447      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:34.834844      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"
I1106 16:17:38.825843      30 gateway.go:166] "DatabaseHealthCheck: handling request" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-sample"
I1106 16:17:38.825959      30 gateway.go:184] "DatabaseHealthCheck: request handled successfully" log_name="agent" project_ns="dbc-bugbash" dbcluster="dbcluster-s
ample"

postgresql.log を取得する

postgresql.log を取得するには、次のコマンドを実行します。

kubectl exec -it al-id-instance-name-0 -n db -c database -- cat /obs/diagnostic/postgresql.log

DBInstance YAML ファイルを取得する

DBInstance YAML ファイルを取得するには、次のコマンドを実行します。

kubectl get dbclusters.a <dbcluster-name> -n db -o yaml

HA シナリオの構成とログを取得する

高可用性(HA)シナリオに固有の構成とログを取得するには、次のコマンドを実行します。

kubectl get replicationconfig -n <namespace>
kubectl get deletestandbyjobs.alloydbomni.internal -n <namespace> -o yaml
kubectl get createstandbyjobs.alloydbomni.internal -n <namespace> -o yaml
kubectl get failovers.alloydbomni.dbadmin.goog -n <namespace> -o yaml

Pod と STS のステータスを取得する

Pod と StatefulSet(STS)のステータスを取得するには、次のコマンドを実行します。

kubectl describe pod -n <namespace> <pod-name>
kubectl describe statefulset -n <namespace> al-<id-instance-name>

エラーを特定する

以下のセクションでは、エラーを特定する方法について説明します。

エラー ステータスとエラーコードを確認する

エラーコードを特定するには、ステータスの下の DBCluster YAML ファイルを確認します。詳細については、エラーコードのドキュメントをご覧ください。

DBCluster YAML ファイルを取得するには、次のコマンドを実行します。

kubectl get dbclusters.a <dbcluster-name> -n <dbcluster-namespace> -o yaml

criticalIncidents の検出結果について確認します。このセクションには、エラーコードとスタック トレースが含まれています。

以下に criticalIncidents の例を示します。

status:
    certificateReference:
      certificateKey: ca.crt
      secretRef:
        name: dbs-al-cert-dr-mce
        namespace: dr
    conditions:
    -   lastTransitionTime: "2024-10-07T22:46:03Z"
    ...
    criticalIncidents:
    -   code: DBSE0304
      createTime: "2024-10-03T11:50:54Z"
      message: 'Healthcheck: Health check invalid result.'
      resource:
        component: healthcheck
        location:
          group: alloydbomni.internal.dbadmin.goog
          kind: Instance
          name: bc0f-dr-mce
          namespace: dr
          version: v1
      stackTrace:
      -   component: healthcheck
        message: 'DBSE0304: Healthcheck: Health check invalid result. rpc error: code
          = Code(10304) desc = DBSE0304: Healthcheck: Health check invalid result.
          dbdaemon/healthCheck: invalid timestamp read back from the healthcheck table.
          Lag is 384837.296269 seconds, wanted 35 seconds'

JSON 形式で特定のフィールドを抽出してステータスを取得することもできます。

kubectl get dbcluster.${DBTYPE:?} -n "${PROJECT:?}" "${DBCLUSTER:?}" -o json -o jsonpath='{.status.criticalIncidents}' | jq

出力は次のようになります。

[
  {
    "code": "DBSE0085",
    "createTime": "2024-03-14T05:41:37Z",
    "message": "Platform: Pod is unschedulable.",
    "resource": {
      "component": "provisioning",
      "location": {
        "group": "alloydb.internal.dbadmin.goog",
        "kind": "Instance",
        "name": "b55f-testdbcluster",
        "namespace": "dbs-system",
        "version": "v1"
      }
    },
    "stackTrace": [
      {
        "component": "provisioning",
        "message": "DBSE0085: Platform: Pod is unschedulable. 0/16 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/16 nodes are available: 16 No preemption victims found for incoming pod..: Pod is unschedulable"
      }
    ]
  }
]

エラー メッセージがデータベース Pod を参照している場合は、同じ Namespace のインスタンスと Pod リソースを確認します。

kubectl get instances.a dbcluster_name -n dbcluster_namespace -o yaml
kubectl get pods -l alloydbomni.internal.dbadmin.goog/dbcluster=dbcluster_name -l alloydbomni.internal.dbadmin.goog/task-type=database -n dbcluster_namespace

メモリの問題をデバッグする

以下のセクションでは、メモリの問題をデバッグする方法について説明します。

実行してヒープダンプを取得する

この機能は、トラブルシューティングの目的でのみオンにしてください。後でオフにすることを忘れないでください。

ヒープダンプを取得する手順は次のとおりです。

  1. alloydb-omni-system Namespace 下のオペレーターの Deployment を名前 fleet-controller-managerlocal-controller-manager で変更します。
  2. Pod の --pprof-address=:8642 または使用可能な他のポートに次の引数を追加します。
  3. コントローラ Pod が再起動するまで待ちます。
  4. 上記のポートをポート転送します。例:

    kubectl port-forward -n alloydb-omni-system fleet-controller-manager-pod-name 8642:8642
    
  5. 別のターミナルで go tool pprof http://localhost:8642/debug/pprof/heap を実行します。8642 を使用しない場合は、ポートを前のポートと一致するように変更します。

  6. アドレスに接続して、トラブルシューティング コマンドを実行します。例: top

  7. トラブルシューティングが完了したら、引数を削除して Pod が再起動するのを待つことで、手順 1 を元に戻します。

オペレーターが監視しているリソースの数を特定する

使用中のリソースを把握するには、次のコマンドを実行します。

kubectl get backuprepositories -A  | wc -l
kubectl get failovers -A  | wc -l
kubectl get instancebackupplans -A  | wc -l
kubectl get instancebackups -A  | wc -l
kubectl get instancerestores -A  | wc -l
kubectl get instances -A  | wc -l
kubectl get instanceswitchovers -A  | wc -l
kubectl get lrojobs -A  | wc -l
kubectl get replicationconfigs -A  | wc -l
kubectl get sidecars -A  | wc -l
kubectl get deployments -A  | wc -l
kubectl get statefulsets -A  | wc -l
kubectl get certificates.cert-manager.io -A  | wc -l
kubectl get issuers.cert-manager.io -A  | wc -l
kubectl get configmaps -A  | wc -l
kubectl get persistentvolumeclaims -A  | wc -l
kubectl get persistentvolumes -A  | wc -l
kubectl get pods -A  | wc -l
kubectl get secrets -A  | wc -l
kubectl get services -A  | wc -l
kubectl get storageclasses.storage.k8s.io -A  | wc -l

たとえば、シークレットの数が多いと、メモリ不足(OOM)エラーが発生する可能性があります。

kubectl get secrets -A | wc -l

高度な HA デバッグ

このセクションでは、内部実装であるリソースについて説明します。これらはいつでも変更される可能性があり、下位互換性は保証されていません。手動による修正は、非本番環境データベースの問題にのみ適用してください。これらの手順を行うと、データベースが復元できなくなる可能性があります。

AlloyDB Omni HA の設定には、次の 3 つのフェーズがあります。

  1. スタンバイからの接続を受け入れるようにプライマリを設定します。
  2. スタンバイを初期化してプライマリに接続します。
  3. プライマリ設定で接続を同期させます。

通常、ステップ 2 が最も時間がかかります。データベースのサイズによっては、数時間かかることがあります。

各インスタンスのレプリカ インスタンスには replicationconfig がアタッチされている必要があります。例: bash ❯ k get replicationconfigs.alloydbomni.internal.dbadmin.goog NAME PARENT TYPE ROLE READY HEALTHY 9f47-dbcluster-sample--7576-dbcluster-sample 9f47-dbcluster-sample Physical Upstream True True ds-7576-dbcluster-sample 7576-dbcluster-sample Physical Downstream True True

この例では、次のようになります。

  • インスタンス 9f47-dbcluster-sample は物理アップストリームとして構成されている。
  • インスタンス 7576-dbcluster-sample は物理ダウンストリームとして構成されている。

レプリケーション構成の仕様は意図された設定を示します。一方、ステータスはデータベースから読み取られた実際の状態を反映します。仕様とステータスが一致しない場合、コントローラは変更の適用を試行しているか、変更の適用を妨げるエラーが発生しています。これはステータス フィールドに反映されます。

スタンバイ ジョブ

スタンバイのワークフローを追跡する内部ジョブが 2 つあるはずです。

  • createstandbyjobs.alloydbomni.internal.dbadmin.goog
  • deletestandbyjobs.alloydbomni.internal.dbadmin.goog

設定が停止しているように見える場合は、データベース クラスタ(DBC)に関連するジョブを表示します。ジョブに、設定がどの状態にあるかを説明するエラー メッセージが表示されることがあります。ジョブは完了後しばらくすると自動的にクリーンアップされるため、進行中のジョブがない場合はジョブが表示されないことがあります。

k get createstandbyjob

出力は次のようになります。

apiVersion: alloydbomni.dbadmin.gdc.goog/v1
  kind: CreateStandbyJob
  metadata:
    creationTimestamp: "2024-11-05T03:34:26Z"
    finalizers:
    -   createstandbyjob.dbadmin.goog/finalizer
    generation: 1804
    labels:
      dbs.internal.dbadmin.goog/dbc: foo-ha-alloydb1-clone1
    name: foo-ha-alloydb1-clone1--ac00-foo-ha-alloydb1-clone1--6036-foo-ha-alloydb1-clone1-1730777666
    namespace: db
    resourceVersion: "11819071"
    uid: 1f24cedf-b326-422f-9405-c96c8720cd90
  spec:
    attempt: 3
    cleanup: false
    currentStep: SetupSynchronous
    currentStepTime: "2024-11-05T03:45:31Z"
    metadata:
      dbc: foo-ha-alloydb1-clone1
      primaryInstance: ac00-foo-ha-alloydb1-clone1
      retryError: 'etcdserver: leader changed'
      standbyInstance: 6036-foo-ha-alloydb1-clone1
    requeueTime: "2024-11-05T18:33:03Z"
    startTime: "2024-11-05T03:36:56Z"

プライマリの検証

最初に確認するのは、プライマリが正しく設定されていることです。スタンバイごとにレプリケーション プロファイルが必要です。仕様とステータスで isSynchronous が true の場合、セットアップは完了しているはずです。仕様とステータスで isSynchronous が false の場合、ステップ 3 にまだ到達していません。スタンバイ ジョブを表示して、実行中のジョブがあるかどうか、エラー メッセージがあるかどうかを確認します。

  replication:
    profiles:
    -   isActive: true
      isSynchronous: true
      name: ha:4c82-dbcluster-sample::d85d-dbcluster-sample
      password:
        name: ha-rep-pw-dbcluster-sample
        namespace: default
      passwordResourceVersion: "896080"
      role: Upstream
      type: Physical
      username: alloydbreplica

disableHealthcheck アノテーションが false であることを確認します。これは、フェイルオーバーまたはスイッチオーバー中にのみ無効にすることを目的としています。

apiVersion: alloydbomni.internal.dbadmin.goog/v1
kind: Instance
metadata:
  annotations:
    dbs.internal.dbadmin.goog/consecutiveHealthcheckFailures: "0"
    dbs.internal.dbadmin.goog/disableHealthcheck: "false"
    dr-secondary: "false"
    forceReconcile: "1730414498"

クエリ

DB Pod のリソースが正しく設定されていることを確認するには、管理者ユーザー alloydbadmin としてデータベースにログインします。次のクエリを発行します。

レプリケーション スロット

alloydbadmin=# select * from pg_replication_slots;
-[ RECORD 1 ]-------+---------------------------------------------
slot_name           | d85d_dbcluster_sample
plugin              |
slot_type           | physical
datoid              |
database            |
temporary           | f
active              | t
active_pid          | 250
xmin                | 16318
catalog_xmin        |
restart_lsn         | 0/CA657F0
confirmed_flush_lsn |
wal_status          | reserved
safe_wal_size       |
two_phase           | f

良好な状態とは、スタンバイ インスタンスと同じ名前のレプリケーション スロットが存在することです。レプリケーション スロットがない場合は、最初の設定手順が正常に完了していないことを示します。

active == t が true でない場合、スタンバイがなんらかの理由(ネットワーク、スタンバイがセットアップを完了していないなど)で接続されていないことを意味します。デバッグはスタンバイ側で続行する必要がある可能性があります。

レプリケーションの統計情報

alloydbadmin=# select * from pg_stat_replication;
-[ RECORD 1 ]----+----------------------------------------------------------------
pid              | 250
usesysid         | 16385
usename          | alloydbreplica
application_name | d85d_dbcluster_sample
client_addr      | 10.54.79.196
client_hostname  | gke-samwise-default-pool-afaf152d-8197.us-central1-a.c.foo
client_port      | 24914
backend_start    | 2024-10-30 21:44:26.408261+00
backend_xmin     |
state            | streaming
sent_lsn         | 0/CA64DA8
write_lsn        | 0/CA64DA8
flush_lsn        | 0/CA64DA8
replay_lsn       | 0/CA64DA8
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 2
sync_state       | sync
reply_time       | 2024-11-04 22:08:04.370838+00

存在しない場合は、アクティブな接続がないことを意味します。sync_statesync になっているはずです。sync でない場合は、セットアップの最終ステップが完了していないことを意味します。ログ / ジョブを確認すると、詳細が表示されます。

スタンバイの検証

スタンバイには、プライマリと同じプロファイルに一致するレプリケーション プロファイルが必要です。

  replication:
    profiles:
    -   host: 10.54.79.210
      isActive: true
      isSynchronous: true
      name: ha:4c82-dbcluster-sample::d85d-dbcluster-sample
      passwordResourceVersion: "896080"
      port: 5432
      role: Downstream
      type: Physical
      username: alloydbreplica

スタンバイからプライマリへの接続がない場合、次の 2 つの可能性が考えられます。

  1. スタンバイがまだ設定中である。
  2. スタンバイの設定中または接続中にエラーが発生する。

オプション 1 が発生しているかどうかを確認するには、データベース Pod のログを取得し、dbdaemon/setupPhysicalReplicationDownstream という名前のログ ステートメントを探します。以下は、セットアップが成功した場合のログの例です。

I1104 22:42:42.604871     103 replication.go:107] "dbdaemon/setupPhysicalReplicationDownstream: begin setup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
2024-11-04 22:42:42,605 INFO waiting for postgres to stop
2024-11-04 22:42:43,566 INFO stopped: postgres (exit status 0)
I1104 22:42:43.567590     103 replication.go:131] "dbdaemon/setupPhysicalReplicationDownstream: about to call pg_basebackup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample" cmd=["-h","10.54.79.210","-D","/mnt/disks/pgsql/pg_basebackup_data","-U","alloydbreplica","-v","-P","-p","5432","-w","-c","fast"]
I1104 22:42:44.206403     103 replication.go:139] "dbdaemon/setupPhysicalReplicationDownstream: pg_basebackup finished" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.206440     103 replication.go:141] "dbdaemon/setupPhysicalReplicationDownstream: replacing data directory with pg_basebackup data directory" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.244749     103 replication.go:148] "dbdaemon/setupPhysicalReplicationDownstream: replaced data directory with pg_basebackup data directory" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.244783     103 replication.go:150] "dbdaemon/setupPhysicalReplicationDownstream: Creating config files" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251565     103 replication.go:155] "dbdaemon/setupPhysicalReplicationDownstream: removing postgresql config file for log archiving" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251621     103 replication.go:160] "dbdaemon/setupPhysicalReplicationDownstream: removing postgresql auto config file" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:44.251689     103 replication.go:165] "dbdaemon/setupPhysicalReplicationDownstream: Successfully wrote to config file" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
2024-11-04 22:42:44,256 INFO spawned: 'postgres' with pid 271
2024-11-04 22:42:45,469 INFO success: postgres entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
I1104 22:42:45.469838     103 replication.go:174] "dbdaemon/setupPhysicalReplicationDownstream: backup replication configuration after changing replication config" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"
I1104 22:42:45.476732     103 replication.go:179] "dbdaemon/setupPhysicalReplicationDownstream: finished standby setup" log_name="agent" project_ns="default" dbcluster="dbcluster-sample"

接続エラーが発生した場合は、db Pod のログとデータベースのログファイル(/obs/diagnostic/postgresql.log)を確認し、接続を試みたときに発生したエラーを確認します。よくあるエラーの一つは、スタンバイとプライマリの間にネットワーク接続がないことです。

手動での修正

HA の問題を解決する最も簡単な方法は、numberOfStandbys を 0 に設定して HA を無効にしてから、必要な数にリセットして HA を再度有効にすることです。スタンバイが無効のままになっている場合は、次の手順に沿って HA 設定を手動でリセットして空にします。

  1. スタンバイ インスタンスを手動で削除します。
  2. プライマリ データベースに接続します。現在のレプリケーション スロットをクエリし、削除するスタンバイのレプリケーション スロットを削除します。

    select pg_drop_replication_slot('<replication_slot_name_here>');
    
  3. 削除するレプリケーション プロファイルをプライマリ インスタンスから削除します。

インスタンスが最近調整されていない場合は、forceReconcile アノテーション値を編集できます。任意の数値に設定します。これは、アノテーションが最後に更新されたときのタイムスタンプです。このアノテーションの唯一の目的は、更新して新しい調整を強制的に行えるフィールドを提供することです。

apiVersion: alloydbomni.internal.dbadmin.goog/v1
kind: Instance
metadata:
  annotations:
    dbs.internal.dbadmin.goog/consecutiveHealthcheckFailures: "0"
    dbs.internal.dbadmin.goog/disableHealthcheck: "false"
    dr-secondary: "false"
    forceReconcile: "1730414498"

データベース エンジンと監査ログを収集する

データベース エンジンのログと監査ログは、データベース Pod 内のファイルとして使用できます(root アクセスが必要です)。

  • obs/diagnostic/postgresql.log
  • obs/diagnostic/postgresql.audit
export NAMESPACE=dbcluster-namespace
export DBCLUSTER=dbcluster-sample

export DBPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER} -l alloydbomni.internal.dbadmin.goog/task-type=database -o jsonpath='{.items[0].metadata.name}'`
kubectl exec -n ${NAMESPACE} ${DBPOD} -it -- /bin/bash

$ ls -la /obs/diagnostic/
-rw------- 1 postgres postgres    98438 Sep 25 20:15 postgresql.audit
-rw------- 1 postgres postgres 21405058 Sep 25 20:24 postgresql.log

データベースとデータベース Pod の指標を収集する

AlloyDB Omni オペレーターは、AlloyDB Omni エンジンとそれをホストする Pod の一連の基本指標を提供します。指標は、ポート 9187 で使用可能な Prometheus エンドポイントとして使用できます。エンドポイントにアクセスするには、次のように DBCluster ラベルと task-type ラベルを使用して、データベース Pod とデータベース モニタリング Pod の Pod 名を特定する必要があります。

export NAMESPACE=default
export DBCLUSTER=dbcluster-sample

export DBPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER},alloydbomni.internal.dbadmin.gdc.goog/task-type=database -o jsonpath='{.items[0].metadata.name}'`

export MONITORINGPOD=`kubectl get pod -n ${NAMESPACE} -l alloydbomni.internal.dbadmin.goog/dbcluster=${DBCLUSTER},alloydbomni.internal.dbadmin.gdc.goog/task-type=monitoring -o jsonpath='{.items[0].metadata.name}'`

AlloyDB Omni データベース指標にアクセスする

kubectl port-forward -n ${NAMESPACE} ${MONITORINGPOD} 9187:9187
curl http://localhost:9187/metrics | grep HELP

データベース Pod の指標にアクセスする

kubectl port-forward -n ${NAMESPACE} ${DBPOD} 9187:9187
curl http://localhost:9187/metrics | grep HELP

Kubernetes クラスタの指標をスクレイピングするように Prometheus を構成することもできます。詳細については、Prometheus Kubernetes サービス ディスカバリ構成をご覧ください。