KubernetesでMariaDB+MariaDB Galera Cluster+Maxscaleを起動してみる

**Master Node**

|    EC2　　 |    OS         | Kubernetes | Docker    | ホスト名  |
|:----------:|:-------------:|:----------:|:---------:|:---------:|
| t3.small　| Amazon Linux2 | 1.16.2       |18.06.1-ce |k8s-master|


**Worker Node**

|    EC2　　 |    OS         | Kubernetes | Docker    | ホスト名  |
|:----------:|:-------------:|:----------:|:---------:|:---------:|
| t3.small   | Amazon Linux2 | 1.16.2       |18.06.1-ce |k8s-worker|

```mariadb.yaml
apiVersion: v1
kind: Service
metadata:
  name: mariadb-svc
  labels:
    app: mariadb
spec:
  selector:
    app: mariadb
  clusterIP: None
  ports:
  - name: mariadb
    port: 3306
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mariadb-config
  labels:
    app: mariadb
data:
  start-mariadb-instance.sh: |
    [[ $(hostname) =~ -([0-9]+)$ ]] || exit 1
    server_id=${BASH_REMATCH[1]}
    cp /mnt/config-map/galera.cnf /etc/mysql/conf.d/galera.cnf
    cat /mnt/config-map/users.sql > /docker-entrypoint-initdb.d/init.sql
    if [ "${serverid}" -eq 0 ]; then
      /usr/local/bin/docker-entrypoint.sh mysqld --wsrep-new-cluster --datadir=/var/lib/mysql/$(hostname)
    else
      /usr/local/bin/docker-entrypoint.sh mysqld --datadir=/var/lib/mysql/$(hostname)
    fi

  users.sql: |
    CREATE USER 'maxuser'@'127.0.0.1' IDENTIFIED BY 'maxpwd';
    CREATE USER 'maxuser'@'%' IDENTIFIED BY 'maxpwd';
    GRANT ALL ON *.* TO 'maxuser'@'127.0.0.1' WITH GRANT OPTION;
    GRANT ALL ON *.* TO 'maxuser'@'%' WITH GRANT OPTION;

    SET GLOBAL gtid_strict_mode=ON;

  galera.cnf: |
    [mysqld]
    wsrep_on=ON
    wsrep_cluster_name="galera-cluster"
    wsrep_cluster_address="gcomm://"
    wsrep_provider=/usr/lib/galera/libgalera_smm.so 
    wsrep-provider-options = "gcache.size=256M;gcache.page_size=128M;debug=no"
    wsrep_sst_method=rsync
    binlog_format=ROW
    default-storage-engine=InnoDB 
    innodb-doublewrite=1 
    innodb-autoinc-lock-mode=2 
    innodb-flush-log-at-trx-commit=2 
    bind-address=0.0.0.0
    innodb_page_size=64k
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mariadb
  labels:
    app: mariadb
spec:
  serviceName: mariadb-svc
  selector:
    matchLabels:
      app: mariadb
  replicas: 3
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
      - name: mariadb
        image: mariadb:10.4.8
        command:
        - bash
        - /mnt/config-map/start-mariadb-instance.sh
        env:
        # 本番環境ではパスワードはSecretにすること
        - name: MYSQL_ROOT_PASSWORD
          value: "root"
        ports:
        - containerPort: 3306
          name: mysql
        - containerPort: 4444
          name: sst
        - containerPort: 4567
          name: replication
        - containerPort: 4568
          name: ist
        volumeMounts:
        - name: mariadb-entrypoint-vol
          mountPath: /docker-entrypoint-initdb.d
        - name: mariadb-config-vol
          mountPath: /mnt/config-map
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        livenessProbe:
          exec:
            command:
            - /bin/bash
            - -ec
            - >-
              mysqladmin -h localhost --user=root --password=${MYSQL_ROOT_PASSWORD} ping
          initialDelaySeconds: 5
          periodSeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - /bin/bash
            - -ec
            - >-
              mysql -h localhost --user=root --password=${MYSQL_ROOT_PASSWORD} -e "SELECT 1"
          initialDelaySeconds: 5
          periodSeconds: 30
          timeoutSeconds: 5
      volumes:
      - name: mariadb-entrypoint-vol
        emptyDir: {}
      - name: mariadb-config-vol
        configMap:
          name: mariadb-config
      - name: mariadb-config-folder
        emptyDir: {}
      # データディレクトリは本番環境はemptyDir以外にすること
      - name: data
        hostPath:
          path: /var/lib/galera
          type: DirectoryOrCreate
```

