파드가 재시작돼도 데이터를 유지하려면 영구 스토리지가 필요합니다. 온프레미스 클러스터에서 가장 손쉬운 방법 중 하나가 NFS 동적 프로비저닝이에요. StorageClass를 만들어두면 PVC 요청이 올 때마다 NFS 서버에 디렉토리가 자동으로 생기고 PV가 붙습니다.
사전 준비
클러스터 내 모든 노드에 NFS 클라이언트 패키지가 있어야 마운트가 됩니다. 이게 없으면 뒤에서 마운트 오류가 납니다.
apt-get install -y nfs-common
그리고 NFS 서버의 export 옵션에 권한 관련 설정을 넣어둡니다.
/k8s 10.8.8.0/24(rw,sync,no_subtree_check,no_root_squash)
no_root_squash 는 컨테이너가 root로 파일을 다룰 때 권한 문제를 줄여줍니다.
StorageClass
프로비저너와 함께 StorageClass를 정의합니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true"
archiveOnDelete 는 PV가 삭제될 때 데이터를 아카이브(보존)할지 결정합니다.
true: 데이터 보존 (실수로 삭제해도 남음)false: 완전 삭제 (복구 불가)
데이터가 중요하다면 반드시 true 로 두세요. Deployment 프로비저너의 env 값과 StorageClass 설정이 일치해야 정상 동작합니다.
프로비저너를 여러 개 쓰기
기존 NFS가 용량이 부족해 별도 저장장치를 붙였고, 그쪽에 저장하는 프로비저너를 따로 두고 싶을 때가 있습니다. 이때 프로비저너 이름이 중복되면 정상 동작하지 않으니 다른 이름을 씁니다.
provisioner: k8s-sigs.io/nfs-02-big-subdir-external-provisioner
동일한 절차로 이름만 다르게 해서 하나 더 만들면, PVC의 storageClassName 으로 어느 저장소에 담길지 골라 쓸 수 있어요.
권한 오류 대처
NFS에 PVC를 붙였을 때 이런 오류를 자주 만납니다.
chown: changing ownership of '/var/lib/mysql/': Operation not permitted
NFS 마운트 디렉토리의 소유자(보통 nobody, UID 65534) 때문입니다. 파드의 securityContext 에 해당 UID를 지정하면 해결됩니다.
securityContext:
runAsUser: 65534 # /etc/passwd에서 nobody UID 확인
그래도 안 되면 최후의 수단으로 PV 디렉토리에 chmod 777 을 주기도 하지만, 권한은 가능한 한 좁게 유지하는 게 원칙입니다.
StatefulSet에서 주의할 점
StatefulSet의 PVC는 Deployment를 내려도 살아남습니다. storageClassName 만 바꿔 다시 올리면 자꾸 이전 PVC에 붙는데, 이건 volumeClaimTemplates 의 이름으로 구분하기 때문이에요. 새 PVC를 만들고 싶다면 템플릿 이름을 바꿔주면 됩니다.