파란하늘의 지식창고
반응형

docker container는 재시작시 모든 데이터가 초기화된다.
데이터를 유지하기 위해 기존에는 Volumes의 hostPath 설정을 통해 host의 디렉토리를 참조하여 사용하였었다.

mariadb를 사용하는 경우 기존 설정은 다음과 같았다

apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: mariadb-deployment 
  labels: 
    app: mariadb 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: mariadb 
  template: 
    metadata: 
      labels: 
        app: mariadb 
    spec: 
      containers: 
      - name: mariadb 
        image: mariadb 
        ports: 
        - containerPort: 3306 
        env: 
        - name: MYSQL_ROOT_PASSWORD 
          value: "root" 
        args: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"] 
        volumeMounts: 
        - name: mariadb-volume 
          mountPath: /var/lib/mysql 
      volumes: 
      - name: mariadb-volume 
        hostPath: 
          path: /mnt/f/dev/data/mariadb

https://kubernetes.io/ko/docs/concepts/storage/volumes/#hostpath
하지만 이는 좋은 사용 방법이 아니기 때문에 kubernetes가 제공하는 PersistentVolume, PersistentVolumeClain을 사용하도록 변경하려고 한다.
(또한 volumes의 hostPath의 경우 configMap을 통한 설정 제공 처리를 지원하지 않는다.)

PersistentVolume (PV)은 관리자가 제공하거나 Storage Class를 사용하여 동적으로 제공하는 cluster의 storage이다.
node가 cluster resource인 것처럼 PV도 cluster resource이다.
PV는 Volumes와 같은 volume plugin이지만 PV를 사용하는 각 pod와 별개의 lifecycle을 가진다.
이 API Object는 NFS, iSCI 또는 cloud-provider 별 storage system등 storage 구현에 대한 세부 정보를 관리한다.

PersistentVolumeClaim (PVC)은 사용자의 storage에 대한 요청이다.
pod와 비슷하다.
pod는 node resource를 사용하고 PVC는 PV resource를 사용한다.
pod는 특정 수준의 resource (cpu 및 memory)를 요청할 수 있다.
claim은 특정 크기 및 접근 모드를 요청할 수 있다.(예: ReadWriteOnce, ReadOnlyMany 또는 ReadWriteMany로 mount할 수 있음)

PVC를 사용하면 사용자가 추상화된 storage resource를 사용할 수 있지만 다른 문제들 때문에 PV가 필요한 경우가 일반적이다.
cluster 관리자는 사용자에게 해당 volume의 구현 방법에 대한 세부 정보를 제공하지 않고 크기와 접근 모드와는 다른 방식으로 다양한 PV를 제공할 수 있어야 한다.
이러한 요구에는 StorageClass resource가 있다.

위에 maraidb deployment에 설정했던 volumes를 PersistentVolume으로 만들면 다음과 같다.

apiVersion: v1 
kind: PersistentVolume 
metadata: 
  name: mariadb-pv 
  labels: 
    app: mariadb-pv 
spec:  
  storageClassName: ""
  capacity: 
    storage: 8Gi 
  accessModes: 
    - ReadWriteOnce 
  hostPath: 
    path: /mnt/f/dev/data/mariadb

PersistentVolume은 capacity와 accessMode를 명시해야 한다.

이제 이 PV를 요청하는 PersistentVolumeClaim을 만들어본다.

apiVersion: v1 
kind: PersistentVolumeClaim 
metadata: 
  name: mariadb-pvc 
spec:  
  volumeName: mariadb-pv
  storageClassName: ""
  accessModes: 
    - ReadWriteOnce 
  resources: 
    requests: 
      storage: 8Gi

PersistentVolumeClaim은 accessMode와 resources[storage]를 명시해야 한다.
PVC에서 사용할 PV를 volumeName으로 지정한다.

로컬에서 사용해보니 PV와 PVC는 storageClassName을 명시하지 않는 경우 기본 값이 각각 빈 값과 "local-path"값을 가지고 있었다.
(template을 인스턴스화 할 때 storageClass 이름을 제공하는 옵션임)
PV와 PVC의 storageClassName이 불일치하면 바인딩되지 않기 때문에 빈 값을 명기하여 사용하였다.

mariadb deployment의 기존 volumes의 hostPath 설정을 persistentVolumeClaim으로 변경한다.

apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: mariadb-deployment 
  labels: 
    app: mariadb 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: mariadb 
  template: 
    metadata: 
      labels: 
        app: mariadb 
    spec: 
      containers: 
      - name: mariadb 
        image: mariadb 
        ports: 
        - containerPort: 3306 
        env: 
        - name: MYSQL_ROOT_PASSWORD 
          value: "root" 
        args: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"] 
        volumeMounts: 
        - name: mariadb-volume 
          mountPath: /var/lib/mysql 
      volumes: 
      - name: mariadb-volume 
        persistentVolumeClaim: 
          claimName: mariadb-pvc

pvc를 만들때 bound할 pv를 찾는다.
만약 지정된 pv가 없으면 동적으로 pv를 생성하고 bound된다.
지정된 pv가 있는 pvc만 삭제하고 (pv는 그대로 둔채) 재생성하는 경우 기존 pvc를 bound한 pv가 새로 생성된 pvc를 bound하지 못한다.
pv의 claimRef를 null로 patch하는 방법이 있지만 단순하게 그냥 pvc 삭제/생성 시엔 pv도 같이 삭제/생성한다고 생각하는게 속 편할 것 같다.
https://stackoverflow.com/questions/50667437/what-to-do-with-released-persistent-volume

kubectl patch pv PV_NAME -p '{"spec":{"claimRef": null}}'
반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요