はじめに
Percona Operator for MySQL は、複雑なDB運用をKubernetesのカスタムリソースとして簡略化してくれる強力なツールです。本ツールは、2種類のレプリケーションタイプをサポートしています。それぞれ以下のような特徴があります。
- グループレプリケーション(Group Replication):GA済み。分散合意アルゴリズムに基づき、ノード間の高い一貫性と読み取りスケーリングを提供します。
- 非同期レプリケーション(Async Replication):tech preview。MySQL伝統のレプリケーション方式です。書き込みレイテンシが低く、グループレプリケーションと比較し、より柔軟なトポロジー構成が可能です。
レプリケーションタイプの変更は、稼働中のクラスターではサポートされていません。設定を変更する際には、一度クラスターを停止させる必要があります。
非同期レプリケーションは現時点の Percona Operator for MySQL 1.0.0 (2025-11-17) バージョンではtech preview段階であり、本番環境での使用は推奨されません。 詳細は以下の公式ドキュメントをご参照ください。
Design and architecture – Percona Operator for MySQL
Asynchronous replication (tech preview)
(…)
- Status – Currently in tech preview and not recommended for production use.
本記事では、tech preview段階ではありますが、あえて非同期レプリケーションを選択し、高可用性管理ツールである Orchestratorを組み合わせた構成を検証します。
Orchestratorは、複雑なトポロジーの可視化と、障害検知からの昇格を自動化してくれる、MySQLレプリケーション運用の定番とも言えるコンポーネントです。
インストール方法に加えて、障害検知時の自動フェイルオーバー挙動について実際の検証手順とともに解説します。
検証環境
本検証では以下のバージョンを使用しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ kubectl version Client Version: v1.35.2 Kustomize Version: v5.7.1 Server Version: v1.34.2 $ helm version version.BuildInfo{Version:"v4.1.1", GitCommit:"5caf0044d4ef3d62a955440272999e139aafbbed", GitTreeState:"clean", GoVersion:"go1.25.7", KubeClientVersion:"v1.35"} $ helm search repo percona/ps-operator NAME CHART VERSION APP VERSION DESCRIPTION percona/ps-operator 1.0.0 1.0.0 A Helm chart for Deploying the Percona Operator... $ helm search repo percona/ps-db NAME CHART VERSION APP VERSION DESCRIPTION percona/ps-db 1.0.0 1.0.0 A Helm chart for installing Percona Server Data... $ mysqld --version /usr/sbin/mysqld Ver 8.4.6-6 for Linux on x86_64 (Percona Server (GPL), Release 6, Revision dbba4396) $ orchestrator --version 3.2.6-18 bd65e056a73002bcfeae403ac5f3768571877311 |
Percona Operator のインストール
Helm を使用して Operator を導入します。
参考: Install with Helm – Percona Operator for MySQL
|
1 2 3 |
$ helm repo add percona https://percona.github.io/percona-helm-charts/ $ helm repo update |
まずは、Operatorのチャートをインストールします。
任意の名前(my-op)と、任意のnamespace名(percona)を付け、インストールします。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ helm install my-op percona/ps-operator --namespace percona --create-namespace NAME: my-op LAST DEPLOYED: Fri Apr 3 06:53:52 2026 NAMESPACE: percona STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES: 1. Percona Operator for MySQL is deployed. See if the operator Pod is running: kubectl get pods -l app.kubernetes.io/name=ps-operator --namespace percona Check the operator logs if the Pod is not starting: export POD=$(kubectl get pods -l app.kubernetes.io/name=ps-operator --namespace percona --output name) kubectl logs $POD --namespace=percona 2. Deploy the database cluster from ps-db chart: helm install my-db percona/ps-db --namespace=percona Read more in our documentation: https://docs.percona.com/percona-operator-for-mysql/ps/ |
Helmチャートのインストールが確認できました。
|
1 2 3 |
$ helm ls --namespace percona NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION my-op percona 1 2026-03-09 09:37:53.781553597 +0000 UTC deployed ps-operator-1.0.0 1.0.0 |
インストール後の確認コマンドが提示されているので、実行してみましょう。
|
1 2 3 |
$ kubectl get pods -l app.kubernetes.io/name=ps-operator --namespace percona NAME READY STATUS RESTARTS AGE my-op-ps-operator-599cdf8dcd-56w5g 1/1 Running 0 3m |
DBクラスターのインストール
次に、DBクラスター本体のチャートをインストールします。
今回の検証用にデフォルト値を変更したいので、あらかじめvalues.yamlファイルに修正を記述しておいて、インストール時にファイルから変数を読み込むようにします。
|
1 |
$ helm show values percona/ps-db > my-db-values.yaml |
以下の点を修正しました。
mysql.clusterTypeをasyncへ変更orchestrator.enabledをtrueに変更
|
1 2 3 4 5 6 7 |
mysql: - clusterType: group-replication + clusterType: async orchestrator: - enabled: false + enabled: true |
任意の名前を付け(my-db)、インストールします。 この時に先ほどのyamlファイルを指定しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$ helm install my-db percona/ps-db --namespace percona -f my-db-values.yaml NAME: my-db LAST DEPLOYED: Fri Apr 3 06:56:54 2026 NAMESPACE: percona STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES: # % _____ %%% | __ \ ###%%%%%%%%%%%%* | |__) |__ _ __ ___ ___ _ __ __ _ ### ##%% %%%% | ___/ _ \ '__/ __/ _ \| '_ \ / _` | #### ##% %%%% | | | __/ | | (_| (_) | | | | (_| | ### #### %%% |_| \___|_| \___\___/|_| |_|\__,_| ,((### ### %%% _ _ _____ _ (((( (### #### %%%% | | / _ \ / ____| | | ((( ((# ###### | | _| (_) |___ | (___ __ _ _ _ __ _ __| | (((( (((# #### | |/ /> _ </ __| \___ \ / _` | | | |/ _` |/ _` | /(( ,((( *### | <| (_) \__ \ ____) | (_| | |_| | (_| | (_| | //// ((( #### |_|\_\\___/|___/ |_____/ \__, |\__,_|\__,_|\__,_| /// (((( #### | | /////////////(((((((((((((((((######## |_| Join @ percona.com/k8s Join Percona Squad! Get early access to new product features, invite-only ”ask me anything” sessions with Percona Kubernetes experts, and monthly swag raffles. >>> https://percona.com/k8s <<< To get a MySQL prompt inside your new cluster you can run: ROOT_PASSWORD=$(kubectl -n percona get secrets my-db-ps-db-secrets -o jsonpath="{.data.root}" | base64 --decode) kubectl -n percona exec -ti \ my-db-ps-db-mysql-0 -- mysql -uroot -p"$ROOT_PASSWORD" |
Perconaロゴの素敵なASCIIアートが表示されましたね。
これで二つのHelmチャートがインストールされました。
|
1 2 3 4 |
$ helm ls --namespace percona NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION my-db percona 1 2026-04-03 06:56:54.863767292 +0000 UTC deployed ps-db-1.0.0 1.0.0 my-op percona 1 2026-04-03 06:53:52.041562509 +0000 UTC deployed ps-operator-1.0.0 1.0.0 |
リソースが作成されるのを少し待ちます。 全てのPodがRunningになるまで、経過を--watchで見ると良いでしょう。 最終的に、MySQLとHAProxyとOrchestratorのPodがそれぞれ3つできます。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
$ kubectl get pods --namespace percona --watch NAME READY STATUS RESTARTS AGE my-db-ps-db-haproxy-0 2/2 Running 0 5m44s my-db-ps-db-haproxy-1 2/2 Running 0 3m40s my-db-ps-db-haproxy-2 2/2 Running 0 3m20s my-db-ps-db-mysql-0 3/3 Running 0 7m8s my-db-ps-db-mysql-1 3/3 Running 1 (4m20s ago) 5m45s my-db-ps-db-mysql-2 3/3 Running 3 (2m6s ago) 3m48s my-db-ps-db-orc-0 2/2 Running 0 7m7s my-db-ps-db-orc-1 2/2 Running 0 6m28s my-db-ps-db-orc-2 2/2 Running 0 5m50s my-op-ps-operator-599cdf8dcd-56w5g 1/1 Running 0 10m |
DBへの接続サンプルコマンドがあるので実行してみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ ROOT_PASSWORD=$(kubectl -n percona get secrets my-db-ps-db-secrets -o jsonpath="{.data.root}" | base64 --decode) $ kubectl -n percona exec -ti \ my-db-ps-db-mysql-0 -- mysql -uroot -p"$ROOT_PASSWORD" (...) mysql> select @@hostname; +---------------------+ | @@hostname | +---------------------+ | my-db-ps-db-mysql-0 | +---------------------+ 1 row in set (0.00 sec) |
接続確認としてMySQL Podに直接アタッチしていますが、HAProxyのServiceをエンドポイントとして接続することが推奨されます。 HAProxyエンドポイントを使用することで、アプリ側で接続先を意識しなくて済みます。
以下は接続例です。
|
1 2 3 4 5 6 7 |
$ kubectl get svc/my-db-ps-db-haproxy NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-db-ps-db-haproxy ClusterIP 10.96.31.80 <none> 3306/TCP,3307/TCP,3309/TCP,33060/TCP,33062/TCP 29m $ export ROOT_PASSWORD=$(kubectl get secret/my-db-ps-db-secrets -ojsonpath="{.data.root}" | base64 -d) $ kubectl run client --image=docker.io/percona/percona-server:8.4.6-6.1 --rm --restart=Never -it \ -- mysql -uroot -p"${ROOT_PASSWORD}" -h my-db-ps-db-haproxy.percona.svc.cluster.local |
デプロイ後、Orchestrator Podにアタッチしてorchestrator-clientコマンドを実行し、Orchestrator のトポロジーを確認してみます。 すると、mysql-0 が Master(rw)、他がSlave(ro)として認識されていることがわかります。
|
1 2 |
$ kubectl exec -it my-db-ps-db-orc-0 --namespace percona -- bash |
|
1 2 3 4 5 6 7 8 9 |
# クラスタエイリアス名確認 $ orchestrator-client -c clusters-alias my-db-ps-db-mysql-0.my-db-ps-db-mysql.percona:3306,my-db-ps-db.percona # 実行結果例 $ orchestrator-client -c topology -i my-db-ps-db.percona my-db-ps-db-mysql-0.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-0) [0s,ok,8.4.6-6,rw,ROW,>>,GTID] + my-db-ps-db-mysql-1.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-1) [0s,ok,8.4.6-6,ro,ROW,>>,GTID] + my-db-ps-db-mysql-2.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-2) [0s,ok,8.4.6-6,ro,ROW,>>,GTID] |
また、OrchestratorのWebUI画面からもトポロジー図を確認しておきましょう。
localhost:3000にポートフォワードするコマンド例
|
1 2 |
$ kubectl port-forward svc/my-db-ps-db-orc --namespace percona 3000:3000 |
ブラウザでhttp://localhost:3000を開きます。

