퍼시스턴트볼륨의 접근 모드를 ReadWriteOncePod로 변경하기

이 페이지에서는 기존 퍼시스턴트볼륨(PersistentVolume)의 접근 모드를 ReadWriteOncePod로 변경하는 방법에 대해 설명한다.

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: v1.22.

버전 확인을 위해서, 다음 커맨드를 실행 kubectl version.

참고:

ReadWriteOncePod 접근 모드는 Kubernetes v1.29 릴리스에서 안정(stable) 단계로 졸업했다. v1.29보다 이전 버전의 Kubernetes를 실행 중인 경우, 기능 게이트(feature gate)를 활성화해야 할 수도 있다. 사용 중인 Kubernetes 버전의 문서를 확인한다.

참고:

ReadWriteOncePod 접근 모드는 CSI 볼륨에서만 지원된다. 이 볼륨 접근 모드를 사용하려면 다음 CSI 사이드카(sidecar) 를 아래 버전 이상으로 업데이트해야 한다.

ReadWriteOncePod를 사용해야 하는가?

Kubernetes v1.22 이전에는 스토리지에 단일 쓰기 접근이 필요한 워크로드에 대해 퍼시스턴트볼륨 접근을 제한하기 위해 ReadWriteOnce 접근 모드가 주로 사용되었다. 그러나 이 접근 모드에는 한계가 있었다. 볼륨 접근을 단일 노드로만 제한했기 때문에, 동일한 노드 위의 여러 파드가 동시에 같은 볼륨에 읽기/쓰기를 할 수 있었다. 이는 데이터 안전을 위해 엄격한 단일 쓰기 접근이 필요한 애플리케이션에 위험을 초래할 수 있다.

워크로드에서 단일 쓰기 접근 보장이 중요하다면, 볼륨을 ReadWriteOncePod로 마이그레이션하는 것을 고려해야 한다.

기존 퍼시스턴트볼륨 마이그레이션

기존 퍼시스턴트 볼륨이 있다면, ReadWriteOncePod를 사용하도록 마이그레이션할 수 있다. ReadWriteOnce에서 ReadWriteOncePod로의 마이그레이션만 지원된다.

이 예시에서는 이미 "cat-pictures-pvc" 퍼시스턴트볼륨에 바인딩된 ReadWriteOnce "cat-pictures-pv" 퍼시스턴트볼륨클레임(PersistentVolumeClaim)과, 해당 퍼시스턴트볼륨클레임을 사용하는 "cat-pictures-writer" 디플로이먼트(Deployment)가 존재한다고 가정한다.

참고:

스토리지 플러그인이 동적 프로비저닝(Dynamic Provisioning) 을 지원하는 경우, "cat-picutres-pv" 가 자동 생성되지만 이름이 다를 수 있다. 퍼시스턴트볼륨의 이름을 확인하려면 다음 명령어를 실행한다.

kubectl get pvc cat-pictures-pvc -o jsonpath='{.spec.volumeName}'

변경하기 전에 PVC를 확인할 수 있다. 매니페스트를 로컬에서 확인하거나, kubectl get pvc <pvc-이름> -o yaml 명령어를 실행한다. 출력 결과는 다음과 비슷하다.

# cat-pictures-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: cat-pictures-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

해당 퍼시스턴트볼륨클레임에 의존하는 디플로이먼트 예시는 다음과 같다.

# cat-pictures-writer-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cat-pictures-writer
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cat-pictures-writer
  template:
    metadata:
      labels:
        app: cat-pictures-writer
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        volumeMounts:
        - name: cat-pictures
          mountPath: /mnt
      volumes:
      - name: cat-pictures
        persistentVolumeClaim:
          claimName: cat-pictures-pvc
          readOnly: false

첫 번째 단계로, 퍼시스턴트볼륨의 spec.persistentVolumeReclaimPolicy를 편집하여 Retain 으로 설정해야 한다. 이렇게 하면 대응하는 퍼시스턴트볼륨클레임을 삭제했을 때 퍼시스턴트볼륨이 삭제되지 않는다.

kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

다음으로, 마이그레이션하려는 퍼시스턴트볼륨에 바인딩된 퍼시스턴트볼륨클레임을 사용하는 모든 워크로드를 중지하고, 퍼시스턴트볼륨클레임을 삭제해야 한다. 마이그레이션이 완료될 때까지 볼륨 크기 조정 등 퍼시스턴트볼륨클레임을 변경하지 않는다.

완료되면, 퍼시스턴트볼륨클레임을 재생성할 때 바인딩될 수 있도록 퍼시스턴트볼륨의 spec.claimRef.uid 를 초기화한다.

kubectl scale --replicas=0 deployment cat-pictures-writer
kubectl delete pvc cat-pictures-pvc
kubectl patch pv cat-pictures-pv -p '{"spec":{"claimRef":{"uid":""}}}'

이후, 퍼시스턴트볼륨의 유효한 접근 모드 목록을 ReadWriteOncePod(만)로 교체한다.

kubectl patch pv cat-pictures-pv -p '{"spec":{"accessModes":["ReadWriteOncePod"]}}'

참고:

ReadWriteOncePod 접근 모드는 다른 접근 모드와 함께 사용할 수 없다. 업데이트 시 퍼시스턴트볼륨의 접근 모드가 ReadWriteOncePod 하나뿐인지 확인한다. 그렇지 않으면 요청이 실패한다.

다음으로, 퍼시스턴트볼륨클레임을 수정하여 ReadWriteOncePod를 유일한 접근 모드로 설정해야 한다. 또한 퍼시스턴트볼륨클레임의 spec.volumeName을 퍼시스턴트볼륨의 이름으로 설정하여 해당 퍼시스턴트볼륨에 바인딩되도록 해야 한다.

완료되면, 퍼시스턴트볼륨클레임을 재생성하고 워크로드를 시작할 수 있다.

# 중요: 적용하기 전에 cat-pictures-pvc.yaml에서 PVC를 편집해야 합니다. 다음 사항을 변경하세요:
# - ReadWriteOncePod를 유일한 접근 모드로 설정
# - spec.volumeName을 "cat-pictures-pv"로 설정

kubectl apply -f cat-pictures-pvc.yaml
kubectl apply -f cat-pictures-writer-deployment.yaml

마지막으로, 이전에 변경했다면 퍼시스턴트볼륨의 spec.persistentVolumeReclaimPolicy를 편집하여 다시 Delete로 되돌릴 수 있다.

kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}'

다음 내용