PostgreSQLをKubernetes上で実行する方法の調査
最近、 Kubernetes 上で PostgreSQL を実行するケースが増加しています。 Kubernetes のスケーラビリティやセルフヒーリング特性と組み合わせて、 PostgreSQL をよりスケーラブルで安定して運用することを目指すユーザーが存在しています。2023年にTimescaleが実施した調査では、一定数のユーザーが Kubernetes 上に PostgreSQL をデプロイしていることが分かります。Helm を使用してデプロイする方法が最も人気ですが、ここ数年では Operator を使用するユーザーも増加しています。
この記事では Kubernetes 上で利用可能ないくつかの PostgreSQL Operator を調査します。
Operatorの調査
以下の6つの Operator を調査しました。いずれも GitHub または GitLab 上でOSSとして公開されており、人気のあるプロジェクトです。
調査の観点としては、以下のような要素に注目しました。
- 高可用性: フェイルオーバーの動作
- ドキュメント: Operator のデプロイ方法、PostgreSQL クラスターのデプロイ方法、など
- カスタマイズ性
- バックアップ手順のテスト
- モニタリング設定のテスト
- その他の機能のテスト (UIや追加の機能など)
Patroni
それぞれの Operator の具体的な調査の前に、 Patroni という PostgreSQL の高可用性をサポートするソフトウェアについて説明します。 Patroni はこれから紹介する Operator のうち、3つで共通して使用されています。
Patroni は PostgreSQL クラスターのリーダーを etcd や Zookeeper などの分散キーストア上で管理します。リーダーノードからの応答がない場合に、自動的にレプリカのうちの一つをリーダーに昇格させて、クラスターの可用性を維持します。
Patroni は本来は Kubernetes 専用に作成されたものではありませんが、 Kubernetes と親和性があります。 Kubernetes 上で Patroni を使用する場合は、専用の etcd クラスターは不要で、 Kubernetes API を使用して、クラスターの状態を保存できます。これは Kubernetes API がそのバックエンドに etcd を使用していることが理由です。
Patroni については、これらのリソースでさらに詳しく説明されています。
CruchyData Postgres-operator
高可用性
Patroni を使用。とてもスムーズにフェイルオーバーが行われる。
ドキュメント
シンプルで読みやすく、使用例が豊富で試しやすい。
カスタマイズ
豊富。一つのマニュフェストにほとんどの要素を定義できる。
バックアップ
pgBackRest が使用されている。 PVC にバックアップする方式は問題なく動作する。しかし、S3互換のストレージ( MinIO や Ceph S3 )などでは正しく動作しなかった。 pgBackRest の設定を変更したり、環境変数を設定したり、ログからデバッグすることが必要。
モニタリング
Prometheus 形式のモニタリングをサポートしている。ただし、 Service や Podmonitor 、ServiceMonitor などは自動的に作成されない。このGitHub issueで議論されているように、既存の Prometheus や Grafana と使用する際の問題点もある。
Pooler
PgBouncer がサポートされている。 PgBouncer にログインするユーザーの作成に注意が必要だが、ドキュメントに記載が少なく、挙動がやや不明瞭。
その他の機能
pgAdmin
pgAdmin Web UIをデプロイできるが、Service が自動的に作成されない。
懸念事項
ライセンス
CrunchyData は、やや特殊なライセンス形式を定義している。Operator 自体は Apache License 2.0 でオープンソースだが、コンテナイメージは別のライセンス形式で公開されている。本番環境での利用時に一部制限がある場合がある。
環境変数の設定
環境変数の設定を行えない問題があり、 StatefulSet を直接編集して設定する必要がある。 (このGitHub issue link で説明されている) これがS3互換のストレージを使用する際に必要な環境変数の設定を難しくしている。
PgBouncer接続時のTLS
PgBouncer に接続する際にTLS接続が要求される。無効化するのが難しく、TLSを使用した接続方法についての説明がやや不明瞭。 (GitHub issue link)
CloudNative PG
高可用性
Patroni ではなく独自の高可用性システムを実装している。 PostgreSQL の物理レプリケーション機能を使用する。また、 Kubernetes API を使用してクラスターの状態を管理している。
デフォルト設定では、フェイルオーバーがゆっくり行われる。 .spec.failoverDelay
のパラメターを調整することで、フェイルオーバーのパフォーマンスを調整できる。データの保護とサービスの可用性のバランスを検討して調整する。このGitHub discussionsで議論されている。
ドキュメント
よい。
カスタマイズ
Helm チャートを使用してカスタマイズ可能。 Operator と PostgreSQL Cluster のどちらも簡単にカスタマイズ &デプロイできる。
バックアップ
S3互換のストレージとも問題なく動作する。
モニタリング
簡単に設定可能。
Pooler
PgBouncer がサポートされている。
その他の機能
StatefulSetを利用しない設計
コントローラーは StatefulSet は使用せず、 Pod を使用してクラスターを管理する。その理由はここで説明されている。
kubectl cnpg
kubectl cnpg
プラグインは非常に優れていて便利。新規クラスターの作成からベンチマークの実行まで、日々の管理タスクを簡単に行える。
懸念事項
独自のHA実装
Patroni に依存せず、独自のアーキテクチャを使用しているため、実装の詳細を理解して使用する必要がある。
設定項目の複雑さ
多くのパラメータを構成するのは複雑。たとえば、デフォルトでは.spec.switchoverDelayフェイルオーバーが遅くなり、アプリケーション要件に基づいた適切な設計と計画が必要になる。
Zalando Postgres オペレーター
高可用性
PostgreSQL と Patroni をバンドルしたSpiloが使用されている。
ドキュメント
やや不十分で、探しているものを見つけるのが難しい。
カスタマイズ
少し複雑。ドキュメントがあまり明確ではない。
バックアップ
S3 がサポートされている。 Ceph S3 などのS3互換ストレージを使用するには、いくつかの環境変数を追加するハックが必要。これはドキュメントからはあまり明確ではない。
モニタリング
なし。サイドカーコンテナーを手動で追加する必要がある。
Pooler
PgBouncer がサポートされている。
その他の機能
Web UI
Web UI、はYAMLファイルなしで PostgreSQL クラスターをデプロイする場合に便利。また、ログの確認もできる。ただし、認証などのアクセス制御機能がない。
懸念事項
オペレーターのパフォーマンス
オペレーターのパフォーマンスにやや心配がある。一部の子リソースがクリーンアップされないことがある。 (最近修正された可能性がある。GitHubの問題とPRを参照) また、ログを確認するのが難しい。Podの終了に長い時間がかかることがある。ドキュメントが不十分で、デバッグやトラブルシューティングが少し難しくなる。
kubegres
HA
PostgreSQL標準のストリーミングレプリケーションを使用。ネイティブのPostgresライブラリのみで構築されている。カスタムライブラリやサードパーティライブラリを使用しない。オペレーターはフェイルオーバーを行うが、速度はやや遅い。
ドキュメント
シンプルで良い。 PostgreSQL の標準レプリケーションを使用するため、学習コストも少ない。
カスタマイズ
カスタマイズできる項目は多くない。使用可能なパラメータはごくわずか。PostgreSQL の公式 Docker イメージを使用するため、コンテナイメージのカスタマイズが簡単。
バックアップ
PVC バックアップ方式がサポートされている。S3はサポートされない。
モニタリング
サポートはない。
Pooler
サポートはない。
その他の機能
とくになし。
懸念事項
サイドカーのサポートなし
サイドカーはサポートされていない。これにより、 Prometheus Exporter や PgBouncer その他のカスタマイズを実装するために手作業が必要でやや面倒になっている。
開発ペースがアクティブではない
GitHubでの開発は他ほど活発ではない。(最後のコミットが数か月前)
stackgres
HA
Patroni を使用している。フェイルオーバーはスムーズ。
ドキュメント
分かりやすくて良い。
カスタマイズ
非常に柔軟で、多くのカスタマイズが可能。ただし、機能が多く他のものよりも複雑。複数のリソースにそれぞれのパラメターを設定する必要がある。( SGInstanceProfile
、SGPostgresConfig
、SGPoolingConfig
、SGOBjectStorage
、SGDistributedLogs
、SGScriptSGCluster
など)
例えば、ユーザーまたはデータベースの作成は、リソースSGScript
内の.sql
ファイルに定義する必要がある。
バックアップ
S3がサポートされている。S3互換のストレージでも問題なく動作する。
監視
既存の Prometheus および Grafana と自動的に統合される。設定は非常に簡単。
Pooler
PgBouncer が、各ポッド内のサイドカーコンテナーとして実装される。(他のオペレーターの場合は、サイドカーではなく、PostgreSQL クラスターの外部に PgBouncer がデプロイされる。)
その他の機能
Citusのサポート
Citus を使用したシャーディング機能もサポートする。
Web UI
OIDCログインをサポートするスタイリッシュなWeb UI。例えば、このUIを使用して開発チームは PostgreSQL インスタンスを自分でデプロイできる。
懸念事項
ライセンス
ライセンスは AGPLv3 。(大きな懸念ではないが、他のオペレーターとは異なる。)
複雑性
多くのコンポーネントと機能による複雑なアーキテクチャ。
結論
私たちの評価結果として、 CloudNative PG がほとんどのユースケースをカバーし、使いやすく設定も簡単なので、最初の選択肢になると結論付けました。また、コミュニティのサポートやドキュメントも充実しており、開発も非常に活発です。kubectl cnpg
プラグインのおかげで管理者の負担も少なくなります。
2番目のオプションは、Stackgres です。複雑ではありますが、他のオペレーターと比較してより堅牢で成熟しています。 Patroni を使用したい場合は、Stackgres が最適です。
また、ミニマリズムとシンプルさという点で、 kubegres のコンセプトは素敵です。他のオペレーターはできるだけ多くの機能を実装しようとしますが、 kubegres はシンプルさを保ち重要な機能にのみ焦点を当てているので独特です。
Helm チャートと比較した場合、Operator の場合の管理コストは少なくなるか、ほぼ同じくらいになります。Operator を導入することで、抽象レイヤーが追加され、管理するべきコンポーネントが1つ増えます。ドキュメントを読んで動作と構成方法を理解するのにコストがかかります。ただし、 PostgreSQL クラスターを何度も展開、破棄する場合、これらのオペレーターは非常に便利です。