0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VMware SQL with MySQL for Kubernetesのインストール方法やバックアップ方法を確認する

Last updated at Posted at 2023-06-01

VMware SQL with MySQL for Kubernetesは以前はTanzu SQLとして展開されていたもので、Kubernetesクラスタ上にMySQLインスタンスを管理するOperatorを展開してくれるものだ。このOperatorがある状態でカスタムリソースであるMySQLの定義(Manifest)をクラスタ上でapplyすると、簡単にDBが構築できる。すなわち、DDB as a Serviceのような感じで簡単にDBを用意することが出来る。

コンポーネントとしては以下が含まれる。

  • Percona Server 8.0
  • Percona XtraBackup 8.0

Percona ServerはMySQLを拡張させたオープンソースのDBで、こちらで開発が行われている。
無料で完全な互換性があり、パフォーマンス、拡張性、可視性で優れているとのこと。
Percona XtraBackupもオープンソースのバックアップユーティリティで、こちらで開発が行われている。
バックアップ中にロックをせず、DBのパフォーマンスを落とさずにシームレスにバックアップできるとのこと。

今回はVMware SQL with MySQL for Kubernetesの構築からこのバックアップを使うところまでやってみる。
なお、バージョンは1.7.1を利用し、TKG2.2.0上で構築するものとする。

前提条件

こちらによると、以下の条件を揃えておく必要がある。

  • kubectlとkubernetesクラスタが利用可能(バージョン指定なし)
  • kubectlをcluster-admin権限で利用可能
  • Kubernetesクラスタ内にcert-managerが構築済み
  • Helm CLIが利用可能 (v3.8.0以降)
  • registry.tanzu.vmware.comにアクセスするためのユーザ名とパスワードを用意
  • Docker daemonが起動している

registry.tanzu.vmware.comにアクセスするアカウント情報はTanzu Networkにアクセスするものと同一になる。
また、バックアップを利用する場合はS3互換ストレージが必要となる。
ここではMinIOを利用する。MinIOの構築手順は過去の記事で書いているためここでは割愛する。

インストール

こちらの手順に従い進めていく。

最初にTanzu Networkのユーザ名とパスワードを設定しておく。

export TANZUNET_USERNAME=xxx@hoge.info
export TANZUNET_PASSWORD=xxxx

レジストリにログインして、Helm Chartを取得する。公式手順だとHelm Chartを/tmpに展開していたが、残しておきたいのでカレントディレクトリに変更している。

echo $TANZUNET_PASSWORD | helm registry login registry.tanzu.vmware.com -u $TANZUNET_USERNAME --password-stdin
helm pull oci://registry.tanzu.vmware.com/tanzu-mysql-for-kubernetes/vmware-sql-with-mysql-operator --version 1.7.1 --untar --untardir ./

Namespaceを作成し、MySQLインスタンスを作る際にイメージをpullするための認証情報を格納したSecretを作成する。

kubectl create namespace vmware-mysql-for-kubernetes-system
kubectl create secret docker-registry tanzu-image-registry \
    --docker-server=https://registry.tanzu.vmware.com/ \
    --docker-username="${TANZUNET_USERNAME}" \
    --docker-password="${TANZUNET_PASSWORD}" \
    --namespace=vmware-mysql-for-kubernetes-system

必要に応じてvmware-sql-with-mysql-operator/values.yamlを編集する。
編集可能な項目とその説明はこちらの中にある表を参照。
今回はデフォルト値を利用するため、特に編集していない。
最後にインストールする。

helm install --wait my-mysql-operator ./vmware-sql-with-mysql-operator/ \
  --namespace=vmware-mysql-for-kubernetes-system \
  --create-namespace

※追記:values.yamlを編集しない場合はhelm pullを飛ばして以下でもOK。

helm install --wait my-mysql-operator oci://registry.tanzu.vmware.com/tanzu-mysql-for-kubernetes/vmware-sql-with-mysql-operator \
  --namespace=vmware-mysql-for-kubernetes-system \
  --create-namespace

インストールに無事成功すれば、以下のような感じで各種リソースが取得できる。

$ kubectl get all --namespace=vmware-mysql-for-kubernetes-system
NAME                                     READY   STATUS    RESTARTS   AGE
pod/my-mysql-operator-5898d897f6-5854t   1/1     Running   0          92s

NAME                                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/vmware-mysql-webhook-service   ClusterIP   100.66.6.61   <none>        443/TCP   92s

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-mysql-operator   1/1     1            1           92s

NAME                                           DESIRED   CURRENT   READY   AGE
replicaset.apps/my-mysql-operator-5898d897f6   1         1         1       92s

インストールされるカスタムリソースと動作確認

