概要
Operatorは、CoreOS社(2018年現在はRedHat社)が、2016年に管理者のもつアプリケーションのナレッジを、Kubernetesの拡張機能を活用しソフトウェアとしてプログラムするものとして、発表されました。Kubernetesでは、セルフヒーリングなどインフラストラクチャーの運用を自律化させるフレームワークが備わっています。このフレームワークを使ったOperatorを開発することでアプリケーションの運用を支援します。
今回は、2018/7にv0.2.0が公開されたOracle社が提供するMySQL-Operatorの動作検証を行います。
検証環境
- Kubernetes v1.10.0
- minikube v0.28.2
- Helm v2.9.1
事前準備
MySQL-Operator はHelmをつかってデプロイするため、Helmのセットアップを行います。
$ helm init
...
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
...
tiller-deploy-f9b8476d-79g5k 1/1 Running 0 6m
これにより、Kubernetesのkube-system
ネームスペースにTaillerのPodがデプロイされます。
Operatorのデプロイ
初めに公式のGitHubレポジトリからMySQL-Operatorをダウンロードします。
$ git clone https://github.com/oracle/mysql-operator.git
Cloning into 'mysql-operator'...
...
$ cd mysql-operator
次に、MySQL-Operatorをデプロイします。デプロイ先のデフォルトはmysql-operator
ネームスペースになります。
$ kubectl create namespace mysql-operator
namespace "mysql-operator" created
$ helm install --name mysql-operator mysql-operator
NAME: mysql-operator
LAST DEPLOYED: Sun Aug 12 19:40:33 2018
NAMESPACE: kube-system
STATUS: DEPLOYED
RESOURCES:
==> v1/ServiceAccount
NAME SECRETS AGE
mysql-operator 1 0s
mysql-agent 1 0s
==> v1beta1/CustomResourceDefinition
NAME AGE
mysqlclusters.mysql.oracle.com 0s
mysqlbackups.mysql.oracle.com 0s
mysqlrestores.mysql.oracle.com 0s
mysqlbackupschedules.mysql.oracle.com 0s
==> v1beta1/ClusterRole
mysql-operator 0s
mysql-agent 0s
==> v1beta1/ClusterRoleBinding
NAME AGE
mysql-agent 0s
mysql-operator 0s
==> v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mysql-operator 1 1 1 0 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
mysql-operator-56cb675b7f-jr56r 0/1 Pending 0 0s
NOTES:
Thanks for installing the MySQL Operator.
Check if the operator is running with
kubectl -n mysql-operator get po
$ kubectl get pod -n mysql-operator
NAME READY STATUS RESTARTS AGE
mysql-operator-56cb675b7f-jr56r 1/1 Running 0 3m
mysql-operator-XXXXXというPodがデプロイされていればデプロイ成功です。
MySQL-Operatorでは、次の4つのCRD(CustomResourceDefinition)がデプロイされます。
- mysqlclusters.mysql.oracle.com
MySQLのクラスタをコントロール (kind: Cluster) - mysqlbackups.mysql.oracle.com
データのバックアップをコントロール (kind:Backup ) - mysqlrestores.mysql.oracle.com
データのリストアをコントロール (kind: Restore) - mysqlbackupschedules.mysql.oracle.com
定期実行のバックアップスケジュールをコントロール (kind: BackupSchedule)
Operatorでは、こららのCRDを使いMySQLを操作していきます。
シンプルな構成のMySQLのデプロイ
今回の検証では、default
ネームスペースにMySQLをデプロイします。
まずは、default
ネームスペースにServiceAccountとRoleBindingを設定します。以下のようなserviceaccount.yaml
ファイルを作成します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: mysql-agent
namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: mysql-agent
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: mysql-agent
subjects:
- kind: ServiceAccount
name: mysql-agent
namespace: default
定義したServiceAccountとRoleBindingをkubectlを使ってデプロイします。
$ kubectl create -f serviceaccount.yaml
serviceaccount "mysql-agent" created
rolebinding "mysql-agent" created
続いて、シンプルなMySQLのクラスタ構成を作るための定義を、以下のcluster.yaml
ファイルに作成します。
apiVersion: mysql.oracle.com/v1alpha1
kind: Cluster
metadata:
name: my-app-db
namespace: default
定義したClusterをkubectlを使ってデプロイします。
$ kubectl create -f cluster.yaml
mysqlcluster "my-app-db" created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-db-0 2/2 Running 0 17m
my-app-db-1 2/2 Running 0 2m
my-app-db-2 2/2 Running 0 1m
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-app-db ClusterIP None <none> 3306/TCP 19m
...
デプロイが成功すると、StatefulSetにて3つのPodが生成されます。また、Service(svc)には、各Podの名前をDNSへ登録するためのヘッドレスサービスmy-app-d
が登録されています。
続いて、デプロイしたMySQLへアクセスしてみます。
MySQL Operatorのデフォルトでは、Rootパスワードは自動生成されているため、MySQLのRootパスワードを取得します。
$ kubectl get secret my-app-db-root-password -o jsonpath="{.data.password}" | base64 --decode
<Password>
取得したRootパスワードを使って、MySQLのテーブルにアクセスします。
アクセスには、mysqlコマンドを利用します。
$ kubectl run mysql-client --image=mysql:5.7 -it --rm --restart=Never -- mysql -h my-app-db -uroot -p<Password> -e 'SELECT 1'
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+
デプロイしたMySQLを削除します。
$ kubectl delete -f cluster.yaml
mysqlcluster "my-app-db" deleted
Rootパスワード変更+PersistentVolume構成のMySQLのデプロイ
次に、MySQLの以下の点をカスタマイズしデプロイします。
- MySQLのRootパスワードを任意に変更
- MySQLのデプロイ数を2つに変更
- Multi-MasterモードのMySQLに変更
- MySQLのデータ格納ディレクトリをPersistentVolumeを使用
まず、MySQLのRootパスワードを格納するSecretを作成します。
$ kubectl create secret generic mysql-root-user-secret --from-literal=password=hogehoge
secret "mysql-root-user-secret" created
次に、MySQLのYAMLをcluster-pv.yaml
に作成します。
apiVersion: mysql.oracle.com/v1alpha1
kind: Cluster
metadata:
name: my-app-db
spec:
rootPasswordSecret:
name: mysql-root-user-secret
members: 2
multiMaster: true
volumeClaimTemplate:
metadata:
name: data
spec:
storageClassName: standard
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
spec. rootPasswordSecret
に、先ほど作成したSecretを指定します。この指定により、MySQLのRootパスワードが任意に指定できます。
spec. members
には、MySQLのデプロイ数を指定します。ここではデプロイ数を2を設定しています。
spec.multiMaster
にTrueを指定することで、Multi-MasterモードのMySQLとなります。
spec.volumeClaimTemplate
には、MySQLのデータ格納ディレクトリの格納先となるPersistentVolumeを指定します。このvolumeClaimTemplate
は、StatefulSetでPodが生成される際に、自動でPersistentVolumeClaimとPersistentVolumeを作成します。今回の検証では、minikubeを利用しているため、あらかじめminikubeに設定されているStorageClassのstandardをstorageClassName
に指定します。
作成したcluster-pv.yaml
をデプロイします。
$ kubectl create -f cluster-pv.yaml
mysqlcluster "my-app-db" created
デプロイしたMySQLを確認します。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-db-0 2/2 Running 0 1m
my-app-db-1 1/2 Running 0 44s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
my-app-db ClusterIP None <none> 3306/TCP 1m
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-my-app-db-0 Bound pvc-d536b611-a04c-11e8-9566-080027ae26d3 1Gi RWO standard 2m
data-my-app-db-1 Bound pvc-f115036f-a04c-11e8-9566-080027ae26d3 1Gi RWO standard 1m
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-d536b611-a04c-11e8-9566-080027ae26d3 1Gi RWO Delete Bound default/data-my-app-db-0 standard 2m
pvc-f115036f-a04c-11e8-9566-080027ae26d3 1Gi RWO Delete Bound default/data-my-app-db-1 standard 1m
MySQLのPodが2つと、データ格納のPersistentVolumeClaimとPersistentVolumeがデプロイされているのが確認できます。
さらに、kubectl describeコマンドでPodを確認してみます。
$ kubectl describe pod my-app-db-0
Name: my-app-db-0
Namespace: default
...
Mounts:
/var/lib/mysql from data (rw)
/var/lib/mysql-agent from mysqlbackupvolume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from mysql-agent-token-9ztcv (ro)
...
Volumes:
data:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: data-my-app-db-0
ReadOnly: false
mysqlbackupvolume:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
mysql-agent-token-9ztcv:
Type: Secret (a volume populated by a Secret)
SecretName: mysql-agent-token-9ztcv
Optional: false
my-app-db-0
のPod内の/var/lib/mysql
が、自動生成されたPersistentVolumeClaimのdata-my-app-db-0
を使ってPersistentVolumeをマウントしているのがわかります。
以上で。Rootパスワード変更+PersistentVolume構成のMySQLがデプロイされました。
クリーンアップ
最初に、デプロイしたMySQLと自動生成されたPersistentVolumeClaim、PersistentVolumeを削除します。
$ kubectl delete -f cluster-pv.yaml
$ kubectl delete pvc --all
$ kubectl delete pv --all
次に、ServiceAccountとRoleBindingを削除します。
$ kubectl delete -f serviceaccount.yaml
最後に、MySQL Operatorとmysql-operator
ネームスペースを削除します。
$ helm delete mysql-operator
$ kubectl delete ns mysql-operator
感想
今回の動作検証では、MySQLのデプロイメントを行いました。MySQL Operatorにより、複雑なYAMLを作成しなくても容易にMySQLのクラスタ構成をデプロイすることが可能です。Operatorを使わず、クラスタ構成のMySQLのYAMLを作成しようとすると、インフラストラクチャーのナレッジとMySQLのナレッジの両方を身につける必要があります。しかし、MySQLが今すぐ欲しい、MySQLを利用するアプリケーションの開発に専念したい等、これらのナレッジをもった管理者が側にいれば良いのになぁと思うケースもあるでしょう。このような場合に、MySQL Operatorを使うと有効かと思います。
このように、Operatorは管理者のナレッジを実現し、アプリケーションの運用を支援するソフトウェアになります。またOperatorのユーザや開発者が多くなりあらゆる運用のナレッジがOperatorに実装されるようになれば、これまで組織や管理者ごとにバラバラであった運用ナレッジを、世界中で共有することができるかも知れません。
残念な点としては、MySQL Operatorはv0.2.0(2018/8現在)と開発がスタートしたばかりのため、以下の制限があるようです。今後の開発に期待します。
- Maser-Slave構成が不完全
MySQLのPodのデプロイは行われますが、Slaveの設定ができておらず、Master-Slave間のデータ同期が出来ません。 - Backup/Restoreで指定できるバックアップ先のストレージはAmazon S3のみ
今回検証で作成したcluster-pv.yaml
にspec. backupVolumeClaimTemplate
を追加することで、Backup/Restoreで利用するためのPersistentVolume, PersistentVolumeClaimは自動生成できます(参照)。しかし、CRDのBackup/Restoreではサポートされていません。