LoginSignup
7
6

More than 1 year has passed since last update.

Oracle MySQL Operator for Kubernetes & WordPress

Last updated at Posted at 2021-12-18

OSSとして公開されているOracle MySQL Operator for Kubernetesを利用して、Kubernetesクラスタ上にWordPressとMySQL InnoDBクラスタ環境を構築する過程を辿りたいと思います。

Oracle MySQL Operator for Kubernetes

Oracle MySQL Operator for Kubernetesは、MySQLの高可用構成を実現するInnoDBクラスタをKubernetes上に構築、管理を容易化するオペレーターです。

OracleがOSSとして開発、ソースコードはGitHubで公開されています。

MySQL Operator for Kubernetes

OPERATOR CAPABILITY LEVELSのLevel3です。(2021年12月)
image.png

2021年12月時点での、主な機能は以下となります。

  • MySQL Server/Routerの自動デプロイと管理
  • セルフヒーリング
  • バックアップ
  • MySQL Server/Routerのスケールアウト/イン
  • ローリングアップデート

image.png

MySQL InnoDB Cluster

MySQL InnoDB Clusterは、グループレプリケーション、MySQL Router、MySQL Shell の3つの技術要素を組み合わせて実現するMySQLサーバの高可用性構成です。

image.png

MySQL InnoDB Clusterには、シングルプライマリ型とマルチプライマリ型があります。Oracle MySQL Operator for Kubernetesでは、シングルプライマリのみ対応しています。(2021年12月)

image.png
シングルプライマリ型での高可用性は、以下のように機能します。

image.png

WordPress + Oracle MySQL Operator (Scale Out/In) on Kubernetes

実際に、Kubernetesクラスタ上に、WordPressとOracle MySQL Operatorの環境を構築して、InnoDBクラスタやWordPressのスケールイン・アウトを実行してみたいと思います。

環境としては、3ノードの1Kubernetesクラスタ上に、WordPressとOracle MySQL Operatorを構築します。

image.png

環境構築の流れ

  • Installation of the MySQL Operator
  • Using the MySQL Operator to setup a MySQL InnoDB Cluster
  • Connecting to the MYSQL InnoDB Cluster
  • Installation of WordPress
  • Connect to MySQL
  • MySQL Scale Out/In
  • WordPress Scale

環境

Public Cloud: Oracle Cloud Infrastructure
Kubernetes : Oracle Container Engine for Kubernetes (OKE)

  • Cluster:1
  • Node:3
  • Shape:VM.Standard.E3.Flex
  • OCPU:1 x 3
  • MEM:16Gi x 3

Installation of the MySQL Operator

Namespace mysql-operator を作成します。

kubectl create ns mysql-operator

コマンド結果

namespace/mysql-operator created

MySQL Operator をインストールします。

kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-crds.yaml

コマンド結果

customresourcedefinition.apiextensions.k8s.io/innodbclusters.mysql.oracle.com created
customresourcedefinition.apiextensions.k8s.io/mysqlbackups.mysql.oracle.com created
customresourcedefinition.apiextensions.k8s.io/clusterkopfpeerings.zalando.org created
customresourcedefinition.apiextensions.k8s.io/kopfpeerings.zalando.org created
kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-operator/trunk/deploy/deploy-operator.yaml

コマンド結果

serviceaccount/mysql-sidecar-sa created
clusterrole.rbac.authorization.k8s.io/mysql-operator created
clusterrole.rbac.authorization.k8s.io/mysql-sidecar created
clusterrolebinding.rbac.authorization.k8s.io/mysql-operator-rolebinding created
clusterkopfpeering.zalando.org/mysql-operator created
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
namespace/mysql-operator configured
serviceaccount/mysql-operator-sa created
deployment.apps/mysql-operator created

Namespace mysql-operator に MySQL Operator がインストールされたことを確認します。

kubectl get deployment -n mysql-operator mysql-operator

コマンド結果

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mysql-operator   1/1     1            1           30s

Using the MySQL Operator to setup a MySQL InnoDB Cluster

InnoDBクラスタを作成する上で必要となる、MySQLのrootユーザ情報(パスワード)をSecretに登録します。

kubectl create secret generic  mypwds --from-literal=rootPassword="mysqlp@ssword"

コマンド結果

secret/mypwds created

サンプルクラスタのマニフェストを作成します。このサンプルクラスタは、​​3つのMySQLサーバーインスタンスと1つのMySQLルーターインスタンスを持つInnoDBクラスタです。

