[k8s 구축] 9. NFS 동적 프로바이저를 이용한 네트워크 PV 설정

k8s를 운영할 땐 네트워크 PV(Persistent Volume)를 통해 스토리지를 공유해 사용하는 것이 일반적이다.
이에 네트워크 PV를 구성하는 방법을 정리해본다.
Rocky Linux 9.5를 기준으로 작성하였다.

1. NFS 구축

네트워크 PV를 구축하는 방법은 다양하나 이 글에서는 NFS를 이용하기로 한다.
먼저 마스터 노드에 NFS 서버를 설치하자.

NFS로 공유할 디렉터리의 권한이 777임을 주의하자.
필자는 NFS에 접근 가능한 노드를 모두 신뢰하기에 세팅 편의를 위해 777 권한을 주었으나 썩 바람직한 방법은 아니다.

$ sudo dnf install nfs-utils -y
$ sudo systemctl enable nfs-server
$ sudo systemctl start nfs-server
$ sudo mkdir /storage/k8s
$ sudo chmod 777 /storage/k8s

이제 NFS로 공유할 디렉터리와 공유 대상 네트워크 대역을 입력한다.
필자의 k8s 워커 노드는 10.10.10.64/26 대역을 사용하므로 이를 적용하였다.
참고로 마스터 노드는 이 대역에 포함되지 않아도 무방하다.

$ sudo vim /etc/exports
> /storage/k8s 10.10.10.0/26(rw,sync,no_subtree_check)
$ sudo exportfs -arv
$ sudo systemctl restart nfs-server

이제 워커 노드에도 NFS 서버를 설치하면 준비는 끝이다.

$ sudo dnf install nfs-utils -y

2. nfs 동적 프로비저닝

nfs만을 사용하는 경우 존재하는 디렉터리만을 네트워크 PV로 사용할 수 있는 문제가 있다.
이를 해결하기 위해 nfs 동적 프로비저닝(nfs-subdir-external-provisioner) 도구를 설치한다. [Github]
이 도구를 사용하면 PVC(PV Claim, PV 요청)가 발생할 때 자동으로 PV가 생성된다.
이제 helm을 통해 동적 프로비저닝 도구를 설치해보자.

아래는 위에서 설정한 nfs 서버의 /k8s 디렉터리를 nfs-csi 이름으로 동적 프로비저닝하되
PVC가 삭제되면서 디렉터리를 아카이빙하지 않고 바로 삭제(archiveOnDelete)하는 명령어이다.
아래 명령어를 실행하면 nfs-csi라는 이름의 storageClass가 생성된다.

참고로 storageClass가 생성된 이후로 archiveOnDelete와 같은 파라미터는 수정이 불가능하며, storageClass 삭제 시 연결된 PV와 PVC도 모두 삭제된다는 점을 주의하자.

$ helm repo add nfs-subdir https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner
$ helm install nfs-provisioner nfs-subdir/nfs-subdir-external-provisioner \
  --set nfs.server=<NFS_SERVER_IP> \
  --set nfs.path=/k8s \
  --set storageClass.name=nfs-csi \
  --set storageClass.archiveOnDelete=false

3. 서비스 배포

서비스를 배포하면서 PVC를 함께 배포하면 PVC 이름대로 PV가 자동 생성된다.
예를 들어 다음 매니페스트 파일에서는 web-pvc 이름으로 1GiB의 PV가 생성될 것이다.
참고로 nfs의 경우 RWX(ReadWriteMany)를 지원하기에 여러 PVC가 하나의 PV를 공유해 사용할 수 있다.

아래 매니페스트 파일처럼 PVC를 배포하고 이 PVC를 이용해 Volume을 마운트하면 된다.

# temporary-webserver.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-pvc
spec:
  accessModes:
    - ReadWriteOnce  # 단일 노드 읽기/쓰기
  resources:
    requests:
      storage: 1Gi  # 1GB 스토리지 요청
  storageClassName: nfs-csi  # 기존에 생성한 nfs 프로바이저 이름

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
          volumeMounts:
            - name: web-storage
              mountPath: "/usr/share/nginx/html"  # 웹 콘텐츠 디렉토리
      volumes:
        - name: web-storage
          persistentVolumeClaim:
            claimName: web-pvc  # 위에서 정의한 PVC 참조

끝이다.

Series Navigation<< [k8s 구축] 8. 로컬 PV 설정[k8s 구축] 10. MySQL 구축 >>

댓글 남기기