k8sでNFSマウント出来なくて困った話
はじめに
k8sでNFSマウントしようとすると
1Unable to mount volumes for pod "test_default(xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)": timeout expired waiting for volumes to attach/mount for pod "default"/"test". list of unattached/unmounted volumes=[nfs]
みたいなエラーで怒られて上手くいかなかったのでその原因の調べ方と設定時の注意点のメモ
そもそもどうやってマウントするの?みたいな話は公式のドキュメント見た方がわかりやすいのでそちらに譲ります
DockerホストでNFSをマウントして条件に合致するpodにデータボリュームでNFSの領域をマウントしてるっぽい
- https://kubernetes.io/docs/concepts/storage/volumes/#nfs
- https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs
環境
相変わらずオンプレです.
物理マシンを2台にUbuntu16.04をインストールし,それぞれMasterとClusterとして設定してあります.
バージョンはv1.9.3です.
1$ kubectl version
2Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.3", GitCommit:"d2835416544f298c919e2ead3be3d0864b52323b", GitTreeState:"clean", BuildDate:"2018-02-07T12:22:21Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
3Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.3", GitCommit:"d2835416544f298c919e2ead3be3d0864b52323b", GitTreeState:"clean", BuildDate:"2018-02-07T11:55:20Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
今回はMaster側にNFS Serverを設定しましたが適宜別のマシン等でNFSを提供できるように設定しておきます.
一応exportsは制限なしで設定した上でこの記事を書いていますが仕組み的にDockerをホストしているマシンからさえマウントできれば問題ありません.
1$ tail -n 1 /etc/exports
2/opt/nfs *(rw,sync,no_subtree_check,no_root_squash)
設定ファイル
PVと作成してPVの条件に適合するPVCを作ってそれをpodにマウントしてやればOKです.volume.beta.kubernetes.io/storage-class
はあとでPVCがマウント可能なPVを探す際に条件として扱われるので値を合わせておく必要があります.
空欄にしておけばすべて適合する(はず
PV
1$ cat nfs-pv.yml
2apiVersion: v1
3kind: PersistentVolume
4metadata:
5 name: nfs-pv
6 annotations:
7 volume.beta.kubernetes.io/storage-class: "nfs"
8spec:
9 capacity:
10 storage: 50Gi
11 accessModes:
12 - ReadWriteMany
13 persistentVolumeReclaimPolicy: Retain
14 nfs:
15 server: 192.168.xxx.xxx
16 path: /opt/nfs
作成して確認します.
既にpvc出来てますけど実際は空欄か何かになっています.
1$ kubectl create -f nfs-pv.yml
2$ kubectl get pv
3NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
4nfs-pv 50Gi RWX Retain Bound default/nfs-pvc slow 20m
PVC
合致するPVがないと永遠に使用可能にならないので上で作成したPVに合致するような設定を入れます.
1$ cat nfs-pvc.yml
2apiVersion: v1
3kind: PersistentVolumeClaim
4metadata:
5 name: nfs-pvc
6spec:
7 accessModes:
8 - ReadWriteMany
9 resources:
10 requests:
11 storage: 50Gi
12 storageClassName: slow
こちらも作成して確認します.
1$ kubectl get pvc
2NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
3nfs-pvc Bound nfs-pv 50Gi RWX slow 38m
問題なく作成されていればひとまずpodでマウントできるか確認します.
1$ cat nfs-pod.yml
2apiVersion: v1
3kind: Pod
4metadata:
5 name: nfs-test
6spec:
7 containers:
8 - name: nfs-test
9 image: nginx
10 volumeMounts:
11 - name: nfs
12 mountPath: "/var/www/"
13 volumes:
14 - name: nfs
15 persistentVolumeClaim:
16 claimName: nfs-pvc
あとはpod作って問題なく動けば終了です.
1$ kubectl create -f nfs-pod.yml
2pod "nfs-test" deleted
3$ kubectl get pod
4NAME READY STATUS RESTARTS AGE
5nfs-test 1/1 Running 0 42m
6$ kubectl describe pod nfs-test
7Events:
8 Type Reason Age From Message
9 ---- ------ ---- ---- -------
10 Normal Scheduled 11s default-scheduler Successfully assigned demo to ノード名
11 Normal SuccessfulMountVolume 10s kubelet, ノード名 MountVolume.SetUp succeeded for volume "nfs-pvc"
12 Normal SuccessfulMountVolume 10s kubelet, ノード名 MountVolume.SetUp succeeded for volume "default-token-xxxxxx"
13 Normal Pulling 9s kubelet, ノード名 pulling image "nginx"
14 Normal Pulled 6s kubelet, ノード名 Successfully pulled image "nginx"
15 Normal Created 6s kubelet, ノード名 Created container
16 Normal Started 6s kubelet, ノード名 Started container
適当にファイルおいてみて確認しておわりです.
詰まったとことか
Node には必ず nfs-common が必要
漠然とDocker自体でマウントしているイメージで用意していませんでした.
先にDockerでNFSマウントできるか試したので先入観良くない.
describeすると以下のエラーが出ます.
1$ kubectl get describe test
2~省略~
3Mounting command: systemd-run
4Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/xxxxxxxx-xxxx-xxxx-xxxxxxxx/volumes/kubernetes.io~nfs/nfs-pv --scope -- mount -t nfs 192.189.xxx.xxx:/opt/nfs /var/lib/kubelet/pods/xxxxxxxx-xxxx-xxxx-xxxxxxxx/volumes/kubernetes.io~nfs/nfs-pv
5Output: Running scope as unit run-r9da60928545e43c49189115bc75d8d44.scope.
6mount: wrong fs type, bad option, bad superblock on 192.189.xxx.xxx:/opt/nfs,
7 missing codepage or helper program, or other error
8 (for several filesystems (e.g. nfs, cifs) you might
9 need a /sbin/mount.<type> helper program)
10
11 In some cases useful info is found in syslog - try
12 dmesg | tail or so.
nfs-common入れればマウントできるようになるので解決します.
1$ sudo apt-get install nfs-common
タイムアウトしてしまう
以下のようなエラーでマウント出来ない
1$ kubectl describe pod nfs-test
2~中略~
3Events:
4 Type Reason Age From Message
5 ---- ------ ---- ---- -------
6 Normal Scheduled 2m default-scheduler Successfully assigned demo to ノード名
7 Normal SuccessfulMountVolume 2m kubelet, ノード名 MountVolume.SetUp succeeded for volume "default-token-xxxxx"
8 Warning FailedMount 44s kubelet, ノード名 Unable to mount volumes for pod "nfs-test_default(xxxxx-xxxx-xxxx-xxxxxx)": timeout expired waiting for volumes to attach/mount for pod "default"/"nfs-test". list of unattached/unmounted volumes=[nfs]
もう少し待ってると詳細エラーが出てきます
1Mounting command: systemd-run
2Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/xxxxx-xxxx-xxxx-xxxxxx/volumes/kubernetes.io~xxxxx-xxxx-xxxx-xxxxxx/volumes/kubernetes.io~nfs/nfs-pvc
3Output: Running scope as unit run-xxxxx-xxxx-xxxx-xxxxxx.scope.
4mount.nfs: Connection timed out
メモし損ねましたがこの前後に実行されたmountコマンドが表示されているので実際にマウントできるかテストしましょう.
自分の場合はしょうもないですがnfs-pvのIPアドレスを打ち間違えていたことにここで気付きました.