vim sample-cluster.yaml
apiVersion: mysql.oracle.com/v2alpha1
kind: InnoDBCluster
metadata:
  name: mycluster
spec:
  secretName: mypwds
  instances: 3
  version: "8.0.25"
  router:
    instances: 1
    version: "8.0.25"

マニフェストを適用します。

kubectl apply -f sample-cluster.yaml

コマンド結果

innodbcluster.mysql.oracle.com/mycluster created

InnoDBクラスタの状況を確認します。

kubectl get innodbcluster --watch
NAME          STATUS    ONLINE   INSTANCES   ROUTERS   AGE
・
・
・
mycluster   ONLINE           3        3           1         7m7s

Connecting to the MYSQL InnoDB Cluster

InnoDBクラスタに接続する、KubernetesクラスタのServiceを確認します。後のWordPressと連携する際に必要となります。

kubectl get service mycluster

コマンド結果

NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                               AGE
mycluster   ClusterIP   10.96.201.29   <none>        6446/TCP,6448/TCP,6447/TCP,6449/TCP   8m13s

エクスポートされたポートは、MySQLプロトコルおよびXプロトコルの読み取り/書き込み、読み取り専用ポートです。

kubectl describe service mycluster

コマンド結果

Name:              mycluster
Namespace:         default
Labels:            mysql.oracle.com/cluster=mycluster
                   tier=mysql
Annotations:       <none>
Selector:          component=mysqlrouter,mysql.oracle.com/cluster=mycluster,tier=mysql
Type:              ClusterIP
IP Families:       <none>
IP:                10.43.203.248
IPs:               <none>
Port:              mysql  6446/TCP
TargetPort:        6446/TCP
Endpoints:         <none>
Port:              mysqlx  6448/TCP
TargetPort:        6448/TCP
Endpoints:         <none>
Port:              mysql-ro  6447/TCP
TargetPort:        6447/TCP
Endpoints:         <none>
Port:              mysqlx-ro  6449/TCP
TargetPort:        6449/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

Installation of WordPress

WordPress環境を構築します。

NFS Server

NFSサーバを構築します。最初にPersistentVolumeClaimを作成します。

vim nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  storageClassName: "oci-bv"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi

マニフェストを適用します。

kubectl apply -f nfs-pvc.yaml

コマンド結果

persistentvolumeclaim/nfs-pvc created

NFSサーバを作成します。

vim nfs-server.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-server
spec:
  replicas: 1
  selector:
    matchLabels:
      role: nfs-server
  template:
    metadata:
      labels:
        role: nfs-server
    spec:
      containers:
      - name: nfs-server
        image: gcr.io/google_containers/volume-nfs:0.8
        ports:
          - name: nfs
            containerPort: 2049
          - name: mountd
            containerPort: 20048
          - name: rpcbind
            containerPort: 111
        securityContext:
          privileged: true
        volumeMounts:
          - mountPath: /exports
            name: nfs-local-storage
      volumes:
        - name: nfs-local-storage
          persistentVolumeClaim:
            claimName: nfs-pvc

マニフェストを適用します。

kubectl apply -f nfs-server.yaml

コマンド結果

deployment.apps/nfs-server created

WordPressのPersistentVolumeから指定するNFSのServiceを作成します。

vim nfs-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nfs-service
spec:
  ports:
    - name: nfs
      port: 2049
    - name: mountd
      port: 20048
    - name: rpcbind
      port: 111
  selector:
    role: nfs-server

マニフェストを適用します。

kubectl apply -f nfs-service.yaml

コマンド結果

service/nfs-service created

WordPressのPersistentVolumeから指定するNFSのServiceのClusterIPを確認します。

kubectl get services

コマンド結果

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP                               16m
mycluster             ClusterIP   10.96.198.46    <none>        6446/TCP,6448/TCP,6447/TCP,6449/TCP   9m33s
mycluster-instances   ClusterIP   None            <none>        3306/TCP,33060/TCP,33061/TCP          9m33s
nfs-service           ClusterIP   10.96.189.130   <none>        2049/TCP,20048/TCP,111/TCP            14s

WordPress

WordPressのPersistentVolumeを作成します。

vim wordpress-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: wordpress-pv
  labels:
    type: local
