IT기술/쿠버네티스 (k8s)

RKE2 스토리지 완벽 가이드: 로컬부터 분산 스토리지까지 모든 환경 대응 전략

후스파 2025. 7. 11. 17:29
반응형

RKE2 클러스터에서 안정적인 스토리지를 구성하는 방법을 단계별로 알려드립니다. 로컬 스토리지부터 클라우드 볼륨까지, 모든 환경에 맞는 설정 전략을 알아봅니다.


StorageClass 생성: 동적 프로비저닝의 시작

RKE2는 local-path-provisioner를 기본 제공합니다. 아래 YAML로 커스텀 StorageClass를 생성하세요.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rke2-local
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
allowVolumeExpansion: true
parameters:
  nodePath: "/var/lib/rancher/rke2/storage"

적용

kubectl apply -f local-storageclass.yaml

# StorageClass 확인
kubectl get storageclass
kubectl describe storageclass rke2-local

주요 설정 옵션

  • WaitForFirstConsumer: Pod가 스케줄링된 노드에 PV 생성
  • reclaimPolicy: Delete: PVC 삭제 시 PV도 함께 삭제
  • allowVolumeExpansion: 볼륨 크기 동적 확장 허용

주의: /var/lib/rancher/rke2/server/local-path가 기본 저장 경로

local-path-provisioner 설정 커스터마이징

# ConfigMap으로 저장 경로 변경
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
      "nodePathMap": [
        {
          "node": "DEFAULT_PATH_FOR_NON_LISTED_NODES",
          "paths": ["/opt/local-path-provisioner"]
        }
      ]
    }
  setup: |-
    #!/bin/sh
    set -eu
    mkdir -m 0777 -p "$VOL_DIR"
  teardown: |-
    #!/bin/sh
    set -eu
    rm -rf "$VOL_DIR"

동적 프로비저닝: PVC로 간편하게

PVC 생성 시 StorageClass를 지정하면 자동으로 PV가 생성됩니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
  namespace: default
spec:
  storageClassName: rke2-local
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

확인

kubectl apply -f dynamic-pvc.yaml
kubectl get pvc dynamic-pvc
kubectl get pv

# PVC 상세 정보 확인
kubectl describe pvc dynamic-pvc

테스트 Pod 배포

apiVersion: v1
kind: Pod
metadata:
  name: storage-test
spec:
  containers:
  - name: test-container
    image: nginx:alpine
    volumeMounts:
    - name: test-volume
      mountPath: /data
    command: ["/bin/sh"]
    args: ["-c", "echo 'Hello RKE2 Storage' > /data/test.txt && tail -f /dev/null"]
  volumes:
  - name: test-volume
    persistentVolumeClaim:
      claimName: dynamic-pvc
# 테스트 실행
kubectl apply -f storage-test-pod.yaml
kubectl exec storage-test -- cat /data/test.txt

# 데이터 영속성 테스트
kubectl delete pod storage-test
kubectl apply -f storage-test-pod.yaml
kubectl exec storage-test -- cat /data/test.txt  # 데이터 유지 확인

정적 프로비저닝: 수동 PV 관리

NFS나 외부 스토리지를 사용할 때 유용합니다.

NFS 예시

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /data/nfs
    server: 192.168.1.100
  mountOptions:
    - nfsvers=4.1
    - hard
    - intr

HostPath 예시

apiVersion: v1
kind: PersistentVolume
metadata:
  name: hostpath-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  hostPath:
    path: "/mnt/data"
    type: DirectoryOrCreate
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker-node-1

PVC 바인딩

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: static-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  volumeName: hostpath-pv
  storageClassName: ""  # 정적 바인딩을 위해 빈 값

고급 구성: Longhorn & OpenEBS

분산 스토리지 솔루션으로 고가용성 보장

Longhorn 설치

# Longhorn 설치
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultDataPath="/var/lib/longhorn"

