トラブルシューティング

このページでは、Kubernetes クラスターのデプロイで CloudNativePG をトラブルシューティングする方法に関する基本的な情報を見つけることができます。

ヒント

Kubernetes 管理者として、 :ref:``kubectl` に cnpg プラグインを使用する<kubectl に cnpg プラグインを使用する>` ページをブックマークする必要があります。

始める前に

Kubernetes 環境

トラブルシューティング活動に違いをもたらすことができるのは、基盤となる Kubernetes システムに関する明確な情報を提供することです。

次のことを確認してください。

  • 使用している Kubernetes のディストリビューションとバージョン

・PostgreSQLが稼働しているノードの仕様

  • 実際の ストレージ容量の使用 についてできる限り、本番環境に入る前に行ったストレージ クラスとベンチマークを含みます。

  • クラスターで使用している関連する Kubernetes アプリケーション (つまり、Prometheus、Grafana、Istio、Certmanager など)

  • 継続的なバックアップの状況、特に適切に機能しているかどうか: 正しく機能していない場合は、必ず 緊急バックアップ を実行してください。

潜在的な中断操作を実行する前に

便利なユーティリティ

必須の kubectl ユーティリティに加えて、トラブルシューティングのために、システムで次のプラグイン/ユーティリティを使用できるようにすることをお勧めします。

  • kubectl の :ref:``kubectl` に cnpg プラグインを使用する<kubectl に cnpg プラグインを使用する>`

  • jq 、軽量で柔軟なコマンドライン JSON プロセッサ

  • grep 、指定されたパターンに一致する行を含む 1

つ以上の入力ファイルを検索します。ほとんどの *nix ディストリビューションで既に利用可能です。 Windows OS を使用している場合は、grep の代わりに findstr を使用するか、 wsl を直接使用できます。

好みの *nix ディストリビューションをインストールし、上記のツールを使用します。

緊急バックアップ

緊急事態では、メインの app データベースの緊急論理バックアップを作成する必要がある場合があります。

重要

以下の手順は、緊急時にのみ実行し、組織で有効なデータ保護ポリシーの下で一時バックアップ ファイルを保持する必要があります。ダンプ ファイルは実際に kubectl コマンドを実行するクライアント マシンに保存されるため、すべての保護が実施され、バックアップ ファイルを保存するのに十分なスペースがあることを確認してください。

次の例は、cluster-example-1 ポッドから、cluster-example Postgres クラスター内の app データベースの論理バックアップを取得する方法を示しています。

kubectl exec cluster-example-1 -c postgres \
  -- pg_dump -Fc -d app > app.dump

注釈

環境で使用したオブジェクトの名前を指定することで、上記のコマンドをクラスターのバックアップに簡単に適用できます。

上記のコマンドは、カスタム形式で pg_dump コマンドを発行します。これは、 logical backups in PostgreSQL を取得する最も用途の広い方法です。

次のステップは、データベースを復元することです。初期化されたばかりの新しい PostgreSQL クラスターで操作していると仮定します (つまり、app データベースは空です)。

次の例は、プライマリ (new-cluster-example-1 ポッド) に接続して、new-cluster-example Postgres クラスターの app データベースで上記の論理バックアップを復元する方法を示しています。

kubectl exec -i new-cluster-example-1 -c postgres \
  -- pg_restore --no-owner --role=app -d app --verbose < app.dump

重要

このセクションの例では、推奨に従って、ダンプおよび復元するグローバル オブジェクト (データベースとロール) が他にないことを前提としています。複数の役割がある場合は、pg_dumpall -g を使用してバックアップを作成し、それらを新しいクラスターに手動で復元していることを確認してください。複数のデータベースがある場合は、正しい所有権を割り当てていることを確認して、一度に 1 つのデータベースで上記の操作を繰り返す必要があります。 PostgreSQL に慣れていない場合は、これらの重要な操作を専門のサポート会社の指導の下で行うことをお勧めします。

上記の手順は、将来のある段階で cnpg プラグインに統合される可能性があります。

ログ

CloudNativePG によって作成および制御されるすべてのリソースは、Kubernetes によって期待されるように標準出力に記録され、JSON format に直接記録されます。そのため、kubectl logs コマンドを使用して特定のリソースからログを取得する必要があります。

詳細については、次のように入力してください。

kubectl logs --help

ヒント

JSON ログは機械読み取りには適していますが、人間には読み取りが困難です。使いやすさを向上させるために、jq コマンドを使用することをお勧めします。たとえば、kubectl logs コマンドを | jq -C で パイプ できます。

注釈

以下のセクションでは、CloudNativePG のトラブルシューティングに関して、さまざまなリソースに関するログを取得する方法の例をいくつか示します。

オペレーター情報