spec:
  persistentVolumeReclaimPolicy: Delete
  storageClassName: wordpress
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: xx.xx.xx.xx #「nfs-service」のCLUSTER-IPを定義
    path: /

マニフェストを適用します。

kubectl apply -f wordpress-pv.yaml

コマンド結果

persistentvolume/wordpress-pv created

WordPressのPersistentVolumeClaimを作成します。

vim wordpress-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress-pvc
  labels:
    app: wordpress
    tier: wordpress
spec:
  storageClassName: wordpress
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

マニフェストを適用します。

kubectl apply -f wordpress-pvc.yaml

コマンド結果

persistentvolumeclaim/wordpress-pvc created

WordPressのPersistentVolumeとPersistentVolumeClaimが連携していることを確認します。

kubectl get persistentvolumes,persistentvolumeclaims

コマンド結果

NAME                                                                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS   REASON   AGE
persistentvolume/csi-343c6a85-ceac-41ad-9ec3-5a9c66c16be2                                                   50Gi       RWO            Delete           Bound    default/nfs-pvc               oci-bv                  116s
persistentvolume/ocid1.volume.oc1.ap-osaka-1.abvwsljr4ub2x5hdai6hrobi2c742b7cogbzttaln2cv7tvvn6efcd4zukga   50Gi       RWO            Delete           Bound    default/datadir-mycluster-2   oci                     6m
persistentvolume/ocid1.volume.oc1.ap-osaka-1.abvwsljr7zgyejcsd3gg5vbzlzgpr72nkxn2x4qtwax5lj4tskpsnnstnm2q   50Gi       RWO            Delete           Bound    default/datadir-mycluster-0   oci                     10m
persistentvolume/ocid1.volume.oc1.ap-osaka-1.abvwsljreozgjd5kz4zei24w47nee4raeef33e7o56auoqilcificgvugtqq   50Gi       RWO            Delete           Bound    default/datadir-mycluster-1   oci                     8m19s
persistentvolume/wordpress-pv                                                                               50Gi       RWX            Delete           Bound    default/wordpress-pvc         wordpress               26s

NAME                                        STATUS   VOLUME                                                                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/datadir-mycluster-0   Bound    ocid1.volume.oc1.ap-osaka-1.abvwsljr7zgyejcsd3gg5vbzlzgpr72nkxn2x4qtwax5lj4tskpsnnstnm2q   50Gi       RWO            oci            10m
persistentvolumeclaim/datadir-mycluster-1   Bound    ocid1.volume.oc1.ap-osaka-1.abvwsljreozgjd5kz4zei24w47nee4raeef33e7o56auoqilcificgvugtqq   50Gi       RWO            oci            8m30s
persistentvolumeclaim/datadir-mycluster-2   Bound    ocid1.volume.oc1.ap-osaka-1.abvwsljr4ub2x5hdai6hrobi2c742b7cogbzttaln2cv7tvvn6efcd4zukga   50Gi       RWO            oci            6m11s
persistentvolumeclaim/nfs-pvc               Bound    csi-343c6a85-ceac-41ad-9ec3-5a9c66c16be2                                                   50Gi       RWO            oci-bv         2m30s
persistentvolumeclaim/wordpress-pvc         Bound    wordpress-pv                                                                               50Gi       RWX            wordpress      12s

WordPressのマニフェストを作成します。

vim wordpress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
        - image: wordpress:5.6.2
          name: wordpress
          env:
          #Service名「mycluster:6446」を定義
          - name: WORDPRESS_DB_HOST
            value: mycluster:6446
          #MySQLのデータベースパスワードを参照する定義
          - name: WORDPRESS_DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mypwds
                key: rootPassword
          ports:
            - containerPort: 80
              name: wordpress
          #Podのマウントパス定義
          volumeMounts:
            - name: wordpress-local-storage
              mountPath: /var/www/html
      #「wordpress-pvc」を指定する定義
      volumes:
        - name: wordpress-local-storage
          persistentVolumeClaim:
            claimName: wordpress-pvc

マニフェストを適用します。

kubectl apply -f wordpress.yaml

コマンド結果

deployment.apps/wordpress created

WordPressのPodがRunnninngであることを確認します。

kubectl get pods

コマンド結果

