[k8s] NFS로 온프레미스 Persistent Volume 구성하기
선행 포스트
https://blog.naver.com/sssang97/223096927913
클라우드 환경에서는 S3 같은 스토리지 서비스에 기반해서 볼륨을 쉽게 할당해서 쓸 수 있지만, 온프레미스 환경에서는 여러가지 번잡한 처리와 관리가 필요하다.
온프레미스 환경에서는 볼륨을 동적으로 조절하면서 내어주는 그런 백그라운드 시스템을 띄워야 하는데, 여기에도 방법이 여러가지 존재한다.
NFS, ceph, minio 등등... 뭐 많은데 여기서는 NFS를 이용해서 볼륨 환경을 구성해보겠다.
가장 고전적인 구성 방법이다.
고가용성과 분산 저장 같은걸 원한다면 rook-ceph 같은 방법을 사용해야 한다.
NFS 서버 구성
NFS 기반으로 스토리지를 구성하려면, 먼저 쿠버네티스와 별개로 NFS 서버를 구성해야 한다.
이건 보통 마스터 노드 언저리에 많이 둔다.
서버를 먼저 설치하고
sudo apt-get install nfs-kernel-server -y

NFS에서 사용할 디렉터리를 정한다.
sudo mkdir /home/nfs

그리고 그걸 exports라는 특수한 정의 파일에 추가한다.
sudo vi /etc/exports
/home/nfs 192.168.1.2(rw,sync,no_root_squash,no_subtree_check)
방금 만든 경로와 현재 서버의 노출 IP를 넣어줘야 한다.
그리고 다음 명령을 사용해서 nfs 서버에 적용하고, 시작한다.
sudo exportfs -a
sudo systemctl restart nfs-kernel-server.service
sudo systemctl status nfs-kernel-server.service

그리고 showmount로 잘 동작하는지 핑을 날려서,
showmount -e 192.168.1.2
이런식으로 잘 찍히면 잘 된 것이다.
이제 k8s로 돌아가서 볼륨 설정을 해보자.
스토리지 클래스 만들기
스토리지 클래스를 먼저 정의해주겠다.
이걸 만들어야지 복잡한 레이블 매칭 없이 이 볼륨을 쓰겠다고 간편하게 지정할 수 있고, 시작/종료/제거 시의 처리도 어느정도 핸들링할 수 있다.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
volumeBindingMode: Immediate
reclaimPolicy: Retain
- name: nfs는 클래스의 이름을 nfs로 하겠다는 뜻이다.
- volumeBindingMode: Immediate는 Claim을 생성했을때 바로 저장공간을 할당하겠다는 뜻이다. 저걸 WaitForFirstConsumer로 하면 실제로 Claim을 Pod에 붙이는 시점에 저장공간을 할당하도록 미룬다.
- reclaimPolicy는 삭제될때 기존 리소스를 어떻게 할지 정하는 부분이다. Retain은 유지다.

그리고 적당히 띄우면 된다.
Persistent Volume 만들기
이제 본격적으로 구성했던 NFS 서버를 볼륨으로 엮어보자.
이전 포스트에도 언급했지만, 볼륨은 일종의 스토리지 풀이다.
최고관리자가 한번 크게 잡아서 할당해놓으면, 이후의 사용자들이 Claim이라는 단위로 공간을 조금씩 할당받아 사용하는 형태로 쓰게 되는 것이다.
다음과 같이 정의할 수 있다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
storageClassName: nfs
capacity:
storage: 50Gi # 할당 용량
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.1.2 # NFS 서버의 IP
path: /home/nfs
할당 용량이나 NFS 서버 엔드포인트, path 정도만 상황에 맞춰서 조정해주면 된다.

그렇다.
Persistent Volume Claim 만들기
이번에는 만들어놨던 Persistent Volume을 기반으로 실제 Claim을 할당받아 사용해보자.
비교적 간단한 편이다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc-example
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 3Gi
storageClassName: nfs
claim 자체의 이름을 지정해주고, storage 사이즈 넣고, storageClassName 맞춰주면 끝이다.
그렇게 생성이 되면 이렇게 뜰 것이다.
용량이 50Gi로 잡히는데, 현재로서는 이렇게 표시되는게 맞다.
그리고 pv에도 사용중임을 뜻하는 Status:Bound가 설정될 것이다.
Pod에서 Persistent Volume Claim 갖다쓰기
이제 본격적으로 서버를 띄워서 볼륨과 클레임을 사용해보자.
내가 예전에 말아놨던 이미지로 테스트를 해보겠다.
저건 노드 서버를 하나 띄우는데, /var/log/nodejs 경로에 계속 로그를 쓰는 구성을 갖고 있다.
apiVersion: v1
kind: Pod
metadata:
name: log-daemon
spec:
volumes:
- name: nfs-mount
persistentVolumeClaim:
claimName: nfs-pvc-example
containers:
- name: container-name
image: myyrakle/log-daemon-for-test
volumeMounts:
- name: nfs-mount
mountPath: /var/log/nodejs
이러면 방금 만든 Claim을 볼륨으로 등록하고, 컨테이너 이미지에도 마운트해서 /var/log/nodejs 경로에 파일이 쓰일 때마다 nfs에도 쓰이도록 한다.
그렇게 해서 띄워보면

서버 자체에는 당연히 로그가 뜰 것이고

NFS를 구성했던 디렉터리에도 로그 파일이 누적될 것이다.
이건 당연히 컨테이너와는 별개로 영속적으로 저장된다.
참조
https://docs.openshift.com/container-platform/4.8/storage/persistent_storage/persistent-storage-nfs.html
https://kubernetes.io/ko/docs/concepts/storage/storage-classes/