スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL Operatorについて

Kubernatesを利用するシステムが増えて来ていることもあり、MySQL製品でもKubernates対応が加速してきています。

データベースのような複雑でステートフルなソフトウェアは、KubernatesのCoreコントローラのみでは正しく管理することが困難であることから、独自のCustom Resource Definition(CRD)と、Operatorを利用することが一般的です。

今回は、Oracleが開発中の MySQL Operator について検証しました。

MySQL(+MySQLフォーク)に関するKubernates Operatorについて

MySQL(or MySQL フォーク)のKubernates Operatorとしては、確認する限り以下のものが存在しています。

なお、2022/03/04時点で mysql-operatorは Alpha バージョンになりますので、GAまでには今回触れた機能以外にも様々な機能が実装される可能性があります。

MySQL Operator

MySQL Operatorは、Kubernates上にMySQLを展開するものですが、ほぼ MySQL InnoDB Cluster 用となっています。
現時点では、MySQL ReplicaSetなどの非同期レプリケーション環境をサポートするものでは無いようです。

インストール方法は、直接マニフェストを適用する他にHelmによる方法が提供されています。
helmを利用する場合は、以下のようにリポジトリを登録し、 helm install を実行するだけです。

helm install 時に設定可能なパラメータについては、 helm show values mysql-operator/mysql-innodbcluster --devel で確認できます。
※ 現在MySQL OperatorはAlpha版であるため --devel フラグを必要とします。

helmを使用すると、 helm upgrade 等によって管理が簡単になりますが、現在のところhelm経由でカスタマイズ可能なパラメータが少ないため、基本的にはマニフェストを使う方法をおすすめします。
ということで、まずリポジトリを git clone してしまいましょう。

MySQL Operatorのデプロイ

オペレータのデプロイは、 deploy/deploy-crds.yaml 及び、 deploy/deploy-operator.yaml を使用します。

Operatorはデフォルトで mysql-operator というNamespaceにデプロイされます。
Namespaceがなければ作成されます。

しばらくするとOperatorが起動します。
OperatorのPodはDeploymentリソースによって管理されているため、Pod停止時はセルフヒーリングされます。

Podでは、mysqlshからmysqloperatorが起動している事がわかります。

これでMySQL InnoDB Clusterをデプロイする準備が整いました。
今回は検証用のNamespace(blog)を作成します。

早速実施したいところですが、mysql-operatorの自動バックアップ機能を利用したいため、事前にPVCを作成します。
k3s にバンドルされているlocal-path-provisionerを利用していますが、バックアップ用PVはReadWriteManyが可能なものを利用したほうが利便性はよいと考えられます。

また、初期データロードのテスト用にsakila databasemysqlsh util.dumpSchemas() でダンプした結果を含むOCI Object Storage(blog-bucket)を作成しています。

OCIへのアクセス情報が必要になりますので、以下のSecretを作成しました。

MySQL InnoDB Clusterのデプロイ

MySQL InnoDB Clusterをデプロイすると以下のリソースが作成されます。

  • StatefulSet: mysqld(Group replication)
  • CronJob : mysqldバックアップ
  • PersistentVolume/PersistentVolumeClaim : mysqld datadir
  • Secret : mysql認証用
  • ConfigMap : mysqld設定ファイル、livenessProbe, readinessProbe 用スクリプト
  • Deployment : mysqlrouter
  • Service : mysqld/mysqlrouter Podへの接続

マニフェストは、sample/sample-cluster.yamlsample/sample-secret.yaml にあり、指定可能なパラメータはChapter 3 MySQL Operator Propertiesで説明されています。

今回は、サンプルを元に指定可能なパラメータを盛り込んだ以下のマニフェストを作成しました。
Secretに平文やbase64 encodeされた値を記載するのはセキュリティ上望ましくないため、本番で利用する場合はkubesecの利用をご検討ください。

設定の意味については、マニフェスト中に記載します。

なお、initDB.dump.storage には persistentVolumeClaimを指定する事ができ、initDB.dump.storage.persistentVolumeClaim.path にロード対象データのパスを指定することも可能な実装になっています。
この際の util.loadDump()sidecar コンテナが実行します。
しかし今回の検証では、persistentVolumeClaim.claimName に指定したディレクトリがマウントされず、volumes定義でマウントすると2つめのPodが起動しないという状態になりましたので、GA時にまた動作を確認したいと思います。

マニフェストの適用については特別な点はありません。

リソース状態の確認

完全に起動すると以下の状態になります。

pod/mycluster-router-5457bfc967-6n7c6 が2回RESTARTしているのは、livenessProbeの開始が早すぎたためですので、もしMySQL Routerからの追加の死活監視等が必要なら開始タイミングの調整をしたほうが良いかもしれません。

Kubernates内部から 各 MySQLインスタンスへは、ServiceによるFQDNでアクセス可能です。

Service リソースが2つありますが、{cluster.name}-instance は各インスタンスへの直接接続用、{cluster.name} はMySQL Routerを介したロードバランス用になります。

例ではmyclusterですのでMySQL Routerへの接続では、mycluster.blog.svc.cluster.local のようなFQDNでアクセスします。
個別のインスタンスへの接続は、 mycluster-0.mycluster-instances.blog.svc.cluster.local のようになります。

接続確認してみましょう。

initDBでロードされたデータも入っています。

バックアップも確認すると、問題なく取れているようです。

backupSchedules.[*].deleteBackupData という設定により、一見古いバックアップをローテーションしてくれそうに見えますが、コード上では実装されていないようでした。
また、バックアップ方法として dump 方式と snapshot 方式の設定が可能ですが、現時点ではsnapshot方式は未実装のようです。

まとめ

とりあえずインストールのみ試してみたという感じですが、GA前のプロダクトにしては問題なく動作している印象を受けました。
まだ実装されていない機能もありますので、GAした際にはさらに便利になっていることでしょう。
Kubernates上でのMySQL運用をお考えの方は今のうちに検証してみてはいかがでしょうか。

Return Top