k8sの勉強としてMySQLを動かしてみました。
単に動かすだけならk8sのtasksに載ってる通り↓やればできたのですが、
Run a Single-Instance Stateful Application
https://kubernetes.io/docs/tasks/run-application/run-single-instance-stateful-application/
これだけだと何をやってるのかよくわからなかったので、自分なりに補足してみました。
Run a Single-Instance Stateful Applicationでやっていること
- MySQLのpodが使用するpersistentvolumeを作成
- ↑の永続ボリュームをpodが見つけられるよう、podに持たせるpersistentVolumeClaimを作成
- deploymentを介してMySQLのpodを立てる
- podに外部から接続するためのserviceを作成
上記ではやっていませんが、Secretを使う書き方にも挑戦してみます
#PersistentVolume(PV)とPersistentVolumeClaim(PVC)の作成
PVはホストが持っているストレージをpodに割り当てたいときに使う。
PVを介することで容量を必要な分だけ、任意のディレクトリで割り当てることができる
application/mysql/mysql-pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv-volume # PVの名前
labels:
type: local
spec:
storageClassName: manual # PVCと一致させる必要がある
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce # 一つのノードからread/writeでマウントできるモード
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
# storageClassName=manualのPVを探してマウントする
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi # PVが持っている容量のうち20GBを使用する
#mysqlのpodとservice作成
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
# deploymentが管理するpodを定義
# labelsにapp=mysqlと設定されたpodを管理する
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
# podをアップデートする時の動作を定義
# Recreateのときはpodは一つしか存在できず、更新すると
# 古いものが消え新しいものが再度作成される
strategy:
type: Recreate
template: # podの定義
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password # 本番ではsecretを使ってねとある
ports:
- containerPort: 3306
name: mysql
volumeMounts:# コンテナ内のどのディレクトリにpersistentVolumeをマウントするか
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes: #
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
# name=mysql-pv-claimを使って、マウントできるPVを探す
せっかくなのでSecretを使う場合のやりかたにも挑戦してみます
SecretはdeploymentやServiceのようなk8sのリソースの一つで、名前の通りパスワード等の機密情報を管理するものです。
deploymentのマニフェストにパスワードのベタ書きを避けるために使用します。
Secretに書くパスワードはbase64形式でデコードする必要があります。
echo "password" | base64
vi secret.yaml
kubectl create -f secret.yaml
Secretのマニフェストはこんな感じ↓
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
password: cGFzc3dvcmQK
deploymentのマニフェストのパスワード部分をこんなふうに書き換えます
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
動作確認
ドキュメントの通りにコマンドを実行してみます
# リソースを作成
$ kubectl create -f mysql_pv.yaml
$ kubectl create -f mysql_deployment.yaml
# コンテナに入ってみる
# mysqlが起動すれば成功
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword