トラブルシューティング

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

ヒント

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

始める前に

Kubernetes環境

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

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

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

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

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

    StorageConfiguration についてできる限り。

  • クラスターで使用している関連する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 podから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オペレーターは、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:15.3-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クラスターが報告され、すべてが 準備完了 状態で、 <CLUSTER>-1 がプライマリです。

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

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

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

kubectl cnpg status -n <NAMESPACE> <CLUSTER>

Tip

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

注釈

クラスターのステータスを知ることに加えて、 cnpgプラグインを使用して次のことを行うこともできます。レプリカをプロモートします。<br />証明書を管理します。<br />ロールアウトリスタートクラスターを作成して構成の変更を適用します。<br />ループを使用してリロードし、構成の変更を適用します。<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.3-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

特定のpodからerr wordに一致するメッセージを取得します。

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 と同様に、クラスターは status.conditions も公開します。これにより、クラスター全体のヘルス状態に依存する代わりに、特定のイベントが発生するのを「待機」できます。現時点で利用可能な条件は次のとおりです。

  • LastBackupSucceeded

  • ContinuousArchiving

  • レディ

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>
  • Ready(クラスターの準備ができているかどうか):

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

ネットワーキング

CloudNativePGには、基本的なネットワーキングと接続が整っている必要があります。

ネットワーキング セクションで詳細情報を見つけることができます。

CloudNativePGを既存の環境にインストールする場合、ネットワークポリシーが設定されているか、クラスター専用に作成されたその他のネットワーク構成が存在する可能性があり、オペレーターとクラスターポッド間および/またはポッド間で必要な接続に影響を与える可能性があります。

次のコマンドを使用して、既存のネットワークポリシーを探すことができます。

kubectl get networkpolicies

Kubernetesネットワーク管理者によって設定されたネットワークポリシーがいくつかある場合があります。

$ kubectl get networkpolicies
NAME                   POD-SELECTOR                      AGE
allow-prometheus       cnpg.io/cluster=cluster-example   47m
default-deny-ingress   <none>                            57m

いくつかの一般的な問題

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

クラスター内の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 pvc/$PODNAME-wal pv/$VOLNAME

Creating new replica でスタックするクラスター

クラスターは「新しいレプリカの作成」でスタックしていますが、ポッドログには関連する問題が表示されません。これは、次の問題

on connectivity

に関連していることが判明しています。リリース1.20.1、1.19.3、および1.18.5から、ネットワークの問題は、次のようにステータス列により明確に反映されます。

Instance Status Extraction Error: HTTP communication issue

インストールされたネットワークポリシーによりネットワーキングが損なわれています

networking section で指摘されているように、ローカルネットワークポリシーは、必要な接続の一部を妨げる可能性があります。

接続が損なわれていることを示す兆候は、次のようなメッセージのオペレーターログに存在することです。

"Cannot extract Pod status", […snipped…] "Get \"http://<pod IP>:8000/pg/status\": dial tcp <pod IP>:8000: i/o timeout"

ネットワークポリシーをリストし、接続を制限するポリシーを探す必要があります。

$ kubectl get networkpolicies
NAME                   POD-SELECTOR                      AGE
allow-prometheus       cnpg.io/cluster=cluster-example   47m
default-deny-ingress   <none>                            57m

たとえば、上記のリストでは、 default-deny-ingress が犯人である可能性が高いようです。あなたはそれにドリルすることができます:

  $ kubectl get networkpolicies default-deny-ingress -o yaml
  <…snipped…>
  spec:
    podSelector: {}
    policyTypes:
    - Ingress

:ref:`networking page <ネットワーキング>` には、カスタマイズして\ ``NetworkPolicy``

を明示的に作成できるネットワークポリシーファイルがあり、オペレーターはクロス名前空間をクラスターポッドに接続できます。

データディレクトリのブートストラップ中のエラー

クラスターの初期化ジョブが「バスエラー(コアダンプ)子プロセスが終了コード135で終了しました」でクラッシュした場合、おそらくクラスター hugepages設定を修正する必要があります。

その理由は、v2で修正する必要があるcgroup v1のhugepageのサポートが不完全であるためです。詳細については、PostgreSQL BUG #17757: Not honoring huge_pages setting during initdb causes DB crash in Kubernetesを確認してください。

hugepagesが有効になっているかどうかを確認するには、Kubernetesノードでgrep HugePages /proc/meminfo を実行し、hugepagesが存在するかどうか、そのサイズ、およびいくつが空いているかを確認します。

hugepagesが存在する場合は、すべてのPostgreSQLポッドで使用可能なhugepagesメモリの量を構成する必要があります。

例:

postgresql:
  parameters:
    shared_buffers: "128MB"

resources:
  requests:
    memory: "512Mi"
  limits:
    hugepages-2Mi: "512Mi"

クラスター内のすべてのポッドをスケジュールするには、十分なhugepagesメモリが必要であることに注意してください(上記の例では、ポッドあたり少なくとも512MiBを空ける必要があります)。