この記事は
の続きで、
構築したkubernetesクラスタにとりあえずmysqlを構築した際のメモです。
やりたいこと
- Oracle Cloud無料枠に構築したkubernetesクラスタでmysqlを使えるようにする
- workerで動作させる
- podが作り直されてもデータが消えないよう永続化もする
永続化用の設定
こんな感じでPersistentVolumeとPersistentVolumeClaimの設定を書いて反映させる。
20GB確保、/data/mysql
に永続化。
mysql-storage.yml
apiVersion: v1 kind: PersistentVolume metadata: name: db-pv labels: type: local spec: storageClassName: manual capacity: storage: 20Gi accessModes: - ReadWriteOnce hostPath: path: /data/mysql --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: db-pvc spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 20Gi
$ kubectl apply -f mysql-storage.yml
$ kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/db-pv 20Gi RWO Retain Bound default/db-pvc manual 10h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/db-pvc Bound db-pv 20Gi RWO manual 10h
秘匿情報を先に反映
後で必要になるのでrootのパスワードとかをSecretに入れて反映しておく
パスワードにしたい文字をbase64化
$ echo -n {パスワードにしたい文字列} | base64
Secretに入れて反映
mysql-secret.yml
apiVersion: v1 kind: Secret metadata: name: mysql-secret type: Opaque data: root_password: aG9nZQ== #ここにbase64化した文字列を入れる
$ kubetcl apply -f mysql-secret.yml
worker nodeで動作させたいのでlabelをつけておく
まずnodeの名前を確認して
$ kubectl get nodes NAME STATUS ROLES AGE VERSION vm-1 Ready control-plane,master 3d22h v1.21.1 vm-2 Ready <none> 3d21h v1.21.1
key=value
で名前をつける。
kubectl label nodes vm-2 nodeName=worker
mysql構築
mysql公式のDocker imageを使う。
mysql
使えば余裕じゃんと思っていたのだが、
今回使用しているVM.Standard.A1.FlexのCPUはarmベースとなっており、
mysql
のDocker imageは現状armに対応していないため動作しなかった。
どうやら、mysql-server
は対応しているらしいので、そちらを使う。
設定
こんな感じでDeployment, Service, ConfigMap等を書いて反映。
mysql-serverは8.0にした。
my.cnfの設定はお好み。
mysql.yml
apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - image: mysql/mysql-server:8.0 name: mysql env: - name: MYSQL_ROOT_PASSWORD # 先ほど設定したSecretから取得 valueFrom: secretKeyRef: name: mysql-secret key: root_password - name: TZ value: Asia/Tokyo imagePullPolicy: Always ports: - containerPort: 3306 volumeMounts: - name: mysql mountPath: /var/lib/mysql - name: my-cnf mountPath: /etc/my.cnf subPath: my.cnf readOnly: true # 先ほど設定したlabelをnodeSelectorで指定する nodeSelector: nodeName: worker volumes: - name: mysql # 先ほど設定したPVCを指定する persistentVolumeClaim: claimName: db-pvc - name: my-cnf configMap: name: db-configmap items: - key: my.cnf path: my.cnf --- apiVersion: v1 kind: Service metadata: name: mysql spec: selector: app: mysql type: NodePort ports: - protocol: TCP port: 3306 targetPort: 3306 # nodePort: 30000 # 手元のPC等から確認したい場合に設定(当然セキュリティは落ちる) --- apiVersion: v1 kind: ConfigMap metadata: name: db-configmap labels: app: mysql data: my.cnf: |- [mysqld] bind-address=0.0.0.0 character-set-server=utf8mb4 collation_server=utf8mb4_unicode_ci lower_case_table_names = 1 transaction-isolation=READ-COMMITTED sql_mode = 'TRADITIONAL' skip-name-resolve=1 default_authentication_plugin=mysql_native_password [client] default-character-set=utf8mb4
kubectl apply -f mysql.yml
containerの外から接続できるようにする
参考記事にも記載されているが、
mysql-server
の場合はこんな感じになっている(rootのhostがlocalhost)のでpodの中からしかDBに接続できない。
mysql> select user,host from mysql.user; +------------------+-----------+ | user | host | +------------------+-----------+ | healthchecker | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +------------------+-----------+
ので、一度podに入って外から接続できるユーザを作ってあげる必要がある。
(以下はrootを作る例)
$ kubectl get pods NAME READY STATUS RESTARTS AGE mysql-658d66ff85-nz46j 1/1 Running 0 110m $ kubectl exec --stdin --tty mysql-658d66ff85-nz46j -- /bin/bash bash-4.4# mysql -uroot -p
create user root@'10.%'; grant all privileges on *.* to root@'10.%' with grant option;
確認
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql NodePort 10.X.Y.Z <none> 3306:30000/TCP 116m
worker側で
$ mysql -uroot -h 10.X.Y.Z
で接続できるところまで確認できた。
root以外でも同じ要領でやれば良さそう。
vmインスタンス外からもアクセスしたい場合は
ServiceのnodePort設定、vmインスタンスのiptables穴あけ、OracleCloud上で同じく穴あけが必要なので注意。
(自分はなんとなくrootはpodの中でだけアクセス可能なままで良いやと思ったので消した)