コンテナでのデータベースの構築を考えてみる

投稿者: | 2月 15, 2025

昔、完全に海外の会社にポツンと日本人一人で勤務していたことがあって、そこで扱う羽目になったのが、PostgreSQLのクラスター、Slonyである。さっぱりわからない。Slonyは書き込みができるノードと参照しかできないノードがあって非同期にレプリケーションされる。知らない割には知っていたんだがわからない。その知らない割に知っていた理由は、前の会社でSlonyを担当していた人間が横にいたから。ある時、トラブルで紛糾していたので、その担当していた人間をこっそり飲みに誘ったことがある。一応、パソコンを開ける個室というのがミソだったのかもしれないが、登場した瞬間、ノートPCを開き、「さて、何にお困りですかと。」

で、Slonyのデータベースを戻したいけど戻らないと実演して見せたら、「あっ、カスケードのスキーマー消さないとリストアできませんよ。」と一瞬で解決。もっと早く聞くべきだった。その後、色々Slonyのことを教えてもらった。というか、聞くこと以上のことを勝手に教えてくれる。2人の弟子というか師匠というかの存在のうちの1人であるが、「マニアなサービス精神」を持つ人間は、見たことがない。というか、最近人を助ける余裕が全くない人が増えてきたなぁと思う。結果として、作業員になってしまうのだが。

 

閑話休題

 

以前、bitnamiのPostgreSQLを以下のようにして構築していた。

cat <<EOF >values.yaml
primary:
extendedConfiguration: |-
  archive_mode = on
  archive_timeout = 60
  archive_command = '/bin/true'
  wal_level = replica
  summarize_wal = on
  wal_summary_keep_time = 14400
EOF
helm install -n ${PG_NAMESPACE} my-release bitnami/postgresql --create-namespace \
                      --set architecture=standalone \
                      --set global.postgresql.auth.postgresPassword="<postgres's Password>" \
                      --set global.postgresql.auth.username=admin \
                      --set global.postgresql.auth.password="<admin's Password>" \
                      --set primary.persistence.storageClass=longhorn \
                      --set primary.persistence.size=8Gi \
                      --set primary.service.type=LoadBalancer \
                        -f values.yaml

まぁ、動かすだけなら、helm install -n ${PG_NAMESPACE} my-release bitnami/postgresql –create-namespace で動くのだが、色々指定したいので設定を加えた。ただ、いくつか問題点があることが判明。

 

1) どれだけリソースが確保されているかわからない。

Kubernetesって、リソースを使い果たすと展開ができないので、シングルノードでやっている場合だと、すぐにノードのリソースを使い果たしてしまう。大抵、何が悪いんだろうと調べても気が付かず。

 

展開時のメッセージで、以下が出る。つまり、ちゃんとリソースを設定しろと。。。

WARNING: There are “resources” sections in the chart not set. Using “resourcesPreset” is not recommended for production. For production installations, please set the following values according to your workload needs:

  – primary.resources

  – readReplicas.resources

+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

 

無指定の場合のリソース要求と制限を調べてとりあえずパラメータに追加した。これで、このPostgreSQLのPodがどれくらいのリソースが必要なのかを意識できるようになる。

--set primary.resources.requests.cpu=100m \
--set primary.resources.requests.memory=128Mi \
--set primary.resources.limits.cpu=150m \
--set primary.resources.limits.memory=192Mi \

こうなってくると、実は仮想マシンでの構築と変わらなくなってくる。

 

2) 大きめなデータベース (2.5GB)をリストアをすると、以下のエラーでリストアが止まってしまう。

psql:demo-big-en-20170815.sql:21595980: server closed the connection unexpectedly

 This probably means the server terminated abnormally

 before or while processing the request.

psql:demo-big-en-20170815.sql:21595980: error: connection to server was lost

 

PostgreSQL自体の設定も必要になってくるのではないかと、postgresql.confの設定を追加したところ、リストアも成功するようになった。

 

最終的な設定は以下となった。PostgreSQL v17特有の設定とログを記録するパラメータも追加設定した。

cat <<EOF >values.yaml
primary:
extendedConfiguration: |-
  max_connections = 300
  shared_buffers = 32MB
  effective_cache_size = 96MB
  maintenance_work_mem = 8MB
  checkpoint_completion_target = 0.9
  wal_buffers = 984kB
  default_statistics_target = 100
  random_page_cost = 1.1
  effective_io_concurrency = 200
  work_mem = 64kB
  huge_pages = off
  min_wal_size = 2GB
  max_wal_size = 8GB
  logging_collector = on
  log_statement = 'all'
  archive_mode = on
  archive_timeout = 60
  archive_command = '/bin/true'
  wal_level = replica
  summarize_wal = on
  wal_summary_keep_time = 14400
EOF
helm install -n ${PG_NAMESPACE} my-release bitnami/postgresql --create-namespace \
                      --set architecture=standalone \
                      --set global.postgresql.auth.postgresPassword="<postgres's Password>" \
                      --set global.postgresql.auth.username=admin \
                      --set global.postgresql.auth.password="<admin's Password>" \
                      --set primary.resources.requests.cpu=100m \
                      --set primary.resources.requests.memory=128Mi \
                      --set primary.resources.limits.cpu=150m \
                      --set primary.resources.limits.memory=192Mi \
                      --set primary.persistence.storageClass=longhorn \
                      --set primary.persistence.accessModes[0]=ReadWriteOnce \
                      --set primary.persistence.size=8Gi \
                      --set primary.service.type=LoadBalancer \
                      --set primary.service.ports.postgresql=5432 \
                      --set readReplicas.enabled=false \
                        -f values.yaml

コンテナだから勝手にやってくれるのは間違いで、ちゃんとリソースを指定したほうがいい。また、仮想マシンで設定していたパラメータを入れ込むことによって正しく動く。つまりデータベースを外だしにする必要もなくなる。

まとめると、データベースのインスタンスのOSの設定とデータベースの設定をちゃんと設定することによって、仮想マシンと同等に動き、さらにコンテナならではの機能も利用可能になってくる。

 

こうなってくると、普通の仮想マシンでPostgreSQLを動かしているのがアホくさく感じる。コンテナのほうが構築が楽なので。

コメントを残す