```maxscale.yaml
apiVersion: v1
kind: Service
metadata:
  name: maxscale
  labels:
    app: maxscale
spec:
  ports:
  - name: maxscale-readwrite
    port: 3306
  clusterIP: None
  selector:
    app: maxscale
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: maxscale-config
  labels:
    app: maxscale
data:
  maxscale.cnf: |
    [maxscale]
    threads=auto
    admin_host=0.0.0.0

    [dbserv1]
    type=server
    address=mariadb-0.mariadb-svc.default.svc.cluster.local
    port=3306
    protocol=mariadbbackend

    [dbserv2]
    type=server
    address=mariadb-1.mariadb-svc.default.svc.cluster.local
    port=3306
    protocol=mariadbbackend

    [dbserv3]
    type=server
    address=mariadb-2.mariadb-svc.default.svc.cluster.local
    port=3306
    protocol=mariadbbackend

    [Splitter-Service]
    type=service
    router=readwritesplit
    servers=dbserv1,dbserv2,dbserv3
    user=maxuser
    password=maxpwd

    [Splitter-Listener]
    type=listener
    service=Splitter-Service
    protocol=mariadbclient
    port=3306

    [Galera-Monitor]
    type=monitor
    module=galeramon
    servers=dbserv1,dbserv2,dbserv3
    user=maxuser
    password=maxpwd
    disable_master_failback=true
    available_when_donor=true

  start-maxscale-instance.sh: |
    cp /etc/config-template/maxscale.cnf /etc/config-map/maxscale.cnf
    maxscale -d -U maxscale --configdir=/etc/config-map -lstdout
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: maxscale
  labels:
    app: maxscale
spec:
  serviceName: maxscale
  selector:
    matchLabels:
      app: maxscale
  replicas: 1
  template:
    metadata:
      labels:
        app: maxscale
    spec:
      containers:
      - name: maxscale
        image: mariadb/maxscale:2.4.2-0
        command:
        - bash
        - /etc/config-template/start-maxscale-instance.sh 
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mariadb-config-vol
          mountPath: /etc/config-map
        - name: mariadb-config-template-vol
          mountPath: /etc/config-template
      restartPolicy: Always
      volumes:
      - name: mariadb-config-vol
        emptyDir: {}
      - name: mariadb-config-template-vol
        configMap:
          name: maxscale-config
```

```
kubectl apply -f mariadb.yaml

kubectl get pod

NAME                     READY   STATUS    RESTARTS   AGE
mariadb-0   1/1     Running   0          116s
mariadb-1   1/1     Running   0          92s
mariadb-2   1/1     Running   0          56s

kubectl apply -f maxscale.yaml
```

Maxscale

```
kubectl exec -it maxscale-0  --container=maxscale -- maxctrl list servers
┌─────────┬─────────────────────────────────────────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address                                         │ Port │ Connections │ State                   │ GTID │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv1 │ mariadb-0.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Master, Synced, Running │      │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv2 │ mariadb-1.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Slave, Synced, Running  │      │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv3 │ mariadb-2.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Slave, Synced, Running  │      │
└─────────┴─────────────────────────────────────────────────┴──────┴─────────────┴─────────────────────────┴──────┘

kubectl delete pod mariadb-0
kubectl exec -it maxscale-0  --container=maxscale -- maxctrl list servers
┌─────────┬─────────────────────────────────────────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address                                         │ Port │ Connections │ State                   │ GTID │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv1 │ mariadb-0.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Slave, Synced, Running  │      │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv2 │ mariadb-1.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Master, Synced, Running │      │
├─────────┼─────────────────────────────────────────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ dbserv3 │ mariadb-2.mariadb-svc.default.svc.cluster.local │ 3306 │ 0           │ Slave, Synced, Running  │      │
└─────────┴─────────────────────────────────────────────────┴──────┴─────────────┴─────────────────────────┴──────┘
```

## 動作確認

Maxscaleのイメージのバージョンを2.4.2より大きくして
動作確認したところ、Stateのところが1台だけ
「Master, Synced, Running」で、後の2つは
「Running」になった。原因調査中(2020/02/20追記)