KubernetesのhostPathを使ったDynamic Volume Provisioningテスト
経緯
Helmを使ってインストールしようとしたらpodが以下のメッセージでPendingになりました。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 21s default-scheduler 0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
Kubernetesで永続化したボリュームを使うにはPersistentVolumeが必要なのですが、
自分で構築したKubernetesの場合、別途事前に作成する必要があります。
実際確認すると存在していませんでした。
$ kubectl get pv
No resources found
そこでPersistentVolumeを準備しようとしましたが、
Helmで提供されているchartはDynamic Provisioning前提となっているものがあるので、
それに対応したストレージクラスにする必要があるようです。
例えばbitnami/mysql
。
しかし対応しているProvisionerはクラウドばかりなので、
NFS
や
iSCSI
で
利用しようとするとexternal provisionersにする必要があるらしい。
ちょっとテストするだけでそれらを準備するのはちょっと億劫だなと思ったら、
こちら
によると
テストまたは開発目的用のhostPath Provisionerと言うのがあるらしいです。
これだ!と思ったら紹介されていたのはソースコードからビルドする方法だったので、
kubeadmで構築した環境でのやり方を調べてみました。
環境
ESXi上のUbuntuにkubeadmで構築したシングルノードクラスターです。
ubuntu@k8s:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s Ready control-plane,master 22d v1.20.2
ubuntu@k8s:~$ kubectl get all -n kube-system
NAME READY STATUS RESTARTS AGE
pod/coredns-74ff55c5b-7w7kq 1/1 Running 1 22d
pod/coredns-74ff55c5b-bmdnw 1/1 Running 1 22d
pod/etcd-k8s 1/1 Running 1 22d
pod/kube-apiserver-k8s 1/1 Running 1 22d
pod/kube-controller-manager-k8s 1/1 Running 1 22h
pod/kube-flannel-ds-95hkq 1/1 Running 1 22d
pod/kube-proxy-tgdm2 1/1 Running 2 22d
pod/kube-scheduler-k8s 1/1 Running 1 22d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 22d
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/kube-flannel-ds 1 1 1 1 1 <none> 22d
daemonset.apps/kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 22d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/coredns 2/2 2 2 22d
NAME DESIRED CURRENT READY AGE
replicaset.apps/coredns-74ff55c5b 2 2 2 22d
kube-controller-managerの設定変更
こちらのドキュメント
によるとkube-controller-managerの
「–enable-hostpath-provisioner」オプションを有効化すると使えそうです。
変更の仕方はこちら
を参考にさせていただきました。
以下のように1行追記すれば自動で反映されます。
ubuntu@k8s:~$ sudo cat /etc/kubernetes/manifests/kube-controller-manager.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: kube-controller-manager
tier: control-plane
name: kube-controller-manager
namespace: kube-system
spec:
containers:
- command:
- kube-controller-manager
- --allocate-node-cidrs=true
- --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
- --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
- --bind-address=127.0.0.1
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --cluster-cidr=10.244.0.0/16
- --cluster-name=kubernetes
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
- --controllers=*,bootstrapsigner,tokencleaner
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true
- --port=0
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --root-ca-file=/etc/kubernetes/pki/ca.crt
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/12
- --use-service-account-credentials=true
- --enable-hostpath-provisioner=true
動作テスト
有効にしましたらこちら を 参考にストレージクラスを作成します。
ubuntu@k8s:~$ cat provisioner.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: standard
annotations:
storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/host-path
ubuntu@k8s:~$ kubectl create -f provisioner.yaml
storageclass.storage.k8s.io/standard created
では bitnami/mysql をインストールしてみます。
ubuntu@k8s:~$ helm install my-release bitnami/mysql --set volumePermissions.enabled=true
※僕の場合以下のエラーが発生したので
トラブルシュート
に従って
「–set volumePermissions.enabled=true」を追加しています。
mkdir: cannot create directory '/bitnami/mysql/data': Permission denied
無事起動したようです。
ubuntu@k8s:~$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/my-release-mysql-0 1/1 Running 0 6m14s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
service/my-release-mysql ClusterIP 10.106.170.174 <none> 3306/TCP 6m14s
service/my-release-mysql-headless ClusterIP None <none> 3306/TCP 6m14s
NAME READY AGE
statefulset.apps/my-release-mysql 1/1 6m14s
ubuntu@k8s:~$ kubectl get sc,pv,pvc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/standard (default) kubernetes.io/host-path Delete Immediate false 33m
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-eb90dca8-103d-4ca1-b619-4804fa09d311 8Gi RWO Delete Bound default/data-my-release-mysql-0 standard 6m58s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/data-my-release-mysql-0 Bound pvc-eb90dca8-103d-4ca1-b619-4804fa09d311 8Gi RWO standard 6m58s