フェイルオーバー試験
実際に稼働中の Pod (mysql-0) を削除し、Orchestrator がどのように新 Master を選出するかを観測します。
Pod の削除
|
1 2 |
$ kubectl delete po/my-db-ps-db-mysql-0 --namespace percona |
OrchestratorがMasterのダウンを検知しました。

昇格の観測
数秒後、Orchestrator が mysql-2 を新たな Master(rw)として昇格させ、mysql-0(再起動後)と mysql-1 をその配下の Slave(ro) として再構成します。

|
1 2 3 4 5 |
# 実行結果例 $ orchestrator-client -c topology -i my-db-ps-db.percona my-db-ps-db-mysql-2.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-2) [0s,ok,8.4.6-6,rw,ROW,>>,GTID] + my-db-ps-db-mysql-0.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-0) [0s,ok,8.4.6-6,ro,ROW,>>,GTID] + my-db-ps-db-mysql-1.my-db-ps-db-mysql.percona:3306 (my-db-ps-db-mysql-1) [0s,ok,8.4.6-6,ro,ROW,>>,GTID] |
Podの自動再作成
deleteしたmysql-0Podは再起動しクラスターに再参加しました。
|
1 2 3 4 5 6 7 8 |
$ kubectl get pods --namespace percona --watch NAME READY STATUS RESTARTS AGE (...) my-db-ps-db-mysql-0 2/3 Running 0 11s my-db-ps-db-mysql-0 1/3 Error 1 (2s ago) 32s my-db-ps-db-mysql-0 2/3 Running 2 (3s ago) 33s my-db-ps-db-mysql-0 2/3 Running 2 (25s ago) 55s my-db-ps-db-mysql-0 3/3 Running 2 (35s ago) 65s |
Orchestratorのログ
Orchestrator の Web UI やログを確認すると、トポロジー変更の履歴が記録されています。
Web UIでは以下のように確認できます。

