トラブルシューティング

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

ヒント

Kubernetes管理者は、 kubectl ページをブックマークしておく必要があります。

始める前に

Kubernetes環境

トラブルシューティングアクティビティで違いを生むのは、基になるKubernetesシステムに関する明確な情報を提供することです。

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

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

  • PostgreSQLが動作しているノードの仕様

  • 実稼働に入る前に行ったストレージクラスとベンチマークを含む、実際の

    StorageConfiguration についてできる限り。

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

便利なユーティリティ

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

  • kubectl の cnpg

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

  • grep

、指定されたパターンに一致する行を1つ以上の入力ファイルで検索します。ほとんどの*nixディストリビューションで既に利用可能です。 Windows OSを使用している場合は、 grep の代わりに findstr を使用するか、

wsl を直接使用して、好みの*

nixディストリビューションをインストールして上記のツールを使用できます。

ログ

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

詳細については、次のように入力します。

kubectl logs --help

ヒント

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

注釈

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

オペレーター情報

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

展開に関する詳細 を参照)。

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

kubectl get pods -n cnpg-system

注釈

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

次を使用して、 pod <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:14.4-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 />証明書を管理します。<br /> ロールアウトリスタートクラスターを作成して構成の変更を適用します。<br />ループを使用してリロードし、構成の変更を適用します。<br /> 詳細については、 cnpg ドキュメントを参照してください。

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

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

出力:

Image Name:    ghcr.io/cloudnative-pg/postgresql:14.4-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 Podから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/clusterName=<CLUSTER> \
  -L role -n <NAMESPACE> -o wide
後者は、ポッドが配布されている場所を理解することが重要です。

affinity/anti-affinity rules and/or tolerations を使用している場合に非常に役立ちます。

条件

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

  • LastBackupSucceeded

  • 連続アーカイブ

  • レディ

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

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

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

特定の条件を待機する方法

  • バックアップ:bash $ kubectl wait --for=condition=LastBackupSucceeded cluster/<CLUSTER-NAME> -n <NAMESPACE>

  • ContinuousArchiving:bash $ kubectl wait --for=condition=ContinuousArchiving cluster/<CLUSTER-NAME> -n <NAMESPACE>

  • Ready(クラスターの準備ができているかどうか): edb_notranlate_37 以下は、失敗した条件を含む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 を報告します。

これらの場合、ポッドは準備ができていないため、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 pv/$VOLNAME