自宅で動かしている k8s でも Statefulset を使ってデータベースをデプロイしてみたかったが、 Statefulset を使用する場合はストレージを Dynamic Volume Provisioning できるようにしておく必要があった。
プロビジョナー一覧を確認して最も簡単に用意できそうなのが nfs だったので、 kubernetes-sigs/nfs-subdir-external-provisioner を使ってセットアップしてみた。
kustomize の設定
おおよそ README.md の通りに進めて行けば良い。基本的な構成ファイルは こちらの GitHub リポジトリ にあり、これを resources
で指定しつつ、必要部分だけ resources
や patch
で上書きしていく。
provisioner を動かすネームスペースと、利用する nfs サーバーのパラメーターを指定するため、まずは namespace.yaml と deployment.yaml を用意していく。
# namespace.yaml apiVersion: v1 kind: Namespace metadata: name: example-namespace # provisoner を動かす namespace
# namespace.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: nfs-client-provisioner name: nfs-client-provisioner spec: template: spec: containers: - name: nfs-client-provisioner env: - name: NFS_SERVER value: 192.0.2.254 # nfs サーバーのアドレス - name: NFS_PATH value: /kube/nfs # nfs サーバーのパス volumes: - name: nfs-client-root nfs: server: 192.0.2.254 # nfs サーバーのアドレス path: /kube/nfs # nfs サーバーのパス
env と volumes で同じ値を記述していくの二度手間だな...と思いつつ素直に真似しておく。
最後に kustomization.yaml を作成して、GitHub リポジトリにあるベース設定と、作成した namespaces.yaml、deployment.yaml を指定しておく。
# kustomization.yaml namespace: example-namespace resources: - https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner//deploy?ref=nfs-subdir-external-provisioner-4.0.18 - namespace.yaml patches: - path: deployment.yaml
resources に GitHub の URL を書けたりするのは知らなかった。remote targets と呼ぶらしい。README.md の例は Legacy URL format だったので読み替えたりした。
完成したら yaml を置いてあるディレクトリを指定して apply する。
kubectl -k ./nfs-provioner
終わったら provisioner の pod が起動しているか確認する
$ kubectl get pod -n example-namespace NAME READY STATUS RESTARTS AGE nfs-client-provisioner-6d6d6586d6-bzr2n 1/1 Running 0 52s
pod は無事起動しているようだ。
provisioner の動作確認
本当に動作するか PersistentVolumeClaim を記述した yaml ファイルを用意して確認する。
# pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfs-example spec: storageClassName: nfs-client accessModes: - ReadWriteMany resources: requests: storage: 100Mi
apply する
kubectl apply -f ./pvc.yaml
volume が作成されていることか確認。
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfs-example Bound pvc-357aee94-d1fe-4e7a-962b-c41a429d65b2 100Mi RWX nfs-client 110s
$ kubectl describe pvc nfs-example Name: nfs-example Namespace: default StorageClass: nfs-client Status: Bound Volume: pvc-357aee94-d1fe-4e7a-962b-c41a429d65b2 Labels: <none> Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes volume.beta.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner volume.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner Finalizers: [kubernetes.io/pvc-protection] Capacity: 100Mi Access Modes: RWX VolumeMode: Filesystem Used By: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ExternalProvisioning 121s persistentvolume-controller waiting for a volume to be created, either by external provisioner "k8s-sigs.io/nfs-subdir-external-provisioner" or manually created by system administrator Normal Provisioning 121s k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-6d6d6586d6-bzr2n_b29d68e1-cd9a-465e-b78a-a46a8e8e03fc External provisioner is provisioning volume for claim "default/nfs-example" Normal ProvisioningSucceeded 121s k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-6d6d6586d6-bzr2n_b29d68e1-cd9a-465e-b78a-a46a8e8e03fc Successfully provisioned volume pvc-357aee94-d1fe-4e7a-962b-c41a429d65b2
無事に provision されてそう。これで Statefulset を使って Postgres や Redis をデプロイし放題になった。*1
*1:PostgreSQL を NFS 上で動かす場合は注意事項が色々あるので気をつけよう