概要
KubernetesのPersistentVolume(永続ストレージ)を使って、NFSサーバーをPodにmountする。
Dynamic Provisioningについてはこのページでは触れない。以下を参照。
【KubernetesのPersistentVolume】その2- Dynamic Provisionerを使ってNFSサーバーをPodにmountする
目次
前提知識
PersistentVolumeの仕組み
まず、PersistentVolumeがPodにmountされる仕組みについて説明する。
以下の表の用に、3つの定義ファイルを用意する。
filename | Resource | description |
---|---|---|
pod.yml | Pod | Podの定義 |
persistent-volume-claim.yml | PersistentVolumeClaim | Podが要求するVolumeのspecを定義する |
persistent-volume.yml | PersistentVolume | Volumeの定義 |
- persistent-volume.ymlでは、Volumeの定義をする。
- pod.ymlでpodの定義と、関連付けるpersistent-volume-claim.ymlを定義する。
- persistent-volume-claim.ymlには、Podが要求するspecのVolumeの定義をする。
- PersistentVolumeClaimは、要求に一番近いspecのPersistentVolume探し、mountする。
つまりPodは、PersistentVolumeClaimを通して「こういうspecのVolumeが欲しい」と要求を出すと、その要求に一番近いPersistentVolumeがmountされるという仕組みになっている。
例えば、Podが5GiのVolumeが欲しいと要求を出したが、実際には10Gi, 20GiのVolumeしか存在していない場合、一番近い10GiのVolumeがmountされる。
ただし、persistent-volume.ymlとmetadata.name、metadata.labelsと、persistent-volume-claim.ymlのspec.selector.matchLabels、spec.selector.matchExpressionsの値を合わせることで、PersistentVolumeとPersistentVolumeClaimのマッチングをより明示的に、期待したとおりにできる。
ここで指定した条件が見つからない場合には自動割当、最悪いずれも割り当てられないという状態になる。
以下のページが分かりやすい。
参考:KubernetesのConfig&Storageリソース(その2)
Dynamic Provisioningについて
Dynamic Provisioningを利用することで、PersistentVolumeClaimが要求を出したタイミングで、動的にPersistentVolumeを作成することが可能となるが、ここでは触れず、以下のページで説明する。
【KubernetesのPersistentVolume】その2- Dynamic Provisionerを使ってNFSサーバーをPodにmountする
ハンズオン
実際にやってみる。
今回はNFSサーバーの/var/share/nfsディレクトリを、Podの/usr/share/nginx/htmlにmountする。
環境
- CentOS 7.6
- Minikube v1.1.1
- Kubernetes v1.14.3
ここではMinikubeで構築した環境のPodに、NFSサーバーをmountする。
関連記事:Minikubeを使ってローカルにkubernetes環境を構築
事前準備
NFSサーバーの構築
以下を参考にNFSサーバーを構築する。
PersistentVolume
Volumeの定義をする。
apiVersion: v1
kind: PersistentVolume
###################################################################
# persistent-volume-claim.ymlのspec.selector.matchLabels、
# spec.selector.matchExpressions以下の値と合わせることで
# PersistentVolumeとPersistentVolumeClaimのマッチング精度を高める。
###################################################################
metadata:
# persistent-volume-claim.ymlのspec.selector.matchLabels.typeと合わせる
name: nfs001
labels:
type: nfs
environment: stg
# Annotaion: https://blog.a-know.me/entry/2018/08/13/223633
annotations:
volume.beta.kubernetes.io/storage-class: "slow"
spec:
# Volumeの容量を定義する
capacity:
storage: 1Gi
##################################################
# ReadWriteOnce: 1つのノードからR/Wでマウントできる
# ReadOnlyMany: 複数のノードからReadOnlyでマウントできる
# ReadWriteMany: 複数のノードからR/Wでマウントできる
##################################################
accessModes:
- ReadWriteMany
# PersistentVolumeClaim を削除した時の動作
persistentVolumeReclaimPolicy: Recycle
# persistent-volume-claim.ymlのspec.storageClassNameと合わせる
storageClassName: slow
# mountコマンドの-oオプション。hard, soft, nolock
mountOptions:
- hard
nfs:
# mountするNFSサーバーのディレクトリ
path: /var/share/nfs
# NFSサーバーのホスト
server: xxx.xxx.xxx.xxx
PersistentVolumeClaim
Podが要求するPersistentVolumeの内容を定義する。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
# pod.ymlのspec.volumes.persistentVolumeClaim.classNameと合わせる
name: nfs-claim1
# Annotaion: https://blog.a-know.me/entry/2018/08/13/223633
annotations:
"volume.beta.kubernetes.io/storage-class": "slow"
# 要求するpersistentVolumeのspec
spec:
selector:
matchLabels:
# persistent-volume.ymlのmetadata.labels.typeと合わせる
type: "nfs"
matchExpressions:
###################################################################
# persistent-volume.ymlのmetadata.labels以下の値と合わせることで
# PersistentVolumeとPersistentVolumeClaimのマッチング精度を高める。
# operatorはIn, NotIn, Exists, DoesNotExistのどれかを選ぶ。
# https://kubernetes.io/docs/concepts/storage/persistent-volumes/
###################################################################
- {key: environment, operator: In, values: [stg]}
##################################################
# ReadWriteOnce: 1つのノードからR/Wでマウントできる
# ReadOnlyMany: 複数のノードからReadOnlyでマウントできる
# ReadWriteMany: 複数のノードからR/Wでマウントできる
##################################################
accessModes:
- ReadWriteMany
# PersistentVolumeに要求するリソース
resources:
requests:
storage: 1Gi
# persistent-volume.ymlのspec.storageClassNameと合わせる
storageClassName: slow
Pod
Podを定義する。
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
spec:
# コンテナの定義
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
# マウントするディレクトリを指定
volumeMounts:
# 以下のspec.volumes.nameと合わせる
- name: mydata
# mountするコンテナ内のディレクトリ
mountPath: "/usr/share/nginx/html"
volumes:
# 上記のspec.containers.volumeMounts.nameと合わせる
- name: mydata
# 要求(mount)するPersistentVolumeClaimを指定
persistentVolumeClaim:
# persistent-volume-claim.ymlのmetadata.nameと合わせる
claimName: nfs-claim1
作成
$ sudo kubectl apply -f persistent-volume.yml -f persistent-volume-claim.yml -f pod.yml
persistentvolume/nfs001 created
persistentvolumeclaim/nfs-claim1 created
pod/my-nginx-pod created
起動確認
Podが起動した。
$ sudo kubectl get pod
NAME READY STATUS RESTARTS AGE
+my-nginx-pod 1/1 Running 0 32s
PersistentVolumeが作成された。正常に作成されるとSTATUSがBoundになる。
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
+nfs001 1Gi RWX Recycle Bound default/nfs-claim1 slow 36s 50s
PersistentVolumeClaimが作成された。
$ sudo kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
+nfs-claim1 Bound nfs001 1Gi RWX slow 38s
mountされているか確認
NFSサーバーの/var/share/nfsディレクトリを、Podの/usr/share/nginx/htmlにmountしたので、
まず、NFSサーバーの/var/share/nfsにテスト用ファイルを作成する。
$ echo 'This is a sample page.' > /var/share/nfs/index.html
次に、Podで/var/share/nfsが/usr/share/nginx/htmlにmountされているか確認。
index.htmlが見えればOK。
$ sudo kubectl exec -it my-nginx-pod ls /usr/share/nginx/html
index.html
$ sudo kubectl exec -it my-nginx-pod cat /usr/share/nginx/html/index.html
This is a sample page.
その他
PersistentVolumeが完全にCreateされる前にPodを起動すると以下のWarningが出るが、最終的にmountされていることが確認できれば問題ない。
$ sudo kubectl describe pod my-nginx-pod
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 6m25s (x2 over 6m25s) default-scheduler pod has unbound immediate PersistentVolumeClaims
Normal Scheduled 6m23s default-scheduler Successfully assigned default/my-nginx-pod to minikube
Normal Pulling 6m23s kubelet, minikube Pulling image "nginx"
Normal Pulled 6m19s kubelet, minikube Successfully pulled image "nginx"
Normal Created 6m19s kubelet, minikube Created container nginx
Normal Started 6m19s kubelet, minikube Started container nginx