PersistentVolumeを作成したらエラーになる
公式チュートリアルでPersistentVolumeを使ったWordPressのデプロイをやっていたところ
いつまで経ってもPVCがPendingのまま。。。
kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE wp-pv-claim Pending standard 15s
詳細を見てみると「storageclass.storage.k8s.io "standard" not found」とエラーになる。。
kubectl describe pvc wp-pv-claim Name: wp-pv-claim Namespace: test StorageClass: standard Status: Pending Volume: Labels: app=wordpress Annotations: <none> Finalizers: [kubernetes.io/pvc-protection] Capacity: Access Modes: VolumeMode: Filesystem Used By: wordpress-5d96f87b44-tvg4m Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning ProvisioningFailed 12s (x12 over 2m47s) persistentvolume-controller storageclass.storage.k8s.io "standard" not found
あとから分かったことだが、StorageClassというリソースがKubernetesにはあり、 それがなかったのが直接的な原因
kubectl get pv No resources found
それを解決するまでの道筋をメモしておく
PVの作成まで
まず、StorageClassがなくてもPVもPVCも作成することはできる。
試しにPVを作成してみる。
apiVersion: v1 kind: PersistentVolume metadata: name: pv01 spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Delete storageClassName: standard hostPath: path: /data type: DirectoryOrCreate
accessModes
- ReadWriteOnce(RWO) 単一ノードからRead/Writeされる
- ReadOnlyMany(ROX) 単一ノードからWrite、複数ノードからReadされる
- ReadWriteMany(RWX) 複数ノードからRead/Writeされる
persistentVolumeReclaimPolicy
Reclaim Policyは、PersistentVolumeを利用し終わった後の処理方法を制御するポリシー
- Retain PersistentVolumeのデータも消さずに保持する。また、他のPersistentVolumeClaimによって、このPersistentVolumeが再度マウントされることはない
- Recycle PersistentVolumeのデータを削除し、再利用可能な状態にする よって他のPersistentVolumeClaimによって再度マウントされる
- Delete PersistentVolumeが削除されます GCE、AWSなど外部ボリュームの際に利用する
確認
kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01 1Gi RWO Delete Available standard 41s
よさそうなのでPVCも作成してみる
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc01 spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 1Gi storageClassName: standard
これも無事に作成されている
kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc01 Bound pv01 1Gi RWO standard 50s
試しにマウント用のPodを作成して確認してみる
apiVersion: v1 kind: Pod metadata: name: pvc-test spec: containers: - image: alpine name: alpine command: ["tail", "-f", "/dev/null"] volumeMounts: - name: claim-volume mountPath: /data volumes: - name: claim-volume persistentVolumeClaim: claimName: pvc01 terminationGracePeriodSeconds: 0
これでShellの中に入るとたしかにマウント可能
/data # ls -l total 0 -rw-r--r-- 1 root root 0 Jul 19 23:35 aaaaaaaaa
PVが削除されたら中身も削除されるのでPodを消して再生成しても中身は残る
が、Podを立てるたびにPVCを指定しなければならないのはダルすぎる
ってことでPVCの要件を指定したら自動でいい感じにKubernetes側に選んでマウントしてもらいたい
それがStorageClassってリソース
StorageClassの作成
ようやく本題に入るが実はセキュリティ上の理由からデフォルトではホストのマウントする形のStorageClassの作成が許可されていない
のでその許可を先に行う
hostPath provisionerを有効化する
/etc/kubernetes/manifests/kube-controller-manager.yaml を開いて --enable-hostpath-provisioner=true
を追加する。
編集保存した瞬間にcontroller-managerのpodが再起動&反映されるので注意
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.100.0.0/16 - --cluster-name=myhome - --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 - --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 # ← ココ!
いざStorageClassを作成 デフォルトではStorageClassは「standard」らしいのでそれに従う
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: standard annotations: storageclass.beta.kubernetes.io/is-default-class: "true" provisioner: kubernetes.io/host-path
確認
kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) kubernetes.io/host-path Delete Immediate false 67m
あとはチュートリアルの kustomization.yaml を再反映すれば無事に
kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mysql-pv-claim Bound pvc-7a1040f1-3867-44fc-be04-9b980e269a96 20Gi RWO standard 5m53s wp-pv-claim Bound pvc-c303dff4-3327-4df9-b0b1-e73d9b00cdd1 20Gi RWO standard 5m53s
となる
volumeBindingModeについて
後で調べる
参考リンク
- Kubernetes道場 12日目 - PersistentVolume / PersistentVolumeClaim / StorageClassについて - Toku's Blog
- KubernetesのConfig&Storageリソース(その2) | Think IT(シンクイット)
- KubernetesのhostPathを使ったDynamic Volume Provisioningテスト - つちのこメタル
- 【Kubernetes】PVとPVCで永続ボリュームを使う | amateur engineer's blog
- コンテナをくべる [永] PersistentVolumeClaimsでエラー