나는 단일 노드로 쿠버네티스를 구성하고 있었으며 Volume 은 hostPath PV
을 사용하고 있었다. 그러다 분산 로드밸런싱을 위해 노드 하나를 새로 추가하였는데 문제가 발생했다. 새로운 노드에서 기존의 노드의hostPath PV
를 읽지 못하는 현상이 생겼다. 찾아보니 NFS PV
을 사용하면 다중 노드에서 읽고 쓰는 것이 가능하였기에 NFS PV
를 사용하는 방법으로 문제를 해결하였다. 이와 관련해 NFS 를 사용하는 가이드를 작성하여 내용을 공유하려 한다.
Worker Node
에 NFS PV
를 생성하고 Master Node
의 Pod
에서 NFS PV
를 이용할 것입니다.
사전 준비물 : Worker Node 와 Master Node 가 준비되어 있어야 한다.
kubeadm 을 통해 Worker Node 와 Master Node 생성하는 방법
CIDR
: 192.168.0.0 / 8
Master Node
: 192.168.0.213
/ Ubuntu 20.04
Worker Node
: 192.168.0.182
/ Ubuntu 22.04
$ sudo apt-get update
$ sudo apt-get install nfs-common nfs-kernel-server -y
# 폴더를 생성합니다.
sudo mkdir -p /data/nfs1
# 디렉토리의 소유자를 nobody로, 그룹을 nogroup으로 변경합니다.
# nobody와 nogroup은 일반적으로 시스템에서 사용되는 특별한 사용자와 그룹입니다.
sudo chown nobody:nogroup /data/nfs1
# 그룹에 쓰기, 읽기, 실행, 삭제 권한을 부여합니다.
sudo chmod g+rwxs /data/nfs1
폴더를 외부에 노출해서 마스터 노드
가 접근 가능하도록 변경한다.
# 특정 네트워크에 접근 설정
## 192.168.0.0/8 => 마스터 노드와 워커 노드가 공유하고 있는 Private Network 의 CIDR
# /{export할 folder명} {허용할 client ip대역}(client에게 줄 권한)
$ echo -e "/data/nfs1\t192.168.0.0/8(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
# NFS 서버에서 내보낼 파일 시스템을 설정합니다. 이 명령을 사용하여 NFS 서버가 클라이언트에게 공유 디렉토리를 제공합니다.
$ sudo exportfs -av
===
/data/nfs1 192.168.0.0/8
# rw: 읽기 쓰기 가능
# ro: 읽기만 가능
# sync: filesystem변경시 즉시 client동기화
# no_root_squash: client와 server의 root 동일화
# subtree_check: 공유 디렉토리는 서브디렉토리를 가질 수 있음
# client가 특정 file 요청시 server는 subtree checking을 실행해 sub dir까지 탐색, client가 요청한 file의 위치 확인
sudo systemctl restart nfs-kernel-server
sudo systemctl status nfs-kernel-server
# show for localhost
$ /sbin/showmount -e localhost
===
Export list for 127.0.0.1:
/data/nfs1 192.168.0.0/8
NFS 를 소비하는 노드는 모두 NFS Client 패키지
를 설치해야 합니다.
# on Debian/Ubuntu based nodes
sudo apt update
sudo apt install nfs-common -y
NFS 를 제공하는 워커 노드에 마스터 노드가 접근이 가능한 지 확인한다.
# 마스터 노드에서 진행 (192.168.0.182 는 워커 노드의 IP 이다.)
$ /sbin/showmount -e 192.168.0.182
===
Export list for 192.168.0.182:
/data/nfs1 192.168.0.0/8
nfs 을 사용하는 PV 를 생성합니다.
192.168.0.182
는 nfs 를 노출중인 워커노드
의 IP 입니다.
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-test-pv
spec:
capacity:
storage: 10Gi # NFS 서버의 용량에 따라 조정
volumeMode: Filesystem
accessModes:
- ReadWriteMany # 여러 파드에서 읽기 및 쓰기 가능하도록 설정
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data/nfs1 # NFS 서버의 공유 경로
server: 192.168.0.182 # NFS 서버의 주소
# pv 적용
$ kubectl apply -f pv.yaml
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-test-pvc
spec:
accessModes:
- ReadWriteMany
volumeName: nfs-test-pv # 위에서 생성한 pv 의 이름
resources:
requests:
storage: 10Gi # 필요한 스토리지 용량
# pvc 적용
$ kubectl apply -f pvc.yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: nfs-volume
mountPath: /mnt/nfs # 파드 내에서 NFS를 마운트할 경로
volumes:
- name: nfs-volume
persistentVolumeClaim:
claimName: nfs-test-pvc # 위에서 생성한 PVC 이름
# pvc 적용
$ kubectl apply -f pod.yaml
# Pod 에서 nfs 폴더에 파일 쓰기
$ kubectl exec -it pods/nfs-pod -- sh -c "echo \"from pod\" > /mnt/nfs/message.txt"
# Worker Node 의 터미널을 통해 읽기
$ cat /data/nfs1/message.txt
===
from pod
테스트가 끝났으면 사용했던 리소스를 제거해줍시다.
$ kubectl delete pod nfs-pod
$ kubectl delete pvc nfs-test-pvc
$ kubectl delete pv nfs-test-pv