デフォルトでは、CloudNativePG オペレーターは Deployment として Kubernetes の cnpg-system 名前空間にインストールされます ( 導入の詳細 を参照)。

詳細については)。

次のコマンドを実行して、オペレーター ポッドのリストを取得できます。

kubectl get pods -n cnpg-system

注釈

通常の状況では、cnpg-controller-manager- で始まる名前で識別される、オペレーターが実行されているポッドが 1 つ必要です。高可用性のためにオペレーターをセットアップした場合は、より多くのエントリーが必要です。これらのポッドは、cnpg-controller-manager という名前のデプロイメントによって管理されます。

以下を使用して、ポッド <POD> で実行されているオペレーターに関する関連情報を収集します。

kubectl describe pod -n cnpg-system <POD>

次に、次のコマンドを実行して、同じポッドからログを取得します。

kubectl logs -n cnpg-system <POD>

オペレーターに関する詳細情報を収集する

以下を実行して、CloudNativePG オペレーター デプロイのすべてのポッドからログを取得します (マルチ オペレーター デプロイがある場合)。

kubectl logs -n cnpg-system \
  deployment/cnpg-controller-manager --all-containers=true

Tip

上記のコマンドに -f フラグを追加して、リアルタイムでログを追跡できます。

次を実行して、ログを JSON ファイルに保存します。

kubectl logs -n cnpg-system \
  deployment/cnpg-controller-manager --all-containers=true | \
  jq -r . > cnpg_logs.json

kubectl-cnpg プラグインを使用して CloudNativePG オペレーターのバージョンを取得します。

kubectl-cnpg status <CLUSTER>

出力:

Cluster in healthy state
Name:               cluster-example
Namespace:          default
System ID:          7044925089871458324
PostgreSQL Image:   ghcr.io/cloudnative-pg/postgresql:15.2-3
Primary instance:   cluster-example-1
Instances:          3
Ready instances:    3
Current Write LSN:  0/5000000 (Timeline: 1 - WAL File: 000000010000000000000004)

Continuous Backup status
Not configured

Streaming Replication status
Name               Sent LSN   Write LSN  Flush LSN  Replay LSN  Write Lag       Flush Lag       Replay Lag      State      Sync State  Sync Priority
- ---               --------   ---------  ---------  ----------  ---------       ---------       ----------      -----      ----------  -------------
cluster-example-2  0/5000000  0/5000000  0/5000000  0/5000000   00:00:00        00:00:00        00:00:00        streaming  async       0
cluster-example-3  0/5000000  0/5000000  0/5000000  0/5000000   00:00:00.10033  00:00:00.10033  00:00:00.10033  streaming  async       0

Instances status
Name               Database Size  Current LSN  Replication role  Status  QoS         Manager Version
- ---               -------------  -----------  ----------------  ------  ---         ---------------
cluster-example-1  33 MB          0/5000000    Primary           OK      BestEffort  1.12.0
cluster-example-2  33 MB          0/5000000    Standby (async)   OK      BestEffort  1.12.0
cluster-example-3  33 MB          0/5000060    Standby (async)   OK      BestEffort  1.12.0

クラスタ情報

NAMESPACE 名前空間の <CLUSTER> クラスターのステータスは、次のコマンドで確認できます。

kubectl get cluster -n <NAMESPACE> <CLUSTER>

出力:

NAME        AGE        INSTANCES   READY   STATUS                     PRIMARY
<CLUSTER>   10d4h3m    3           3       Cluster in healthy state   <CLUSTER>-1

上記の例では、3 つのインスタンスからなる正常な PostgreSQL クラスターが報告されています。これらはすべて ready 状態であり、<CLUSTER>-1 がプライマリです。

異常な状態の場合は、Cluster リソースのマニフェストを取得することで、さらに多くのことを発見できます。

kubectl get cluster -o yaml -n <NAMESPACE> <CLUSTER>

収集するもう 1 つの重要なコマンドは、cnpg プラグインによって提供される status コマンドです。

kubectl cnpg status -n <NAMESPACE> <CLUSTER>

Tip

--verbose オプションを追加すると、より多くの情報を出力できます。

注釈

クラスターの状態を知るだけでなく、cnpg プラグインを使用して次のことを行うこともできます。構成の変更を再ロードして適用するためのループ。<br /> 詳細については、 :ref:``kubectl` に cnpg プラグインを使用する<kubectl に cnpg プラグインを使用する>` のドキュメントを参照してください。

PostgreSQL コンテナー イメージのバージョンを取得します。

kubectl describe cluster <CLUSTER_NAME> -n <NAMESPACE> | grep "Image Name"

出力:

Image Name:    ghcr.io/cloudnative-pg/postgresql:15.2-3

注釈

また、kubectl-cnpg status -n <NAMESPACE> <CLUSTER_NAME> を使用して同じ情報を取得できます。