VMware SQL with MySQLでは以下のカスタムリソースがインストールされる。

  • kind: MySQL:MySQLインスタンス本体
  • kind: MySQLVersion:利用可能なDBのバージョンの管理
  • kind: MySQLBackup:バックアップのリクエスト
  • kind: MySQLBackupLocation:バックアップに使うS3のバケットを定義
  • kind: MySQLBackupSchedule:バックアップのスケジュールの定義
  • kind: MySQLRestore:リストアのリクエスト

ここではメインとなるkind: MySQLの挙動だけ確認しておく。
defaultNamespaceにkind: MySQLオブジェクトを作成してみる。
MySQLインスタンスのイメージはregistry.tanzu.vmware.comにあるため、Pullする際に認証情報が必要となる。
Namespaceごとに認証情報を用意するのが面倒であれば、tanzu secret registry addで全Namespaceから参照できるようにし、Exportするとよい。

tanzu secret registry add tanzu-image-registry-public --server registry.tanzu.vmware.com --username ${TANZUNET_USERNAME} --password ${TANZUNET_PASSWORD} --export-to-all-namespaces --yes --namespace vmware-mysql-for-kubernetes-system

ImportにはSecretImportを使う。TKG2.2.0であれば標準で利用できる。

cat << EOF > ./secret-import.yaml
apiVersion: secretgen.carvel.dev/v1alpha1
kind: SecretImport
metadata:
  name: tanzu-image-registry-public
spec:
  fromNamespace: vmware-mysql-for-kubernetes-system
EOF
kubectl apply -f ./secret-import.yaml -n default

Secretが取り込まれていることがわかる。

$ kubectl get secret tanzu-image-registry-public
NAME                          TYPE                             DATA   AGE
tanzu-image-registry-public   kubernetes.io/dockerconfigjson   1      2m6s

次に作成したSecretを使ってMySQLインスタンスを作成する。
こちらのManifestを流用し、Secret名だけ変更して実行する。

cat << EOF > ./mysql-sample.yaml
apiVersion: with.sql.tanzu.vmware.com/v1
kind: MySQL
metadata:
  name: mysql-sample
spec:
  resources:
    mysql:
      requests:
        memory: 1Gi
  storageSize: 1Gi
  imagePullSecretName: tanzu-image-registry-public
EOF
kubectl apply -f ./mysql-sample.yaml -n default

起動すると、以下のような形でOperatorやDBのバージョンが取得できる。

$ kubectl get mysql
NAME           READY   STATUS    AGE   OPERATOR VERSION   DB VERSION   UPDATE STATUS      USER ACTION
mysql-sample   true    Running   10m   1.7.1              8.0.31       NoUpdateRequired

なお、kubectl treeで確認すると以下のような構造となる。

NAMESPACE  NAME                                                                   READY  REASON  AGE
default    MySQL/mysql-sample                                                     -              112s
default    ├─Certificate/mysql-sample-metrics-tls                                 True   Ready   111s
default    │ └─CertificateRequest/mysql-sample-metrics-tls-9k49n                  True   Issued  111s
default    ├─Certificate/mysql-sample-mysql-tls                                   True   Ready   112s
default    │ └─CertificateRequest/mysql-sample-mysql-tls-w4ngn                    True   Issued  111s
default    ├─ConfigMap/mysql-sample-autotune-config                               -              111s
default    ├─RoleBinding/tanzu-mysql-backup-cron-mysqlbackup-creator-rolebinding  -              112s
default    ├─RoleBinding/tanzu-mysql-sidecar-rolebinding                          -              112s
default    ├─Secret/mysql-sample-app-user-db-secret                               -              111s
default    ├─Secret/mysql-sample-credentials                                      -              111s
default    ├─Secret/mysql-sample-metrics-tls                                      -              110s
default    ├─Secret/mysql-sample-mysql-tls                                        -              110s
default    ├─Service/mysql-sample                                                 -              111s
default    │ └─EndpointSlice/mysql-sample-l48fx                                   -              111s
default    ├─Service/mysql-sample-members                                         -              111s
default    │ └─EndpointSlice/mysql-sample-members-kkvs9                           -              111s
default    ├─ServiceAccount/tanzu-mysql                                           -              112s
default    ├─ServiceAccount/tanzu-mysql-backup-cron                               -              112s
default    └─StatefulSet/mysql-sample                                             -              111s
default      ├─ControllerRevision/mysql-sample-788c8dc948                         -              111s
default      └─Pod/mysql-sample-0                                                 True           111s

証明書、RBAC(RoleBinding, SA))や設定周り(ConfigMap,Secret)、Service, StatefulSetあたりで構成されることが分かる。

この後は使わないので消しておく。なお、削除してもPVC、PVが残るので、完全削除するにはPVCも削除する。

kubectl delete mysql mysql-sample
kubectl delete pvc mysql-data-mysql-sample-0

