前回の続きでノードの腹持ちにProvisonerがないローカルなStorageClassを作る方法を記載してみた。注意点は、ノードの腹持ちの領域をストレージとして使うので、Podがノードに依存するので、Podがノードに固定されてしまうという問題がある。ノードにデータを置く、ローカルストレージ全般に言えることだが、常日頃バックアップをしていないと怖い。このようなユースケースの場合、LonghornやCephなどの複数ノードが使えるStorageClassを構築するのがベストだと思う。
なぜ、今更やるのか???と思ったが作ってみた。Provisonerのないlocalストレージ。もう2度とやらないと思う。これも
前回記載した、ProvisonerがないNFSと記載が微妙に異なるので注意する。具体的には、
- volumeBindingModeがWaitForFirstConsumerなので、PodができないとPVCがBoundされない。
- accessModesは、当たり前だが ReadWriteOnceしかサポートされない。
- ホスト名の指定が必要
となる。
閑話休題
事前準備
ノードサーバが1台あればいい。今回は、シングルノードのKubernetes環境を想定している。
複数台ある場合は、どれか1台にする。(やったことないのでもしかするとSchedulingとかの設定も必要かもしれない。)
ノードサーバにて
ノードサーバに個別のPVのフォルダをPV10個分を作る。
mkdir -p /disk/localpv/pv{01..10}
chmod -R 777 /disk/localpv/pv{01..10}
Kubernetes側にて
StorageClassの定義
reclaimPolicyは、Retainにしておく。Recycledがサポートされているが、非推奨。また、Deleteにしても動作はRetainになるので。volumeBindingModeは、WaitForFirstConsumerにする。
cat <<EOF | kubectl create -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
EOF
StorageClassの確認
kubectl get sc local-storage
kubectl describe sc local-storage
local-storageというStorageClassが見えるはず。
PVの作成:取り急ぎ、25GBのPVを10個つくる。
PVを10個作るためにSHELLで回している。また、accessModeは、ReadWriteOnceのみを指定している。PVCを呼び出すときにこれが合っていないと利用されない。
for i in $(seq -w 10); do
# Create PV
HOSTNAME=$(hostname)
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv$i
spec:
capacity:
storage: 25Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /disk/localpv/pv$i
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- ${HOSTNAME}
EOF
PVの確認`
kubectl get pv -o wide
作成したPVが10個見えるはず。これで、25GBまでのReadWriteOnceのPVCができるようになる。
ただし、PVCはサイズを10GBと指定しても25GBになる。
PodとPVCを作成
NAMESPACE=test1
kubectl create namespace ${NAMESPACE}
cat <<EOF | kubectl --namespace=${NAMESPACE} create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: local-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
EOF
kubectl -n ${NAMESPACE} get pod,pvc -o wide
以下を実行
kubectl -n ${NAMESPACE} describe pv local-pv04
ノードのローカルパスがわかる。
ノードサーバにて、Volumeの実態のフォルダにコンテンツを作る。上記のVOLUMEがnfs-pv09なので
echo "test pod" >/disk/localpv/pv04/index.html
Kubernetesにて、
curl http://10.0.0.23/
test podと表示されるはず。
テストを終了する場合は
kubectl delete ns test1
ノードサーバにて、利用したPVの中身を削除する。reclaimPolicyがRetainなので、手動でデータを削除する。
rm /disk/localpv/pv04/index.html
結果として、NFSと同様の結果で終わる。それにしても、今となっては何もメリットがない。素直にLonghornを使うべき。