ポッド情報

特定の PostgreSQL クラスターに属するインスタンスのリストを取得するには、次のコマンドを使用します。

kubectl get pod -l cnpg.io/cluster=<CLUSTER> -L role -n <NAMESPACE>

出力:

NAME          READY   STATUS    RESTARTS   AGE       ROLE
<CLUSTER>-1   1/1     Running   0          10d4h5m   primary
<CLUSTER>-2   1/1     Running   0          10d4h4m   replica
<CLUSTER>-3   1/1     Running   0          10d4h4m   replica

以下を実行することで、ポッドが失敗しているかどうか、またどのように失敗しているかを確認できます。

kubectl get pod -n <NAMESPACE> -o yaml <CLUSTER>-<N>

次のコマンドを使用して、特定の PostgreSQL インスタンスのすべてのログを取得できます。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N>

検索を PostgreSQL プロセスのみに制限する場合は、次を実行できます。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | \
  jq select(.logger=="postgres") | .record.message

次の例では、ユーザー フレンドリな形式でタイムスタンプも追加します。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | \
  jq -r select(.logger=="postgres") | [(.ts|strflocaltime("%Y-%m-%dT%H:%M:%S %Z")), .record.message] | @csv

PostgreSQL ポッドに関する追加情報を収集してフィルタリングする

クラッシュした特定のポッドからのログを確認します。

kubectl logs -n <NAMESPACE> --previous <CLUSTER>-<N>

特定の PostgreSQL ポッドから FATAL エラーを取得します。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | \
  jq -r .record | select(.error_severity == "FATAL")

出力:

{
  "log_time": "2021-11-08 14:07:44.520 UTC",
  "user_name": "streaming_replica",
  "process_id": "68",
  "connection_from": "10.244.0.10:60616",
  "session_id": "61892f30.44",
  "session_line_num": "1",
  "command_tag": "startup",
  "session_start_time": "2021-11-08 14:07:44 UTC",
  "virtual_transaction_id": "3/75",
  "transaction_id": "0",
  "error_severity": "FATAL",
  "sql_state_code": "28000",
  "message": "role \"streaming_replica\" does not exist",
  "backend_type": "walsender"
}

特定のポッドのログで PostgreSQL DB エラー メッセージをフィルタリングします。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | jq -r .err | select(. != null)

出力:

dial unix /controller/run/.s.PGSQL.5432: connect: no such file or directory

特定のポッドから err 単語に一致するメッセージを取得します。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | jq -r .msg | grep "err"

出力:

2021-11-08 14:07:39.610 UTC [15] LOG:  ending log output to stderr

特定のポッドの PostgreSQL プロセスからすべてのログを取得します。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | \
  jq -r . | select(.logger == "postgres") | select(.msg != "record") | .msg
``` 出力:

```shell
2021-11-08 14:07:52.591 UTC [16] LOG:  redirecting log output to logging collector process
2021-11-08 14:07:52.591 UTC [16] HINT:  Future log output will appear in directory "/controller/log".
2021-11-08 14:07:52.591 UTC [16] LOG:  ending log output to stderr
2021-11-08 14:07:52.591 UTC [16] HINT:  Future log output will go to log destination "csvlog".

値を含むフィールドでフィルター処理されたポッド ログを取得し、実行中の | で区切られたそれらを結合します。

kubectl logs -n <NAMESPACE> <CLUSTER>-<N> | \
  jq -r [.level, .ts, .logger, .msg] | join(" | ")

出力:

info | 1636380469.5728037 | wal-archive | Backup not configured, skip WAL archiving
info | 1636383566.0664876 | postgres | record

バックアップ情報

次のコマンドを使用して、名前付きクラスター用に作成されたバックアップを一覧表示できます。

kubectl get backup -l cnpg.io/cluster=<CLUSTER>

重要

バックアップのラベル付けは、CloudNativePG のバージョン 1.10.0 で導入されました。そのため、そのバージョンまたはそれ以降のバージョンで作成されたリソースのみに、そのようなラベルが含まれます。

保管情報

次のように、クラスターが使用する StorageClass を再確認して、調査またはトラブルシューティング中にさらにコンテキストを取得すると便利な場合があります。

STORAGECLASS=$(kubectl get pvc <POD> -o jsonpath={.spec.storageClassName})
kubectl get storageclasses $STORAGECLASS -o yaml

多くの場合、クラスターはデフォルトの StorageClass を使用して作成されるため、ここではクラスター ポッドの 1 つから StorageClass を取得しています。

ノード情報

Kubernetes ノードは、最終的に PostgreSQL ポッドが実行される場所です。それらについてできる限り多くのことを知ることは、戦略的に重要です。

