[GCP] GKE에서 PD 이용한 PV 할당하기

Seunghyun Moon·2024년 1월 13일
0

Kubernetes

목록 보기
3/3

오늘의 이슈

기본적으로 container는 stateless application에 적합합니다. stateful한 database를 container로 사용하려면 데이터를 어떻게 저장하는지가 관건인데 kubernetes에서는 PV(persistent volumes)를 통해 방법을 제시합니다.

개념


Pod의 spec.volumes[].persistentVolumeClaime
에서 pvc를 지정합니다.
PVC, PV를 용량, rw여부 등에 따라 설정을 합니다.
어떤 Storage Class를 사용하느냐에 따라서 kubernetes cluster 내에 addon으로 추가 설치가 필요할 수도 있습니다.

GKE 의 경우에는 gcp의 pd에 대해서 GKE 버전 1.18.10-gke.2100 이상 또는 1.19.3-gke.2100 이상 부터는 기본 사용 설정돼있습니다.
설정 예시
클러스터 생성 시

gcloud container clusters create CLUSTER-NAME \
    --addons=GcePersistentDiskCsiDriver \
    --cluster-version=VERSION

기존 클러스터에서

gcloud container clusters update CLUSTER-NAME \
   --update-addons=GcePersistentDiskCsiDriver=ENABLED

disable

gcloud container clusters update CLUSTER-NAME \
   --update-addons=GcePersistentDiskCsiDriver=ENABLED
kind: Pod
apiVersion: v1
metadata:
  name: POD_NAME
spec:
  volumes:
    - name: VOLUME_NAME
      persistentVolumeClaim:
        claimName: PV_CLAIM_NAME
  containers:
    - name: CONTAINER_NAME
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: VOLUME_NAME
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: PV_NAME
spec:
  storageClassName: "STORAGE_CLASS_NAME"
  capacity:
    storage: DISK_SIZE
  accessModes:
    - ReadWriteOnce
  claimRef:
    namespace: default
    name: PV_CLAIM_NAME
  csi:
    driver: pd.csi.storage.gke.io
    volumeHandle: DISK_ID
    fsType: FS_TYPE
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  namespace: default
  name: PV_CLAIM_NAME
spec:
  storageClassName: "STORAGE_CLASS_NAME"
  volumeName: PV_NAME
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: DISK_SIZE

시작

pvc 생성 from scratch

  • 대부분의 경우 PersistentVolume 객체를 직접 구성하거나 Compute Engine 영구 디스크를 만들 필요가 없습니다. 대신 PersistentVolumeClaim을 만들면 Kubernetes가 영구 디스크를 자동으로 프로비저닝합니다.
  • PersistentVolumeClaim이 StorageClassName을 지정하지 않으면 기본 StorageClass가 사용됩니다. 제공된 기본 StorageClass를 자체 StorageClass로 대체할 수 있습니다.
  • yaml 파일 내용
apiVersion: v1
kind: Pod
metadata:
  name: web-server
spec:
  containers:
   - name: web-server
     image: nginx
     volumeMounts:
       - mountPath: /var/lib/www/html
         name: mypvc
  volumes:
   - name: mypvc
     persistentVolumeClaim:
       claimName: podpvc
       readOnly: false
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: podpvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: standard-rwo
  resources:
    requests:
      storage: 6Gi

이렇게 생성하면
pv 까지 자동으로 생성됩니다.

컴퓨팅 > 스토리지에 가보면 pd가 생성된걸 볼 수 있습니다.

pvc 를 삭제하면 pd까지 삭제되는걸 확인할 수 있습니다.

참고
pv로 생성된 pd의 스냅샷을 생성하면 kubectl delete 명령어로 삭제를 해도 pv는 삭제되지 않습니다.