サンプルアプリの起動

公式ドキュメントのConnectiong Applicationに従ってサンプルアプリを立ち上げてデータを格納する。

サンプルアプリ用DBの構築

公式手順はこちらとなる。

先程動作確認用に作成したManifestにmysqlのVersionを追加したものを用意した。
(利用可能なMySQLのバージョンはkubectl get mysqlversionsで取得可能。)

cat << EOF > ./mysql-sample.yaml
apiVersion: with.sql.tanzu.vmware.com/v1
kind: MySQL
metadata:
  name: mysql-for-wordpress
spec:
  mysqlVersion:
    name: mysql-8.0.29
  resources:
    mysql:
      requests:
        memory: 1Gi
  storageSize: 1Gi
  imagePullSecretName: tanzu-image-registry-public
EOF
kubectl apply -f ./mysql-sample.yaml -n default

起動したことを確認する。

$ kubectl get mysql
NAME                  READY   STATUS    AGE     OPERATOR VERSION   DB VERSION   UPDATE STATUS      USER ACTION
mysql-for-wordpress   true    Running   4m54s   1.7.1              8.0.29       NoUpdateRequired

ここからは、こちらの記述に従いサンプルアプリ用にDBの中をいじっていく。
MySQLのコンテナ内に入る。

kubectl exec -it mysql-for-wordpress-0 -c mysql -- bash

MySQLに接続する。環境変数やパスワードのファイルはPod内に持っているので特に設定等する必要はない。

mysql -p$(cat $MYSQL_ROOT_PASSWORD_FILE) -u root

以下実行し、bitnami_wordpressDBとユーザbn_wordpressを作成する。

CREATE DATABASE bitnami_wordpress;
CREATE USER 'bn_wordpress'@'%' IDENTIFIED BY 'hunter2';
GRANT ALL PRIVILEGES ON bitnami_wordpress.* TO 'bn_wordpress'@'%';
FLUSH PRIVILEGES;
exit;

Podを抜けた後、cert-managerを使って証明書を発行する。

cat << EOF | kubectl apply -f -
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: selfsigned-issuer
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ca-certificate
spec:
  isCA: true
  issuerRef:
    name: selfsigned-issuer
  secretName: ca-secret
  commonName: ca-cert
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: tls-issuer
spec:
  ca:
    secretName: ca-secret
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: tls-certificate
spec:
  isCA: false
  dnsNames:
    - mysql-sample.default # See note after the code excerpt
  secretName: mysql-tls-secret
  issuerRef:
    name: tls-issuer
EOF

既存のMySQLインスタンスにTLSの設定を追加する。

kubectl patch mysql mysql-for-wordpress --type merge -p '{"spec":{"tls":{"secret":{"name":"mysql-tls-secret"}}}}'

追加後、ログを確認するとTLSサポートが確認できる。

$ kubectl logs pod/mysql-for-wordpress-0 -c mysql | grep TLS
2023-06-01T01:40:12.245902Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2023-06-01T01:40:12.325310Z 0 [Warning] [MY-000067] [Server] unknown variable 'loose-group-replication-recovery-tls-version=TLSv1.2,TLSv1.3'.

サンプルアプリの用意

bitnami版WordPressを利用するため、最初にbitnamiリポジトリを追加する。

helm repo add  bitnami https://charts.bitnami.com/bitnami

WordPressのvalues.yaml公式手順に用意されているので、これをコピーして一部修正してデプロイする。

cat << EOF > bitnami-wordpress-values.yaml
mariadb:
  enabled: false

externalDatabase:
  host: mysql-for-wordpress.default.svc.cluster.local
  user: bn_wordpress
  password: hunter2
  database: bitnami_wordpress

extraEnvVars:
- name: "WORDPRESS_DATABASE_SSL_CA_FILE"
  value: "/etc/mysql/tls/ca.crt"
- name: "WORDPRESS_ENABLE_DATABASE_SSL"
  value: "yes"
- name: "BITNAMI_DEBUG"
  value: "true"

extraVolumes:
- name: mysql-ca
  secret:
    secretName: "mysql-tls-secret"
    items:
    - key: ca.crt
      path: ca.crt

extraVolumeMounts:
  - name: mysql-ca
    mountPath: /etc/mysql/tls/
EOF
helm install wp bitnami/wordpress -f ./bitnami-wordpress-values.yaml

なお、extraEnvVarsWORDPRESS_ENABLE_DATABASE_SSLをセットしないと動かない。同僚に聞いたところ、WordPress側で同パラメタが設定されていないとMySQLとの接続を有効化してくれないとのこと。
実際、このパラメタなしで実行するとPodが停止するため、必ず付与してデプロイする。

起動後、デフォルトではWordPressはtype:LoadBalancerで公開しているので、公開先IPにアクセスする。
1685584765362.png