NAME                          READY   STATUS    RESTARTS   AGE
mycluster-0                   2/2     Running   0          13m
mycluster-1                   2/2     Running   0          11m
mycluster-2                   2/2     Running   0          8m45s
mycluster-router-gwvpr        1/1     Running   0          11m
nfs-server-788c45b6f5-chp4k   1/1     Running   0          4m47s
wordpress-598746d47b-wfffq    1/1     Running   0          31s

WordPress Serviceのマニフェストを作成します。

vim wordpress-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
  labels:
    app: wordpress
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: wordpress

マニフェストを適用します。

kubectl apply -f wordpress-service.yaml

コマンド結果

service/wordpress-service created

EXTERNAL-IPが表示されます。実際にブラウザでアクセスすると、WordPressのセットアップ画面が表示されます。

kubectl get services

コマンド結果

NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
kubernetes            ClusterIP      10.96.0.1       <none>        443/TCP                               21m
mycluster             ClusterIP      10.96.198.46    <none>        6446/TCP,6448/TCP,6447/TCP,6449/TCP   14m
mycluster-instances   ClusterIP      None            <none>        3306/TCP,33060/TCP,33061/TCP          14m
nfs-service           ClusterIP      10.96.189.130   <none>        2049/TCP,20048/TCP,111/TCP            5m11s
wordpress-service     LoadBalancer   10.96.93.51     140.xx.xx.xx  80:32606/TCP                          31s

Connect to MySQL

1.MySQL Operator Pod に接続してMySQL Shellを実行する場合

MySQL Operator Pod からMySQL Shellを利用して mycluster-0 に接続します。

パスワードが要求されるので、MySQLのSecretに設定したパスワード( mysqlp@ssword )を入力します。

接続後、抜ける場合は、「\q」を実行します。

kubectl exec -it -n mysql-operator mysql-operator-xxxxxxxxxx-xxxxx -- mysqlsh root@mycluster-0.mycluster-instances.default.svc.cluster.local
Cannot set LC_ALL to locale en_US.UTF-8: No such file or directory
Please provide the password for 'root@mycluster-0.mycluster-instances.default.svc.cluster.local': *************
MySQL Shell 8.0.26

Copyright (c) 2016, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a session to 'root@mycluster-0.mycluster-instances.default.svc.cluster.local'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 2115 (X protocol)
Server version: 8.0.25 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
 MySQL  mycluster-0.mycluster-instances.default.svc.cluster.local:33060+ ssl  JS > \q
Bye!

2. mycluster-0 に接続する場合

パスワードが要求されるので、MySQLのSecretに設定したパスワード( mysqlp@ssword )を入力します。

接続後、抜ける場合は、「\q」を実行します。

kubectl exec -it mycluster-0 -- mysqlsh --mysql localroot@localhost
Defaulting container name to sidecar.
Use 'kubectl describe pod/mycluster-0 -n default' to see all of the containers in this pod.
Cannot set LC_ALL to locale en_US.UTF-8: No such file or directory
Please provide the password for 'localroot@localhost': *************
MySQL Shell 8.0.26

Copyright (c) 2016, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type '\help' or '\?' for help; '\quit' to exit.
Creating a Classic session to 'localroot@localhost'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 2262
Server version: 8.0.25 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
 MySQL  localhost  JS > \q
Bye!

MySQL Scale Out/In

Scale Out

sample-cluster.yaml のinstancesを以下に変更

instances: 3 ⇒ 5
instances: 1 ⇒ 2

vim sample-cluster.yaml
apiVersion: mysql.oracle.com/v2alpha1
kind: InnoDBCluster
metadata:
  name: mycluster
spec:
  secretName: mypwds
  instances: 5
  version: "8.0.25"
  router:
    instances: 2
    version: "8.0.25"
kubectl apply -f sample-cluster.yaml

コマンド結果

innodbcluster.mysql.oracle.com/mycluster configured

InnoDBクラスタの状況を確認します。

kubectl get innodbcluster --watch
NAME        STATUS   ONLINE   INSTANCES   ROUTERS   AGE
・
・
・
mycluster   ONLINE           5        5           2         55m

Podも確認するとmyclusterが5、mycluster-routerが2となっていることを確認できます。

kubectl get pods

コマンド結果

NAME                          READY   STATUS    RESTARTS   AGE
mycluster-0                   2/2     Running   0          25m
mycluster-1                   2/2     Running   0          22m
mycluster-2                   2/2     Running   0          20m
mycluster-3                   2/2     Running   0          4m51s
mycluster-4                   2/2     Running   0          2m41s
mycluster-router-6j2t2        1/1     Running   0          4m51s
mycluster-router-gwvpr        1/1     Running   0          22m
nfs-server-788c45b6f5-chp4k   1/1     Running   0          16m
wordpress-598746d47b-wfffq    1/1     Running   0          12m