desc = Failed to delete disk: googleapi: Error 400: The disk resource 'projects/hivelab-prj-1/zones/asia-northeast3-b/disks/pvc-bd54ff2c-f5bd-482f-98cf-498b05044018' is already being used by 'projects/hivelab-prj-1/zones/asia-northeast3-b/instantSnapshots/instant-snapshot-1', resourceInUseByAnotherResource

기존 pd에 연결

  • 기존 pd에 연결하고, pv 선언 후 pvc, pod와 연결합니다.
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-demo
spec:
  storageClassName: "standard-rwo"
  capacity:
    storage: 15Gi
  accessModes:
    - ReadWriteOnce
  claimRef:
    namespace: default
    name: pvc-demo
  csi:
    driver: pd.csi.storage.gke.io
    volumeHandle: projects/hivelab-prj-1/zones/asia-northeast3-a/disks/demo-pd
    fsType: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  namespace: default
  name: pvc-demo
spec:
  storageClassName: "standard-rwo"
  volumeName: pv-demo
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 15Gi

배포가 되지 않았습니다.
kubectl describe pod 로 로그를 살펴봅니다.

AttachVolume.Attach failed for volume "pv-demo" : rpc error: code = Internal desc = Failed to Attach: failed cloud service attach disk call: googleapi: Error 400: Invalid value for field 'resource.source': 'https://compute.googleapis.com/compute/v1/projects/hivelab-prj-1/zones/asia-northeast3-a/disks/demo-pd'. Disk must be in the same zone as the instance.

정적으로 생성한 pd는 zone-a 였지만. 우리의 포드가 올라갈 노드는 zone-a,b,c 중에 어디에 배치될지 모릅니다. 그래서 볼륨 마운트에 실패합니다.


pd와 노드의 위치를 맞춰주니 pod가 제대로 구동됩니다.

이제 마운트한 볼륨에서 한 작업이 정말로 persistent 한지 확인합니다.

index.html 파일을 만듭니다.


kubernetes 오브젝트들을 삭제후 다시 만들고 아까 만든 파일의 경로로 가보면 우리가 만든 파일이 있는걸 볼 수 있습니다.

statefulset 사용

kubernetes는 stateful한 어플리케이션을 위해서 deployments와 유사하다고도 볼 수 있는 statefulset을 제공합니다.

  • PersistentVolumeClaim 템플릿을 각각 배포 또는 StatefulSet 같은 상위 수준 컨트롤러에서 사용할 수 있습니다.
  • deployments는 Stateless 애플리케이션을 위해 설계되었으므로 배포의 모든 복제본은 동일한 PersistentVolumeClaim을 공유합니다. 생성된 복제본 포드는 서로 동일하므로 ReadWriteMany 모드인 볼륨만 이 설정에서 작동할 수 있습니다.
  • StatefulSet은 복제본당 고유한 볼륨이 필요한 스테이트풀(Stateful) 애플리케이션 배포에 권장되는 방법입니다. StatefulSet을 PersistentVolumeClaim 템플릿과 함께 사용하면 각 복제본 포드에 연결된 고유한 PersistentVolumeClaim으로 자동 확장되는 애플리케이션을 사용할 수 있습니다.
    deployments vs statefulset 설명
    statefulset
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-demo
spec:
  selector:
    matchLabels:
      app: mysql-demo
  serviceName: "SERVICE_NAME"
  replicas: 3
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: mysql-demo
    spec:
      containers:
      - name: CONTAINER_NAME
        image: ...
        ports:
        - containerPort: 80
          name: PORT_NAME
        volumeMounts:
        - name: PVC_NAME
          mountPath: ...
  volumeClaimTemplates:
  - metadata:
      name: PVC_NAME
      annotations:
        ...
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi


참고
https://cloud.google.com/compute/docs/disks/persistent-disks?hl=ko
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes
https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver?hl=ko
https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/preexisting-pd?hl=ko
https://cloud.google.com/kubernetes-engine/docs/concepts/persistent-volumes?hl=ko

profile
I live fullest

0개의 댓글