nfsサーバを構築しKubernetesからストレージとして利用してみた
Contents
概要
こんにちは。
Kubernetesのpodは動作しているnodeにマウントしてデータを残すことは可能ですが、podが別nodeに存在していた場合、再利用がおこなえないので外部ストレージとしてnfsサーバを使用します。
nfsサーバの環境は、AlmaLinuxを使用し、Kubernetes環境は、Ubuntuを使用します。
nfsサーバを構築し、PersistentVolume(PV)とPersistentVolumeClaim(PVC)を作成し、作成したリソースをpodから使用します。
PV、PVCは永続化領域を要求するリソースです。
詳細は以下を参考にしてください。
- 参考文献: 永続ボリューム | Kubernetes
NFSサーバ側での操作
NFSサーバインストール
NFSサーバのインストールおよびサービス開始と自動起動設定をします。
dnf install nfs-utils
・
・[中略]
・
インストール済み:
gssproxy-0.8.0-19.el8.aarch64 keyutils-1.5.10-9.el8.aarch64 libverto-libevent-0.3.0-5.el8.aarch64 nfs-utils-1:2.3.3-46.el8.aarch64 python3-pyyaml-3.12-12.el8.aarch64
quota-1:4.04-14.el8.aarch64 quota-nls-1:4.04-14.el8.noarch rpcbind-1.2.5-8.el8.aarch64
完了しました!
→NFSサーバのインストール。
systemctl --now enable nfs-server
Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.
→NFSサーバインストールおよび自動起動有効化
共有するディレクトリの公開設定
筆者は、公開するディレクトリとして、 /export/nfs
としています。
mkdir -p /export/nfs
→共有先ディレクトリ作成
cp -p /etc/exports /etc/exports.org
→設定ファイルのバックアップ。
cp -p /etc/exports /etc/exports_$(date +%Y%m%d)
→設定ファイルのバックアップ。
公開するディレクトリ、公開を許可するネットワークや権限を指定します。
設定はそれぞれの環境にあわせてください。
echo "/export/nfs 192.168.1.0/24(rw,sync,no_root_squash)" > /etc/exports
- 192.168.1.0/24 公開先ホストネットワークを指定
- (rw,sync,no_root_squash) 読み書きを許可し、即座に反映、クライアントのrootアクセスをサーバ上のrootとして扱う。
設定反映
exportfs -a
→先ほどの設定をエクスポートする。
systemctl restart nfs-server.service
→nfsサーバ再起動
exportfs
/export/nfs 192.168.1.0/24
→エクスポートされたことを確認。
podで使用する領域を作成
pod毎に領域を分割して使用できるようにしたいので、 /export/nfs
配下に pv0001
というディレクトリを作成しこちらの領域をKubernetes側で使用します。
mkdir /export/nfs/pv0001
→k8sで利用するpv領域を作成します。
k8s側でnfs領域をマウントするため、 apt-get install nfs-common
コマンドで、必要なパッケージをワーカーノードおよび全クラスターにインストールします。(k8s側 OSはUbuntuを使用しております。)
※上記パッケージをインストールしないと、pod側でマウントができない可能性があります。
Kubernetes側での操作
マニフェスト作成
k8s側でpv、pvc、deployマニフェストを作成します。
mkdir pv-test
cd pv-test/
PV、PVCの動作イメージは以下を参考にしてください。
KubernetesのConfig&Storageリソース(その2)
PVリソース作成
server: 192.168.1.110
の部分は、先ほどのnfsサーバのIPを指定します。
path: /export/nfs/pv0001
の部分は、先ほど作成したpv領域を指定します。
vi create-persistent-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
annotations:
volume.beta.kubernetes.io/storage-class: "slow"
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
server: 192.168.1.110
path: /export/nfs/pv0001
kubectl create -f create-persistent-volume.yaml
→pvを作成します。
STATUSがAvailableになれば問題ありません。
ディレクトリが存在しないなど何かしら問題がある場合にはAvailableにならないので注意。
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 5Gi RWO Recycle Available slow 32m
PVCリソースの作成
今度は、作成したpvを利用するpvcを作成します。
pvで annotations
を指定しているので pvc でも必ず指定します。
annotations や accessModes
がpv作成時の定義とマッチしないと割り当てに失敗します。
vi create-persitent-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: centos-pv-claim
labels:
app: centos-pv-test
annotations:
"volume.beta.kubernetes.io/storage-class": "slow"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
kubectl apply -f create-persitent-claim.yaml
→pvcを作成します。
pvc(PersistentVolumeClaim)
が pv(PersistentVolume)
の確保に失敗すると、ステータスは Pending
のままになります。
STATUSがBound状態であれば問題ありません。
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
centos-pv-claim Bound pv0001 5Gi RWO slow 29s
PODのデプロイ
作成したpvcを利用するpodをデプロイします。
volumes: -> persistentVolumeClaim: -> claimName: は pvc で指定した metadata: -> name:
の値を設定します。
vi centos8-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: centos-pv-test-centos8
labels:
app: centos-pv-test
spec:
selector:
matchLabels:
app: centos-pv-test
tier: centos8
strategy:
type: Recreate
template:
metadata:
labels:
app: centos-pv-test
tier: centos8
spec:
containers:
- image: centos:8
name: centos8
command:
- "/sbin/init"
volumeMounts:
- name: centos8-persistent-storage
mountPath: /tmp
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: true
readOnlyRootFilesystem: false
seLinuxOptions: {}
volumes:
- name: centos8-persistent-storage
persistentVolumeClaim:
claimName: centos-pv-claim
kubectl apply -f centos8-deployment.yaml --record
→podを作成します。
作成したpodのSTATUSがRunningになっていることを確認します。
kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-pv-test-centos8-685fdfd555-78nck 1/1 Running 0 29s
実際にpodに入ってマウントされているか確認します。
dfコマンドで無事にマウントされていることが確認できました。
kubectl exec --stdin --tty centos-pv-test-centos8-685fdfd555-78nck -- bash
[root@centos-pv-test-centos8-685fdfd555-78nck /]# df -PTh
・
・{中略}
・
192.168.1.110:/export/nfs/pv0001 nfs4 29G 1.9G 27G 7% /tmp
・
・{中略}
・
試しにマウント領域でtestファイルを作成してます。
[root@centos-pv-test-centos8-685fdfd555-78nck /]# touch /tmp/test
nfsサーバ側で確認するとtestファイルができていることが確認できました。
ls -la /export/nfs/pv0001/
-rw-r--r-- 1 root root 0 2月 8 23:32 test
→nfsサーバ側から見ています。
podを削除します。
削除後も、マウント先のファイルは残り続けます。
kubectl delete -f centos8-deployment.yaml
※PV、PVCリソースを削除すると、NFSマウント領域、ココで言うと、 /var/nfs/pv0001/ 配下のファイルやディレクトリが削除されるので注意してください。
自動マウント処理
筆者の場合、materクラスターでnfsサーバのファイル管理したいのでk8sシステム側とは別に、自動マウントしたいと思います。
cp -p /etc/fstab /etc/fstab.org
cp -p /etc/fstab /etc/fstab_$(date +%Y%m%d)
fstabにまず記載します。
192.168.1.110はnfsサーバのIPになります。
vi /etc/fstab
192.168.1.110:/export/nfs /var/nfs nfs defaults 0 0
自動マウントに必要なパッケージをインストールします。
apt -y install autofs
Creating config file /etc/auto.master with new version
Creating config file /etc/auto.net with new version
Creating config file /etc/auto.misc with new version
Creating config file /etc/auto.smb with new version
Creating config file /etc/autofs.conf with new version
Creating config file /etc/default/autofs with new version
update-rc.d: warning: start and stop actions are no longer supported; falling back to defaults
Created symlink /etc/systemd/system/multi-user.target.wants/autofs.service → /lib/systemd/system/autofs.service.
man-db (2.9.3-2) のトリガを処理しています ...
systemd (246.6-1ubuntu1.7) のトリガを処理しています ...
cp -p /etc/auto.master /etc/auto.master.org
cp -p /etc/auto.master /etc/auto.master_$(date +%Y%m%d)
最下行に追加します。
vi /etc/auto.master
/- /etc/auto.mount
/etc/auto.mount
は新規で作成する形となります。
vi /etc/auto.mount
/var/nfs -fstype=nfs,rw 192.168.1.110:/export/nfs
systemctl restart autofs
→設定を適用します。
cat /proc/mounts | grep "/var/nfs"
/etc/auto.mount /var/nfs autofs rw,relatime,fd=6,pgrp=2220,timeout=300,minproto=5,maxproto=5,direct,pipe_ino=69741 0 0
→設定が見られることを確認します。
k8s masterクラスター側でいつでもnfsサーバ側のマウント領域を操作できるようになりました。
dev_user@k8s-master:~/script/pv-test$ ls -la /var/nfs/pv0001/
合計 28
drwxrwxrwt 7 root root 4096 2月 8 23:32 .
drwxr-xr-x 3 root root 4096 2月 8 16:58 ..
drwxrwxrwt 2 root root 4096 2月 8 23:19 .ICE-unix
drwxrwxrwt 2 root root 4096 2月 8 23:19 .Test-unix
drwxrwxrwt 2 root root 4096 2月 8 23:19 .X11-unix
drwxrwxrwt 2 root root 4096 2月 8 23:19 .XIM-unix
drwxrwxrwt 2 root root 4096 2月 8 23:19 .font-unix
-rw-r--r-- 1 root root 0 2月 8 23:32 test
トラブルシューティング
timed out waiting for the condition
という内容のメッセージが確認できます。
この場合、クライアントからnfsサーバに対して通信が許可されているか確認します。
手っ取り早く確認する方法としてdescribeコマンドで表示される以下コマンドを実行します。
マウント先は確認として /tmp
を使用しています。
mount -t nfs 192.168.1.110:/export/nfs/pv0001 /tmp
Mounting command: mount
Mounting arguments: -t nfs 192.168.1.110:/export/nfs/pv0001 /var/lib/kubelet/pods/dec52547-a80b-4216-b273-88a1cf2d3daa/volumes/kubernetes.io~nfs/pv0001
kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-pv-test-centos8-7675596dff-nxb8w 0/1 ContainerCreating 0 22m
kubectl describe pod/centos-pv-test-centos8-7675596dff-nxb8w
・
・[中略]
・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 22m default-scheduler Successfully assigned default/centos-pv-test-centos8-7675596dff-nxb8w to k8s-node-a
Warning FailedMount 6m50s (x5 over 20m) kubelet Unable to attach or mount volumes: unmounted volumes=[centos8-persistent-storage], unattached volumes=[default-token-46xm2 centos8-persistent-storage]: timed out waiting for the condition
Warning FailedMount 92s (x9 over 20m) kubelet MountVolume.SetUp failed for volume "pv0001" : mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t nfs 192.168.1.110:/export/nfs/pv0001 /var/lib/kubelet/pods/dec52547-a80b-4216-b273-88a1cf2d3daa/volumes/kubernetes.io~nfs/pv0001
Output: mount.nfs: Connection timed out
Warning FailedMount 2s (x5 over 18m) kubelet Unable to attach or mount volumes: unmounted volumes=[centos8-persistent-storage], unattached volumes=[centos8-persistent-storage default-token-46xm2]: timed out waiting for the condition
-v
オプションを追加で付加しマウントしていみると、timeoutしていることが確認できます。
mount -v -t nfs 192.168.1.110:/export/nfs/pv0001 /tmp/
mount.nfs: timeout set for Tue Feb 8 22:15:19 2022
mount.nfs: trying text-based options 'vers=4.2,addr=192.168.1.110,clientaddr=192.168.1.108'
nfsサーバ側でポートが空いているか確認します。
nmapで確認するとfilteredになっています。
openになっていないといけないのでnfsサーバ側を確認したところ、firewalldが有効になっており通信が届かない状態でしたので停止したところ、openになり無事にマウントできました。
nmap -v -sT 192.168.1.110 -p 2049
PORT STATE SERVICE
2049/tcp filtered nfs
nmap -v -sT 192.168.1.110 -p 111
PORT STATE SERVICE
111/tcp filtered rpcbind
まとめ
Kubernetesストレージについて触れてみました。
難しいですが、慣れるまで辛抱です。
参考文献
KubernetesでNFSを利用してPersistentStorageを準備する
CentOS 8 でNFSサーバー構築 – LIGLOG INFRA JOURNAL
KubernetesのConfig&Storageリソース(その2)
ディスカッション
コメント一覧
まだ、コメントがありません