以下を使用して、Kubernetes クラスター内のノードのリストを取得できます。

#  look at the worker nodes and their status

kubectl get nodes -o wide

さらに、特定のクラスターのポッドが実行されているノードのリストを収集できます。

kubectl get pod -l cnpg.io/cluster=<CLUSTER> \
  -L role -n <NAMESPACE> -o wide
後者は、ポッドが配布されている場所を理解するために重要です。

affinity/anti-affinity rules and/or tolerations を使用している場合は非常に便利です。

条件

多くのネイティブ kubernetes オブジェクト like here と同様に、Cluster は status.conditions も公開します。これにより、クラスター全体の正常性状態に頼るのではなく、特定のイベントが発生するのを「待つ」ことができます。現在利用可能な条件は次のとおりです。

  • LastBackupSucceeded

  • 継続的なアーカイブ

  • 準備

LastBackupSucceeded は最新のバックアップのステータスを報告しています。 True に設定されている場合、最後のバックアップが正しく取得され、それ以外の場合は False に設定されます。

ContinuousArchiving は WAL アーカイブのステータスを報告しています。 True に設定されている場合、最後の WAL アーカイブ プロセスが正常に終了し、それ以外の場合は False に設定されます。

クラスターにユーザーが指定した数のインスタンスがあり、プライマリ インスタンスの準備が整っている場合、Ready は True になります。この条件をスクリプトで使用して、クラスターが作成されるのを待つことができます。

特定の条件を待つ方法

  • バックアップ:

$ kubectl wait --for=condition=LastBackupSucceeded cluster/<CLUSTER-NAME> -n <NAMESPACE>
  • 継続的なアーカイブ:

$ kubectl wait --for=condition=ContinuousArchiving cluster/<CLUSTER-NAME> -n <NAMESPACE>
  • 準備完了 (クラスターの準備ができているかどうか):

edb_notranlate_39 以下は、失敗した状態を含む cluster.status のスニペットです。

$ kubectl get cluster/<cluster-name> -o yaml
.
.
.
  status:
    conditions:
    - message: unexpected failure invoking barman-cloud-wal-archive: exit status
        2
      reason: ContinuousArchivingFailing
      status: "False"
      type: ContinuousArchiving

    - message: exit status 2
      reason: LastBackupFailed
      status: "False"
      type: LastBackupSucceeded

    - message: Cluster Is Not Ready
      reason: ClusterIsNotReady
      status: "False"
      type: Ready

よくある問題

ストレージがいっぱいです

クラスター内の 1 つ以上のポッドが CrashloopBackoff にあり、これがディスクがいっぱいであることが原因である可能性があることをログが示唆している場合、おそらくインスタンスの PersistentVolumeClaim のサイズを増やす必要があります。ドキュメントの

ボリューム拡張 を見てください。

Pod が Pending 状態でスタックする

クラスターのインスタンスが Pending フェーズでスタックしている場合は、ポッドの Events セクションをチェックして、この背後にある理由を把握する必要があります。

kubectl describe pod -n <NAMESPACE> <POD>

これには、次のような原因が考えられます。

  • nodeSelector に一致するノードがありません

  • 容認がノードのテイントに一致するように正しく構成されていない

  • ノードがまったく利用できない: これは、cluster-autoscaler が制限に達したり、一時的な問題が発生したりすることにも関連している可能性があります

この場合、名前空間内のイベントを確認することも役立ちます。

kubectl get events -n <NAMESPACE>
#  list events in chronological order

kubectl get events -n <NAMESPACE> --sort-by=.metadata.creationTimestamp

バックアップが構成されていない場合、レプリカは同期されません

メンテナンス上の理由により、レプリカがしばらくオフになることがあります (Kubernetes ノードがドレインされたときを考えてください)。クラスターにバックアップが構成されていない場合、レプリカが復旧したときに、プライマリにもう存在しない WAL ファイルが必要になる可能性があります ( :ref:``postgresql` セクション<postgresql セクション>` で説明されているように、WAL 管理ポリシーに従って既にリサイクルされています)。同期の。

同様に、pg_rewind が以前のプライマリに存在しなくなった WAL ファイルを必要とする可能性がある場合、pg_rewind: error: could not open file を報告します。

このような場合、Pod の準備ができなくなり、PVC を削除してオペレーターにレプリカの再構築を依頼する必要があります。

動的にプロビジョニングされた永続ボリュームに依存していて、PV 自体を削除する自信がある場合は、次の方法で削除できます。

PODNAME=<POD>
VOLNAME=$(kubectl get pv -o json | \
  jq -r .items[]|select(.spec.claimRef.name==\"$PODNAME\")|.metadata.name)

kubectl delete pod/$PODNAME pvc/$PODNAME pvc/$PODNAME-wal pv/$VOLNAME