Hello world!をクリックするとコメントを残すことが出来るので、適当に入力してPost Commentをクリックする。
1685585378791.png

また、<IP address>/adminにアクセスすると管理画面にアクセスできる。

  • ユーザ名:user
  • パスワード:kubectl get secret --namespace default wp-wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d

でログインすることが出来る。
左サイドバーのPostsからHello world!をEditし、タイトルを修正して右上のUpdateで保存する。
1685585635943.png
変更後の画面は以下のようになっている。

1685585759564.png

これをバックアップ・リストアして復元できることを確認する。

サンプルアプリのバックアップ・リストア

先ほど作成したサンプルアプリをバックアップする。バックアップにはS3互換ストレージが必要になる。
ここではMinIOを利用する。

バックアップ

最初にバックアップの格納先リソース(kind: MySQLBackupLocation)を作成する。
以下のbucketendpointaccessKeyIdsecretAccessKeyは自環境のものにあわせて修正する。また、forcePathStyle: trueがないとendpointのドメインの先頭にバケット名を含めてアクセスしに行くため、MinIOを使う場合は必須となる。

cat << 'EOF' > ./backup-location.yaml
apiVersion: with.sql.tanzu.vmware.com/v1
kind: MySQLBackupLocation
metadata:
  name: mysql-location
spec:
  storage:
    s3:
      bucket: "mysql-bucket"
      endpoint: "http://10.222.147.222:9000"
      forcePathStyle: true
      secret:
        name: minio-creds
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-creds
stringData:
  accessKeyId: "minio"
  secretAccessKey: "minio123"
EOF
kubectl apply -f ./backup-location.yaml

次にバックアップの要求を行うkind: MySQLBackupリソースを作成する。
location.nameは先程作成したMySQLBackupLocationオブジェクトの名前を、instance.nameは起動しているMySQLオブジェクトの名前を指定する。

cat << EOF > ./backup.yaml
apiVersion: with.sql.tanzu.vmware.com/v1
kind: MySQLBackup
metadata:
  name: backup-wp
spec:
  location:
    name: mysql-location
  instance:
    name: mysql-for-wordpress
EOF
kubectl apply -f ./backup.yaml

MySQLBackupLocationに問題がなければ、バックアップが実行(Running)される。

$ kubectl get mysqlbackup
NAME        STATUS    SOURCE INSTANCE       TIME STARTED           TIME COMPLETED
backup-wp   Running   mysql-for-wordpress   2023-06-01T02:46:14Z

成功するとSucceededに変わる。

$ kubectl get mysqlbackup
NAME        STATUS      SOURCE INSTANCE       TIME STARTED           TIME COMPLETED
backup-wp   Succeeded   mysql-for-wordpress   2023-06-01T02:46:14Z   2023-06-01T02:46:23Z

MinIO内にもファイルが作成されている。
1685587806956.png

リストア

問題なくMySQLインスタンスが作成されるか確認する。
一旦WordPressとMySQLインスタンスを削除する。

helm delete wp
kubectl delete mysql mysql-for-wordpress
kubectl delete pvc mysql-data-mysql-for-wordpress-0

ここからMySQLRestoreリソースを使って復元する。以下のManifestをapplyする。
なお、backup.nameに作成したMySQLBackupオブジェクトの名前を、instanceTemplate.metadata.nameMySQLインスタンス名(バックアップと一致しなくてOK)を指定する。またimagePullSecretNameはPullが可能なSecretを指定する。

cat << EOF > ./restore.yaml
apiVersion: with.sql.tanzu.vmware.com/v1
kind: MySQLRestore
metadata:
  name: restore-wp
spec:
  backup:
    name: backup-wp
  instanceTemplate:
    metadata:
      name: mysql-for-wordpress-restored
    spec:
      storageSize: 1Gi
      imagePullSecretName: tanzu-image-registry-public
EOF
kubectl apply -f ./restore.yaml

こちらもMySQLBackupLocationに問題がなければ、リストアが実行(Running)され、完了するとSucceededになる。

$ kubectl get mysqlrestore
NAME         STATUS      SOURCE BACKUP   TARGET INSTANCE                TIME STARTED           TIME COMPLETED
restore-wp   Succeeded   backup-wp       mysql-for-wordpress-restored   2023-06-01T02:55:07Z   2023-06-01T02:57:28Z

この状態でWordPressを立ち上げる。
MySQLインスタンス名を変更したため、values.yamlのDB参照パスを以下のように変更する。

externalDatabase:
  host: mysql-for-wordpress-restored.default.svc.cluster.local

変更が終わったら、helm installで立ち上げる。

helm install wp bitnami/wordpress -f ./bitnami-wordpress-values.yaml

バックアップ前に変更した内容が確認できた。
1685588592950.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?