こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
私は今までにGKEにWordpress環境を少しずつ発展させる形で構築してきました。
今回は永続ボリュームデプロイ時にStorageClassを使用してみたいと思います。
vol.4との比較
vol.4でも永続ボリュームを使用しましたが、その際にGCPのGCEにアクセスしWebコンソール上でポチポチしてストレージを用意しました。
検証用や、永続ボリュームを使用するpod等が少ない状態で有ればこれでも良いかもしれませんが、数が増えてくると地獄を見そうです。ヒューマンエラーも起こり得るでしょう。
k8sのStorageClassを使用すると、今回の様にGCPやAWS,AzureのようなPublicクラウドから、ローカルのNFSやOpenStackのCinder、Ceph等に自動的に必要なストレージを用意してくれるようになります。
具体的にはPVC起因でデプロイされるようになります。
構築する環境
PV/PVC/StorageClassについて、イメージが若干おかしいかもしれませんが、私の頭の中では以下の様な構成になっております。
PVCをyamlからデプロイすると、PVCに関連付けられたStorageClassが反応しGCE上にストレージを作成しに行き、podは作成されたストレージに対してアタッチされます。
用意したファイル一覧
新規作成及び修正分のみこちらに記載します。
残りのyamlはvol.4をご覧頂ければと思います。
新規作成
mysql-storageclass.yaml
GCE上にストレージを作成する為のyamlファイルとなります。
metadataの名前の部分がPVCのstorageClassNameと一致すると、キックされてストレージを作成しに行きます。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql-storage-class
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
fstype: ext4
replication-type: none
修正
mysql-pvc.yaml
StorageClass使用にあたり、spec.storageClassName部分を修正しました。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-vol-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: mysql-storage-class
resources:
requests:
storage: 50Gi
構築
まず、GCE上にストレージが無い事とGKE上にPVCが無いことを確認します。
次にStorageClassをデプロイしてみます。
デプロイ後get,describeもしてみます。RECLAIMPOLICYがDeleteとなっていることからPVCを削除するとストレージも削除されます。この辺りはyamlで変更出来ると思います。確認は特段しておりませんけれども。。。
また、このタイミングではGCE、GKEのWebコンソールには何も変化ありません。
$ kubectl apply -f mysql-storageclass.yaml
$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
enterprise-multishare-rwx filestore.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
enterprise-rwx filestore.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
mysql-storage-class kubernetes.io/gce-pd Delete Immediate false 10s
premium-rwo pd.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
premium-rwx filestore.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
standard kubernetes.io/gce-pd Delete Immediate true 36m
standard-rwo (default) pd.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
standard-rwx filestore.csi.storage.gke.io Delete WaitForFirstConsumer true 36m
$ kubectl describe sc mysql-storage-class
Name: mysql-storage-class
IsDefaultClass: No
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{},"name":"mysql-storage-class"},"parameters":{"fstype":"ext4","replication-type":"none","type":"pd-standard"},"provisioner":"kubernetes.io/gce-pd"}
Provisioner: kubernetes.io/gce-pd
Parameters: fstype=ext4,replication-type=none,type=pd-standard
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
PVCをデプロイします。
$ kubectl apply -f mysql-pvc.yaml
このタイミングでGCE及びGKE上で作成されたストレージ、PVCが確認出来るようになります。
PVCがデプロイされたことでStorageClassがキックされて、ストレージが作成されたということですね。
まずはGCEのストレージ
続いてGKEのPVC
CUIでも確認してみましょう。PVのyamlは用意しておらずデプロイもしておりませんがStorageClassが良い感じにやってくれているようですね。
$ kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-c2a74a10-58eb-4356-ae54-b1316630d42d 50Gi RWO Delete Bound default/mysql-vol-pvc mysql-storage-class 2m53s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mysql-vol-pvc Bound pvc-c2a74a10-58eb-4356-ae54-b1316630d42d 50Gi RWO mysql-storage-class 2m58s
他のyamlファイルからもデプロイをして、Wordpressを立ち上げます。
今回用意したWordpressは"GKE-storageClass"というタイトルのものとします。
MySQL podが削除されてもデータが残ることを確認します。
既存のMySQL podをデリートし新しいpodをデプロイします。
$ kubectl replace --force -f mysql-pod.yaml
pod "mysql-pod" deleted
Warning: Autopilot set default resource requests for Pod default/mysql-pod, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/mysql-pod replaced
再度Webブラウザで接続しに行っても、同じ画面が表示されます。データは残っていると判断できますね。
StorageClassを有効的に活用すれば、ストレージ周りの管理コストが圧縮できそうだなと感じました。バインドについてもたぶんミスることは無いでしょうし、「なぜバインドされない?」的な感じで頭を抱えることも減りそうです。