Postgres Operator on Azure Kubernetes Service
AKS (Azure Kubernetes Service) のお勉強がてら Kubernetes 関連の記事を眺めていたところ、「データ永続化と構築運用の自動化を実現する「PostgreSQL on Kubernetes」の仕組み:クラウドネイティブ時代のデータベース(2) - @IT」という記事があり、その中で紹介されている Postgres Operator が気になったので触ってみました。
環境
- AKS (v1.21.1)
- Postgres Operator (v4.7.0)
- WSL 2 (Ubuntu 20.04)
準備
Azure CLI などは Windows 環境でも利用できますが、Azure ドキュメント類において bash 表記になっていたりして環境変数の設定がコピペで実施できなくて面倒だったりするので、WSL 2 の Ubuntu を利用します。
また、以降の手順はベースとして Quickstart を参考にしています。一部抜粋ではありますので、詳細な内容については上記のマニュアルも併せて読んでみてください。
インストール
Postgres Operator のインストール (AKS へのデプロイ)
kubectl create namespace pgo
kubectl apply -f https://raw.githubusercontent.com/CrunchyData/postgres-operator/v4.7.0/installers/kubectl/postgres-operator.yml
デフォルトの環境では特にエラーもなくデプロイできました。
Postgres Operator Client のインストール
curl https://raw.githubusercontent.com/CrunchyData/postgres-operator/v4.7.0/installers/kubectl/client-setup.sh > client-setup.sh
chmod +x client-setup.sh
./client-setup.sh
注意点としては、このスクリプトの中で Kubernetes と接続する必要があるため、kubectl
コマンドで Kubernetes クラスターに接続できていることを確認しておきましょう。
下記のようなメッセージが出ていれば OK のはずです。
pgo client files have been generated, please add the following to your bashrc
export PATH=/home/<user>/.pgo/pgo:$PATH
export PGOUSER=/home/<user>/.pgo/pgo/pgouser
export PGO_CA_CERT=/home/<user>/.pgo/pgo/client.crt
export PGO_CLIENT_CERT=/home/<user>/.pgo/pgo/client.crt
export PGO_CLIENT_KEY=/home/<user>/.pgo/pgo/client.key
公式の手順に則り、環境変数を追加しておきます。
cat <<EOF >> ~/.bashrc
export PGOUSER="${HOME?}/.pgo/pgo/pgouser"
export PGO_CA_CERT="${HOME?}/.pgo/pgo/client.crt"
export PGO_CLIENT_CERT="${HOME?}/.pgo/pgo/client.crt"
export PGO_CLIENT_KEY="${HOME?}/.pgo/pgo/client.key"
export PGO_APISERVER_URL='https://127.0.0.1:8443'
export PGO_NAMESPACE=pgo
EOF
source ~/.bashrc
インストール確認
別のターミナルを開き、下記のコマンドを実行してアクセスできるようにしておきます。この接続 (ポートフォワーディング) は以降も使うので、実行しっぱなしにしておきましょう。
kubectl -n pgo port-forward svc/postgres-operator 8443:8443
そのうえで、pgo version
コマンドがエラーなく実行できれば、インストール完了です。
$ pgo version
pgo client version 4.7.0
pgo-apiserver version 4.7.0
試してみる
クラスターの作成 (1)
hippo
というクラスターを作成してみます。コマンドの実行後、PostgreSQL のユーザー名とパスワードが表示されます。
$ pgo create cluster -n pgo hippo
created cluster: hippo
workflow id: 934184a4-9e9f-4283-bfd5-f1ead389eb58
database name: hippo
users:
username: testuser password: :-7Pq?*y/,TmzzQgPbqFMDoX
作成状況は、pgo test
コマンドで確認できます。最初はまだ DOWN
状態ですが…
$ pgo test -n pgo hippo
cluster : hippo
Services
Instances
primary (): DOWN
しばらく待つと、UP
状態になります。
$ pgo test -n pgo hippo
cluster : hippo
Services
primary (10.0.51.3:5432): UP
Instances
primary (hippo-6458f6b475-7mstm): UP
Pod を確認してみます。新しい Pod が作成されています!
$ kubectl -n pgo get po
NAME READY STATUS RESTARTS AGE
backrest-backup-hippo-7hhp5 0/1 Completed 0 103s
hippo-6458f6b475-7mstm 1/1 Running 0 3m4s
hippo-backrest-shared-repo-7fb55dfcd4-92v65 1/1 Running 0 3m49s
pgo-deploy-6kvkd 0/1 Completed 0 27m
postgres-operator-668987fdb4-7hv9q 4/4 Running 1 26m
Service を確認しますが、EXTERNAL-IP が振られていないので外部アクセスはできません😢
$ kubectl -n pgo get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hippo ClusterIP 10.0.51.3 <none> 2022/TCP,5432/TCP 3m51s
hippo-backrest-shared-repo ClusterIP 10.0.167.120 <none> 2022/TCP 3m51s
postgres-operator ClusterIP 10.0.42.206 <none> 8443/TCP,4171/TCP,4150/TCP 26m
クラスターの作成 (2)
サクッと試せたので、もう少しオプションを付けて作成してみます。--service-type
で LoadBalancer を指定し、--replica-count
でレプリカ数を 2 にしてみます。
pgo create cluster lb-rep-db \
--service-type=LoadBalancer \
--replica-count 2 \
10分くらい時間がかかる場合がありますので、気長に待ちます☕
完了したら、Pod と Service を確認してみます。
$ kubectl -n pgo get po
NAME READY STATUS RESTARTS AGE
backrest-backup-lb-rep-db-57mjg 0/1 Completed 0 8m15s
lb-rep-db-9cc696cd7-g74dk 2/2 Running 0 9m
lb-rep-db-backrest-shared-repo-68899b9bfb-x82v7 1/1 Running 0 9m20s
lb-rep-db-crul-777f4cc998-qdc8p 2/2 Running 0 7m42s
lb-rep-db-wsjq-546bc99984-kchvs 2/2 Running 0 7m42s
pgo-deploy-6kvkd 0/1 Completed 0 45m
postgres-operator-668987fdb4-7hv9q 4/4 Running 1 44m
$ kubectl -n pgo get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
lb-rep-db LoadBalancer 10.0.6.195 20.43.88.99 9187:31938/TCP,2022:32201/TCP,5432:30720/TCP 9m25s
lb-rep-db-backrest-shared-repo ClusterIP 10.0.89.222 <none> 2022/TCP 9m25s
lb-rep-db-replica LoadBalancer 10.0.23.7 52.155.112.137 9187:30002/TCP,2022:32284/TCP,5432:30629/TCP 7m47s
postgres-operator ClusterIP 10.0.42.206 <none> 8443/TCP,4171/TCP,4150/TCP 44m
先ほどの hippo
の結果と比べると、Pod では lb-rep-db-crul-777f4cc998-qdc8p
と lb-rep-db-wsjq-546bc99984-kchvs
が、Service では lb-rep-db-replica
が増えています。これが、レプリカサーバーの Pod と Service になっているようです。
また、EXTERNAL-IP も振られているので、外部アクセスができるようになりました。
スケールアップしてみる
このクラスタをスケールアップしてみます。スケールアップのコマンドは pgo scale
です。
$ pgo scale lb-rep-db
WARNING: Are you sure? (yes/no): yes
created Pgreplica lb-rep-db-ymwn
新しいレプリカ (lb-rep-db-ymwn-9c8975556-b72h7
) が作成されました。今度はそれほど時間はかからず、手元の環境だと 1 分くらいでした。
$ kubectl -n pgo get po
NAME READY STATUS RESTARTS AGE
backrest-backup-lb-rep-db-57mjg 0/1 Completed 0 9m33s
lb-rep-db-9cc696cd7-g74dk 2/2 Running 0 10m
lb-rep-db-backrest-shared-repo-68899b9bfb-x82v7 1/1 Running 0 10m
lb-rep-db-crul-777f4cc998-qdc8p 2/2 Running 0 9m
lb-rep-db-wsjq-546bc99984-kchvs 2/2 Running 0 9m
lb-rep-db-ymwn-9c8975556-b72h7 2/2 Running 0 1m37s
pgo-deploy-6kvkd 0/1 Completed 0 47m
postgres-operator-668987fdb4-7hv9q 4/4 Running 1 46m
スケールダウンしてみる
スケールダウンは pgo scaledown
コマンドです。落としたいサーバを指定することができます。
--query
オプションを追加してレプリカ名を確認し…
$ pgo scaledown lb-rep-db --query
Cluster: lb-rep-db
REPLICA STATUS NODE REPLICATION LAG PENDING RESTART
lb-rep-db-crul running aks-agentpool-92398728-vmss00000p 0 MB false
lb-rep-db-wsjq running aks-agentpool-92398728-vmss00000r 0 MB false
lb-rep-db-ymwn running aks-agentpool-92398728-vmss00000q 0 MB false
--target
オプションで指定してスケールダウンします。
$ pgo scaledown lb-rep-db --target=lb-rep-db-wsjq
今回は、スケールダウン中の Pod の動きを追ってみました。
$ kubectl -n pgo get po -w
NAME READY STATUS RESTARTS AGE
backrest-backup-lb-rep-db-57mjg 0/1 Completed 0 12m
lb-rep-db-9cc696cd7-g74dk 2/2 Running 0 13m
lb-rep-db-backrest-shared-repo-68899b9bfb-x82v7 1/1 Running 0 13m
lb-rep-db-crul-777f4cc998-qdc8p 2/2 Running 0 11m
lb-rep-db-wsjq-546bc99984-kchvs 2/2 Running 0 11m
lb-rep-db-ymwn-9c8975556-b72h7 2/2 Running 0 3m9s
pgo-deploy-6kvkd 0/1 Completed 0 49m
postgres-operator-668987fdb4-7hv9q 4/4 Running 1 49m
lb-rep-db-rmdata-wzbw-c8tfc 0/1 Pending 0 0s
lb-rep-db-rmdata-wzbw-c8tfc 0/1 Pending 0 0s
lb-rep-db-rmdata-wzbw-c8tfc 0/1 ContainerCreating 0 0s
lb-rep-db-wsjq-546bc99984-kchvs 2/2 Terminating 0 12m
lb-rep-db-wsjq-546bc99984-kchvs 2/2 Terminating 0 12m
lb-rep-db-rmdata-wzbw-c8tfc 1/1 Running 0 2s
lb-rep-db-wsjq-546bc99984-kchvs 0/2 Terminating 0 12m
lb-rep-db-wsjq-546bc99984-kchvs 0/2 Terminating 0 12m
lb-rep-db-wsjq-546bc99984-kchvs 0/2 Terminating 0 12m
lb-rep-db-rmdata-wzbw-c8tfc 0/1 Completed 0 10s
lb-rep-db-rmdata-wzbw-c8tfc 0/1 Terminating 0 10s
lb-rep-db-rmdata-wzbw-c8tfc 0/1 Terminating 0 10s
lb-rep-db-rmdata-wzbw-c8tfc
という Pod が作成された後、lb-rep-db-wsjq-546bc99984-kchvs
Pod が削除されているのが分かります。*-rmdata-*
な Pod は、名前からすると削除処理のジョブ的な動きをする Pod ですかね。なかなか面白いです。
今回は、このあたりまでにしておこうと思います。
公式ドキュメント にあるように、他にも様々な機能があります。「定期バックアップ機能」も試してみたいですし、「永続領域は Azure Files 等に保存する」とかもやってみたいですねー。
Discussion