# 설치 확인
kubectl -n longhorn-system get pods
kubectl -n longhorn-system get svc

Longhorn StorageClass 설정

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-ssd
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fromBackup: ""
  diskSelector: "ssd"
  nodeSelector: "storage"

OpenEBS 구성

# OpenEBS 설치
helm repo add openebs https://openebs.github.io/charts
helm repo update
helm install openebs --namespace openebs openebs/openebs \
  --set engines.replicated.mayastor.enabled=false \
  --set openebs-crds.csi.volumeSnapshots.enabled=false \
  --create-namespace

# 기본 StorageClass 설정
kubectl patch storageclass openebs-hostpath \
  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: openebs-hostpath
  annotations:
    openebs.io/cas-type: local
    cas.openebs.io/config: |
      - name: StorageType
        value: "hostpath"
      - name: BasePath
        value: "/var/openebs/local"
provisioner: openebs.io/local
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

클라우드 스토리지 통합

AWS EBS CSI Driver

# AWS EBS CSI Driver 설치
kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.25"

# StorageClass 생성
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Azure Disk CSI Driver

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azure-disk-premium
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS
  cachingmode: ReadOnly
  kind: Managed
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

문제 해결 필수 체크리스트

증상 원인 해결책
PVC "Pending" 상태 StorageClass 미설정 kubectl get storageclass 확인
PV 바인딩 실패 용량 불일치 PVC/PV 스펙 일치 확인
접근 권한 오류 SELinux·파일 권한 문제 chmod 777 또는 SELinux 비활성화
디스크 공간 부족 노드 저장 공간 한계 df -h로 디스크 사용량 점검
Mount 실패 노드 간 스토리지 불일치 volumeBindingMode: WaitForFirstConsumer 설정

상세 트러블슈팅

# PVC 상태 진단
kubectl describe pvc 
kubectl get events --sort-by=.metadata.creationTimestamp

# PV 상태 확인
kubectl get pv
kubectl describe pv 

# StorageClass 확인
kubectl get storageclass
kubectl describe storageclass 

# 노드 스토리지 상태
kubectl get nodes -o wide
kubectl describe node 

# local-path-provisioner 로그 확인
kubectl -n local-path-storage logs -l app=local-path-provisioner

# Longhorn 상태 확인 (설치된 경우)
kubectl -n longhorn-system get pods
kubectl -n longhorn-system logs -l app=longhorn-manager

성능 최적화

# 디스크 I/O 성능 테스트
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: disk-test
spec:
  containers:
  - name: disk-test
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "dd if=/dev/zero of=/data/test bs=1M count=1000; sync; echo 'Write test completed'"]
    volumeMounts:
    - name: test-volume
      mountPath: /data
  volumes:
  - name: test-volume
    persistentVolumeClaim:
      claimName: dynamic-pvc
EOF

# 결과 확인
kubectl logs disk-test

마무리

RKE2의 스토리지 관리는 동적 프로비저닝으로 시작해 Longhorn/OpenEBS로 확장하는 것이 최적입니다. 첫 단계는 기본 local-path StorageClass 테스트부터 시작하세요. 복잡한 환경에서는 반드시 volumeBindingMode: WaitForFirstConsumer를 설정해 노드 선택 오류를 방지하시길 추천합니다.

핵심 포인트:

  • local-path-provisioner 기본 제공으로 즉시 사용 가능
  • 동적 프로비저닝으로 PVC 생성 시 자동 PV 할당
  • Longhorn/OpenEBS 통합으로 분산 스토리지 구현
  • 클라우드 CSI 드라이버 지원으로 하이브리드 환경 최적화
  • volumeBindingMode 설정으로 노드 선택 최적화

RKE2의 스토리지 기능을 통해 상태 저장 애플리케이션을 안정적으로 운영하고, 데이터 영속성과 고가용성을 동시에 확보할 수 있습니다.

반응형