かつてはステートフルなソフトウェアではKubernatesは難しいということも言われていましたが、最近ではデータベース界隈でも利用が活発化しているように感じます。
MySQLでもα版ですがOperatorを公開していたり、MariaDBでは同社のDBaaSでKubernatesを利用していたりします。
そのような中、Perconaは専用OperatorであるPercona Kubernates Operator for Percona XtraDB Cluster(PKO)をGA版としてリリースしています。
今回はそんなPKOについてご紹介したいと思います。
Custom ResourceとOperatorについて
KubernatesのOperatorについて簡単にご説明します。
KubernatesではPod, ReplicaSet, Deploymentというようなリソースと呼ばれる定義を登録する事で複数のコンテナをルールに基づいて動作させたり、スケジューラジョブを実行したりという事を行います。
実際には各リソースには対応するコントローラと呼ばれるプログラムが存在し、リソース定義(マニフェスト)に記述されたあるべき状態になるように半自動的に管理・運用されます。
初期状態で存在するリソース(コアリソース)で十分ニーズが満たせる場合も多くありますが、高可用性要件を持つデータベース等、複雑な運用が必要な場合、既存のリソースで対応できないことがあります。
そのような場合には、要件に合わせたCustom ResourceとCustom Resourceを管理するためのOperatorを作成する必要があります。
PKOはKubernates上で動作するPercona XtraDB Clusterのノード数、状態の監視、障害復旧のプロセスの自動化等を実現するためのCustom ResourceとOperatorです。
検証環境について
今回、検証環境としてのKubernates ClusterはOracle Cloud Infrastructure Container Engine for Kubernetes(OKE) を利用しました。
数ステップですぐ利用を開始でき、非常に簡単ですので興味があればお試しください。
https://docs.cloud.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengcreatingclusterusingoke.htm
クイックスタートに従い3ノードのワーカーノードを持つOKEを起動しました。
1 2 3 4 5 |
$ kubectl get nodes NAME STATUS ROLES AGE VERSION 10.0.10.2 Ready node 3d4h v1.16.8 10.0.10.3 Ready node 3d4h v1.16.8 10.0.10.4 Ready node 3d4h v1.16.8 |
なお、実はPKOはOKE上での動作をテストしていません(ただし恐らく動作するでしょうとの記載があります)。
https://www.percona.com/doc/kubernetes-operator-for-pxc/System-Requirements.html
The following platforms are supported:
- OpenShift 3.11
- OpenShift 4.2
- Google Kubernetes Engine (GKE) 1.13
- GKE 1.15
- Amazon Elastic Kubernetes Service (EKS) 1.15
- Minikube 1.16
Other Kubernetes platforms may also work but have not been tested.
あくまで今回検証用途ということでご理解頂き、もし本番利用されたい方は上記にご注意ください。
以降の内容は、OKEのセットアップ、kubectlの準備が完了し、操作が可能である事を前提とします。
PKOの入手~デプロイ~接続確認
ドキュメントに沿ってデプロイまで行います。
早速以下のコマンドでPKOを入手します。
1 |
$ git clone -b v1.5.0 https://github.com/percona/percona-xtradb-cluster-operator |
ここではpxcというネームスペースを作成し、切り替えます。
1 2 |
$ kubectl create namespace pxc $ kubectl config set-context $(kubectl config current-context) --namespace=pxc |
以下の一連のコマンドを実行すると、デフォルトの状態でPKOの各リソースが起動します。
1 2 3 4 5 6 |
$ cd percona-xtradb-cluster-operator $ kubectl apply -f deploy/crd.yaml $ kubectl apply -f deploy/rbac.yaml $ kubectl apply -f deploy/operator.yaml $ kubectl apply -f deploy/secrets.yaml $ kubectl apply -f deploy/cr.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 |
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/cluster1-haproxy-0 2/2 Running 0 4m33s pod/cluster1-haproxy-1 2/2 Running 0 4m27s pod/cluster1-haproxy-2 2/2 Running 0 4m20s pod/cluster1-pxc-0 1/1 Running 0 4m33s pod/cluster1-pxc-1 1/1 Running 0 3m14s pod/cluster1-pxc-2 1/1 Running 0 2m2s pod/percona-xtradb-cluster-operator-5c99579f95-tj24p 1/1 Running 0 9m2s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/cluster1-haproxy ClusterIP 10.96.146.238 <none> 3306/TCP,3309/TCP 4m33s service/cluster1-haproxy-replicas ClusterIP 10.96.12.225 <none> 3306/TCP 4m33s service/cluster1-pxc ClusterIP None <none> 3306/TCP 4m33s service/cluster1-pxc-unready ClusterIP None <none> 3306/TCP 4m33s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/percona-xtradb-cluster-operator 1/1 1 1 9m2s NAME DESIRED CURRENT READY AGE replicaset.apps/percona-xtradb-cluster-operator-5c99579f95 1 1 1 9m2s NAME READY AGE statefulset.apps/cluster1-haproxy 3/3 4m33s statefulset.apps/cluster1-pxc 3/3 4m33s NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/daily-backup 0 0 * * * False 0 <none> 4m33s cronjob.batch/sat-night-backup 0 0 * * 6 False 0 <none> 4m33s $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-cluster1-pxc-0 Bound ocid1.volume.oc1.ap-tokyo-1.abxhiljrylrgobhq5d2foipa4wnxchwn774lyaxvfsx2lz34jswbnypncpoq 50Gi RWO oci 3d5h datadir-cluster1-pxc-1 Bound ocid1.volume.oc1.ap-tokyo-1.abxhiljrlxoknvgizdlrvx7pf5g5fc4jqnmyhvkpyesbslsyx4by7dowytoa 50Gi RWO oci 3d5h datadir-cluster1-pxc-2 Bound ocid1.volume.oc1.ap-tokyo-1.abxhiljrfpoqkdbdrq6v2szbvesfk2e6pvtbnijvzataaorytqx3wxa4ybpa 50Gi RWO oci 3d5h |
図にすると以下の状態です。
クライアント用イメージをデプロイして接続出来ることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ kubectl run -i --rm -t percona-client --image=percona:5.7 --restart=Never -- bash percona$ while :;do mysql -h cluster1-haproxy -uroot -proot_password -e "select @@hostname";sleep 1;done 2>/dev/null cluster1-pxc-0 cluster1-pxc-0 cluster1-pxc-0 : percona$ while :;do mysql -h cluster1-haproxy-replicas -uroot -proot_password -e "select @@hostname";sleep 1;done 2>/dev/null cluster1-pxc-0 cluster1-pxc-1 cluster1-pxc-2 : |
とても簡単にフルスタックなPXC環境を用意することができました。
PKOのマニフェスト
PKOのリポジトリ以下で基本的にユーザが修正する必要があるのは deploy
ディレクトリ以下のマニフェストファイルのみです。
deployディレクトリには以下のファイルが含まれています。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ tree deploy -L 1 --dirsfirst -F deploy ├── backup/ ├── backup-s3.yaml ├── bundle.yaml ├── cr.yaml ├── crd.yaml ├── operator.yaml ├── rbac.yaml ├── secrets.yaml ├── ssl-secrets.yaml └── vault-secret.yaml |
このマニフェストを修正する事で、Kubernatesワーカノードのリソースが許す限りユーザ好みの設定にカスタマイズ可能となっています。
まず修正する必要があるものとして、secrets.yamlがあります。
これにはMySQLユーザのパスワード情報が含まれていますので、必要に応じて修正します。
Kubernatesの仕様上、Secretに含まれるパスワードはbase64エンコードされているため見ただけでは元のパスワードはわかりませんが、
簡単にデコードできますので、実運用時は kubesec 等のツールでマニフェストを暗号化する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ cat deploy/secrets.yaml apiVersion: v1 kind: Secret metadata: name: my-cluster-secrets type: Opaque data: root: cm9vdF9wYXNzd29yZA== xtrabackup: YmFja3VwX3Bhc3N3b3Jk monitor: bW9uaXRvcg== clustercheck: Y2x1c3RlcmNoZWNrcGFzc3dvcmQ= proxyadmin: YWRtaW5fcGFzc3dvcmQ= pmmserver: c3VwYXxefHBheno= operator: b3BlcmF0b3JhZG1pbg== $ echo "cm9vdF9wYXNzd29yZA==" | base64 -d root_password |
パスワードはデプロイ後に変更可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ echo -n "P@ssw0rd" | base64 UEBzc3cwcmQ= $ sed -i.bak "s/ root:.\*$/ root: UEBzc3cwcmQ=/g" deploy/secrets.yaml $ kubectl apply -f deploy/secrets.yaml secret/my-cluster-secrets configured $ kubectl run -i --rm -t percona-client --image=percona:5.7 --restart=Never -- \ mysql -uroot -pP@ssw0rd -hcluster1-haproxy -e "select @@hostname" +----------------+ | @@hostname | +----------------+ | cluster1-pxc-0 | +----------------+ pod "percona-client" deleted |
次にcr.yamlを確認しましょう。
PKOが提供するCustom Resourceのオプションのリファレンスを確認しつつカスタムしていくこととなります。
最初はupdate関連のセクションが定義されています。
v1.5.0から実装されたSmartUpdate機能がデフォルトで有効です。
1 2 3 4 5 |
updateStrategy: SmartUpdate upgradeOptions: versionServiceEndpoint: https://check.percona.com/versions apply: recommended schedule: "0 4 * * *" |
これは自動的に最新のマイナーリリースへアップデートしてくれるという非常に便利な機能です。
インターネットに接続していない環境でも、versionServiceEndpointに指定されたPercona社が実行しているバージョン通知サービスと同等のソフトウェアをクラスタ内で実行することも可能です。
理由によりバージョンロックしたい場合はapplyにバージョン番号を指定すると該当バージョン以上にアップデートしないという動作になります。
興味がありましたらマニュアルをご確認ください。
次にpxcセクションではデータベースノードの設定を行います。
複数のパラメータがありますが、configuration(=my.cnfに設定するパラメータ)、resources(=メモリ・CPUの割当)は構築時に変更する事になるでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
pxc: size: 3 image: percona/percona-xtradb-cluster:8.0.19-10.1 : # configuration: | # [mysqld] # wsrep_debug=ON # wsrep_provider_options="gcache.size=1G; gcache.recover=yes" # [sst] # xbstream-opts=--decompress # [xtrabackup] # compress=lz4 : resources: requests: memory: 1G cpu: 600m |
Podのスケジューリングポリシはデフォルトでは 同じワーカノード(=ホスト名)にポッドを配置しない
という設定です。
マルチリージョン/ゾーン、データベース用のKubernatesワーカノードが存在する場合などはaffinityを修正する必要がでてきます。
1 2 |
affinity: antiAffinityTopologyKey: "kubernetes.io/hostname" |
設定値はこちらのブログで紹介されています。
kubectl drainを実行し、計画的に縮退運転する場合に最大で1ノードまで許容されるという設定となっています。
3ノード以上の構成などでは増やしてみても良いかもしれません。
1 2 |
podDisruptionBudget: maxUnavailable: 1 |
ボリュームに関する設定は以下です。
resources.requests.storageのサイズは必ず変更することになるでしょう。
storageClassNameにはクラウドプロバイダによってより高速なディスクが指定可能であったりします。
OKEの場合はこちらに記載があります。
なお、OKEでは最低50GiBからですので、6Giと設定されていても50GiBが割り当てられていました。
1 2 3 4 5 6 7 8 9 |
volumeSpec: : persistentVolumeClaim: # storageClassName: standard # accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 6Gi gracePeriod: 600 |
さらに下部にはhaproxy, proxysqlのセクションがあります。
デフォルトではhaproxyが有効なようですが、HAProxyを実装したチケット内で紹介されている実装の経緯についてのリンクは非公開でした(涙)
各セクションのenabledを有効化することでどちらを使用するか選択できるようになっています。
pxcセクションとは異なり概ねKubernatesとしてのパラメータで構成されているようです。
1 2 3 4 5 6 7 8 9 10 |
haproxy: enabled: true size: 3 image: percona/percona-xtradb-cluster-operator:1.5.0-haproxy : proxysql: enabled: false size: 3 image: percona/percona-xtradb-cluster-operator:1.5.0-proxysql : |
proxysqlを選択した場合、設定保存用DB(Percona XtraDB Cluster)がサイドカーコンテナとして起動します。
このノードはワークロード上ほとんどスペックを必要としませんが、よりシンプルな仕組みを望まれる場合はhaproxyを選択するのもよいでしょう。
PKO上のProxySQLについてはこちらのブログで紹介されています。
その他としてPMMの監視を開始することも可能です。
以下はPMM ClientのDocker imageに関する設定であることにご注意ください(別途PMM Serverの起動が必要です)。
1 2 3 4 5 |
pmm: enabled: false image: percona/percona-xtradb-cluster-operator:1.5.0-pmm serverHost: monitoring-service serverUser: pmm |
最後にbackupセクションがあります。
backupは、CronJobリソースとして定期的に実行することも可能であり、またkubectl apply -f deploy/backup.yamlとしてオンデマンドで取得することも可能です。
デフォルトではS3(および互換ストレージ)にバックアップを保存する設定(storages.type = s3)となっています。
ストレージのサイズ、スケジュール等は環境に合わせて修正することとなりそうです。
また、バックアップをどのノードで実行するかという点は運用上意識する必要がありますので、Affinity, TaintsとTolerations
などのスケジューリング設定も調整する必要がでてくるでしょう。
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 |
backup: image: percona/percona-xtradb-cluster-operator:1.5.0-pxc8.0-backup serviceAccountName: percona-xtradb-cluster-operator : storages: s3-us-west: type: s3 : s3: bucket: S3-BACKUP-BUCKET-NAME-HERE credentialsSecret: my-cluster-name-backup-s3 region: us-west-2 fs-pvc: type: filesystem : volume: persistentVolumeClaim: : resources: requests: storage: 6Gi schedule: - name: "sat-night-backup" schedule: "0 0 * * 6" keep: 3 storageName: s3-us-west - name: "daily-backup" schedule: "0 0 * * *" keep: 5 storageName: fs-pvc |
まとめ
今回はPKOのデプロイとマニフェストについてご紹介しました。
ご紹介しきれなかった内容も含め、PKOをデプロイするだけで以下の機能を実現できます。
- 高可用性(フェイルオーバ・スイッチオーバ・セルフヒーリング)
- データベースプロキシ
- スケジュールされたリモート送信可能なバックアップジョブ
- 監視クライアントの実装
- 半自動的なアップグレード
ユーザ数も順調に伸びていると見受けられ、Issueも活発に動いているようです。
https://jira.percona.com/projects/K8SPXC/issues/
もし手元にKubernatesを触れる環境がありましたら、ぜひ今のうちに検証してみてはいかがでしょうか。