OCIコンソールで、Block Volumeが追加されていることも確認できます。

WordPressで使用しているNFSのものを含めて、6 Block Volumeとなります。

image.png

Scale In

sample-cluster.yaml のinstancesを以下に変更

instances: 3
instances: 1

vim sample-cluster.yaml
apiVersion: mysql.oracle.com/v2alpha1
kind: InnoDBCluster
metadata:
  name: mycluster
spec:
  secretName: mypwds
  instances: 3
  version: "8.0.25"
  router:
    instances: 1
    version: "8.0.25"
kubectl apply -f sample-cluster.yaml

コマンド結果

innodbcluster.mysql.oracle.com/mycluster configured
kubectl get innodbcluster --watch
NAME        STATUS   ONLINE   INSTANCES   ROUTERS   AGE
・
・
・
mycluster   ONLINE   3        3           1         60m
kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
mycluster-0                   2/2     Running   0          28m
mycluster-1                   2/2     Running   0          25m
mycluster-2                   2/2     Running   0          23m
mycluster-router-gwvpr        1/1     Running   0          25m
nfs-server-788c45b6f5-chp4k   1/1     Running   0          19m
wordpress-598746d47b-wfffq    1/1     Running   0          14m

現時点(2021年12月)では、myclusterとmycluster-routerのPodは、指定した数に自動で戻りますが、PVC、PV、Block Volumeは自動で削除されないので、手動でPVCを削除します。(同時にPV、Block Volumeも削除されます。ReclaimPolicyでDeleteを指定しているため。)

kubectl delete pvc datadir-mycluster-4

コマンド結果

persistentvolumeclaim "datadir-mycluster-4" deleted
kubectl delete pvc datadir-mycluster-3

コマンド結果

persistentvolumeclaim "datadir-mycluster-3" deleted

OCIコンソールで、Block Volumeが終了されていることも確認できます。

image.png

WordPress Scale

WordPressのPod数を10に変更してスケールします。

kubectl scale deployment wordpress --replicas 10

コマンド結果

deployment.apps/wordpress scaled
kubectl get pods

コマンド結果

NAME                          READY   STATUS    RESTARTS   AGE
mycluster-0                   2/2     Running   0          31m
mycluster-1                   2/2     Running   0          28m
mycluster-2                   2/2     Running   0          26m
mycluster-router-gwvpr        1/1     Running   0          28m
nfs-server-788c45b6f5-chp4k   1/1     Running   0          22m
wordpress-598746d47b-2r776    1/1     Running   0          37s
wordpress-598746d47b-4rx94    1/1     Running   0          37s
wordpress-598746d47b-626x7    1/1     Running   0          37s
wordpress-598746d47b-bv2c2    1/1     Running   0          37s
wordpress-598746d47b-jd9sh    1/1     Running   0          37s
wordpress-598746d47b-l7t4d    1/1     Running   0          37s
wordpress-598746d47b-lhsws    1/1     Running   0          37s
wordpress-598746d47b-qht84    1/1     Running   0          37s
wordpress-598746d47b-vdf8s    1/1     Running   0          37s
wordpress-598746d47b-wfffq    1/1     Running   0          18m

実際にWordPressにアクセスして、初期セットアップして問題ないことを確認します。「wordpress-service」の「EXTERNAL-IP」を確認して、ブラウザでアクセスします。

kubectl get services

コマンド結果

NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                               AGE
kubernetes            ClusterIP      10.96.0.1       <none>          443/TCP                               64m
mycluster             ClusterIP      10.96.159.155   <none>          6446/TCP,6448/TCP,6447/TCP,6449/TCP   48m
mycluster-instances   ClusterIP      None            <none>          3306/TCP,33060/TCP,33061/TCP          48m
nfs-service           ClusterIP      10.96.49.232    <none>          2049/TCP,20048/TCP,111/TCP            39m
wordpress-service     LoadBalancer   10.96.79.114    152.xxx.xxx.xxx 80:30769/TCP                          26m

image.png
以上となります。

次回は、疑似障害を起こした場合のInnoDBクラスタの挙動について試してみたいと思います。

7
6
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
7
6