フェイルオーバーした際の新Masterや、開始終了時間、処理したOrchestratorなどの情報が確認できます。
| 項目 | 詳細内容 |
|---|---|
| Analysis | DeadMaster |
| Failed Instance | mysql-0 |
| Successor | mysql-2 |
| Cluster alias | my-db-ps-db.percona |
| Affected Replicas | 2 (mysql-1, mysql-2) |
| Start Time | 2026-04-03 07:28:36Z |
| End Time | 2026-04-03 07:28:36 |
| Processed By | my-db-ps-db-orc-1 |
またOrchestrator Podのログでも確認可能です。
|
1 2 |
$ kubectl logs my-db-ps-db-orc-1 --namespace percona |
検証は以上です。
Podの削除(障害発生)からOrchestratorによる新Masterの選出、そして他Slaveの向き先変更までが迅速に完結しました。
OrchestratorのWeb UIによって、今どのノードが書き込み許可されているのか、レプリケーションの遅延はないかといった状況が可視化されるのもポイントです。
まとめ
Percona Orchestrator を採用することで、 Kubernetes 上の MySQL 運用において不可欠な「自動フェイルオーバー」と「トポロジーの可視化」が容易になります。
ただし、Percona Operatorの公式ドキュメントにある通り、非同期レプリケーション構成は現時点で tech preview 段階のため、本番環境への採用は推奨されません。こちらは将来的な展望としつつ、構築にあたっては既に GA されているグループレプリケーション構成の検討を強くお勧めします。
KubernetesでのDB運用はOperatorを活用することでインフラ管理の多くを自動化できます。本記事が、最新のクラウドネイティブなDB運用を目指す一助となれば幸いです。


