[Retry, k8s] 23. 컨피그 & 스토리지 API - 볼륨

Date:     Updated:

카테고리:

태그:


🔔 볼륨(Volume), 영구 볼륨(Persistent Volume), 영구 볼륨 클레임(PV Claim)의 차이


시작하기 전 선행 작업 및 확인해야할 내용
- https://revenge1005.github.io/kubernetes/ch03-6-1/
- https://revenge1005.github.io/kubernetes/ch03-6-2/
- https://revenge1005.github.io/kubernetes/ch03-6-3/


(1) 볼륨

  • 미리 준비된 사용 가능한 볼륨(호스트볼륨/nfs/iSCSi/Ceph) 등을 매니페스트에 직접 지정하여 사용할 수 있는 것이다.

  • 사용자가 설정된 볼륨을 사용할 수 있지만, 쿠버네티스에서 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 작업은 할 수 없다.

  • 매니페스트에서 볼륨 리소스를 생성하는 것도 불가능하다.


(2) 영구 볼륨

  • 영구 볼륨은 외부 영구 스토리지 시스템과 연계하여 신규 볼륨을 생성하거나 기존 볼륨을 삭제하는 등의 작업이 가능하다.

  • 구체적으로는 매니페스트에서 영구 볼륨 리소스를 별도도로 생성하는 형태다.

  • 영구 볼륨과 볼륨은 같은 플러그인을 제공한다.

  • 영구 볼륨 플로그인에서는 볼륨 생성 및 삭제 같은 라이프사이클을 처리할 수 있지만, 볼륨 플러그인의 경우에는 기존에 있는 볼륨만 사용할 수 있다.


(3) 영구 볼륨 클레임

  • 생성된 영구 볼륨 리소스를 할당하는 리소스

  • 영구 볼륨은 클러스터에 볼륨을 등록만 하기 때문에 실제 파드에서 사용하려면 영구 볼륨 클레임을 정의하고 사용해야 한다.

  • 동적 프로비저닝 기능을 사용한 경우에는 영구 볼륨 클레임이 사용된 시점에 영구 볼륨을 동적으로 생성할 수 있어 순서가 바뀌었다고 느낄 수도 있다.




(4) 볼륨

k8s에서는 볼륨을 추상화하여 파드와 느슨하게 결합된 리소스로 정의하고 있다.


📜 emptyDir

  • 파드가 노드에 할당될 때 생성되는 파드용 임시 디스크 영역으로, 파드가 노드에서 제거(또는 종료)되면 삭제된다.

  • emptyDir은 처음에 비어 있으며, 파드 내의 모든 컨테이너가 emptyDir 볼륨에 있는 동일한 파일을 읽고 쓸 수 있다.

  • 호스트 볼륨(컨테이너용 임시 디스크 영역)을 컨테이너 볼륨에 매핑하지만, 호스트의 임의 영역을 마운트하거나 호스트에 있는 파일을 참조할 수는 없다.

2222

【emptyDir 볼륨을 마운트하는 파드 예제】

$ cat <<EOF > sample-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
EOF


$ kubectl exec -it sample-emptydir -- df -h | grep /cache
/dev/mapper/ubuntu--vg-ubuntu--lv  9.8G  6.7G  2.6G  73% /cache

【용량 제한을둔 emptyDir 볼륨을 마운트하는 파드 예제】

  • emptyDir을 사용한 볼륨에 “emptyDir.sizeLimit”로 리소스 제한을 할 수 있다.
$ cat <<EOF > sample-emptydir-limit.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir-limit
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 128Mi
EOF


# 150MB 파일을 생성
$ kubectl exec -it sample-emptydir-limit -- dd if=/dev/zero of=/cache/dummy bs=1M count=150


# 할당된 영역에 대해 용량이 초과로 Evict(축출)되는 것을 확인할 수 있다.
$ kubectl get pod --watch
NAME                    READY   STATUS    RESTARTS   AGE
sample-emptydir-limit   1/1     Running   0          3m
sample-emptydir-limit   1/1     Evicted   0          3m41s


$ kubectl describe pod sample-emptydir-limit

~(생략)~

Events:
  Type     Reason     Age    From               Message
  ----     ------     ----   ----               -------
  Warning  Evicted    5m37s  kubelet            Usage of EmptyDir volume "cache-volume" exceeds the limit "128Mi".
  Normal   Killing    5m37s  kubelet            Stopping container nginx-container

【고속 메모리 영역을 사용한 emptyDir 볼륨을 마운트하는 파드 예제】

  • emptydir은 호스트상의 디스크 영역뿐만 아니라 고속 tmpfs 메모리 영역을 사용할 수도 있다.

  • 메모리 영역을 사용하려면 “emptyDir.medium”에 Memory를 지정한다.

$ cat <<EOF > sample-emptydir-memory.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir-memory
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      medium: Memory
      sizeLimit: 128Mi
EOF


# 쿠버네티스 노드의 tmpfs 영역이 할당된 것을 확인
$ kubectl exec -it sample-emptydir-memory -- df -h | grep /cache
tmpfs                              128M     0  128M   0% /cache

【메모리 리소스 제한과 emptyDir을 같이 사용한 예제】

  • emptyDir 메모리 영역에서 사용하는 용량은 컨테이너에 대한 메모리 사용 상한 설정 “resource.limits.memory”에도 영향을 준다.

  • 이 매니페스트는 128Mi까지 tmpfs 영역을 사용할 수있는 점은 같지만, 컨테이너가 사용할 수 있는 메모리 상한이 설정되어 있다.

  • emptyDir도 이 제한이 예외가 아니라서 70MB 파일을 작성하는 단계에서 OOM(Out of Memory)에 의해 파드가 정지되는 점에 주의.

$ cat <<EOF > sample-emptydir-memory-with-memory-limits.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-emptydir-memory-with-memory-limits
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    resources:
      limits:
        memory: 64Mi
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      medium: Memory
      sizeLimit: 128Mi
EOF


# 70MB 파일을 /cache/dummy에 생성
$ kubectl exec -it sample-emptydir-memory-with-memory-limits -- dd if=/dev/zero of=/cache/dummy bs=1M
command terminated with exit code 137


# 파드 상태 모니터링(별도 터미널에서 파일 생성 전에 실행)
$ kubectl get pod --watch
NAME                                        READY   STATUS    RESTARTS      AGE
sample-emptydir-memory-with-memory-limits   1/1     Running   1             48s
sample-emptydir-memory-with-memory-limits   0/1     OOMKilled 0             20s


📜 hostPath

  • 쿠버네티스 노드상의 파일 시스템에서 파일이나 디렉터리를 파드에 마운트하는 볼륨 유형

  • type은 “Directory/DirectroyOrCreate/File/Socket/BlockDevice 등”을 선택할 수 있으고, DirectroyOrCreate와 Directory의 차이는 디렉터리가 존재하지 않을 경우 생성하고 기동하는지 여부에 있다.

  • 보안상의 이유로 안전하지 않은 컨테이너가 업로드될 수 있으므로 사용하지 않는 것을 권장한다.

23123123

【hostPath 볼륨을 마운트하는 파드 예제】

$ cat <<EOF > sample-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-hostpath
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /srv
      name: hostpath-sample
  volumes:
  - name: hostpath-sample
    hostPath:
      path: /etc
      type: DirectoryOrCreate
EOF


# 호스트 OS 이미지 확인 - (호스트의 /etc가 생성한 파드의 /srv에 마운트된 것을 확인)
$ kubectl exec -it sample-hostpath -- cat /srv/os-release | grep PRETTY_NAME
PRETTY_NAME="Ubuntu 22.04.2 LTS"


# 컨테이너 OS 이미지 확인
$ kubectl exec -it sample-hostpath -- cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Debian GNU/Linux 10 (buster)"


📜 downwardAPI

  • 파드 정보 등을 파일로 배치하기 위한 플러그인

  • 환경 변수 fieldRef와 resourceFieldRef의 사용 방법과 같다.

$ cat <<EOF > sample-downward-api.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-downward-api
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    volumeMounts:
    - name: downward-api-volume
      mountPath: /srv
  volumes:
  - name: downward-api-volume
    downwardAPI:
      items:
      - path: "podname"
        fieldRef:
          fieldPath: metadata.name
      - path: "cpu-request"
        resourceFieldRef:
          containerName: nginx-container
          resource: requests.cpu
EOF


# sample-downward-api 파드의 /srv 아래 파일 확인
$ kubectl exec -it sample-downward-api -- ls /srv
cpu-request  podname


📜 projected

  • 시크릿/컨피그맵/downwardAPI/serviceAccountToken의 볼륨 마운트를 하나의 디렉터리에 통합하는 플러그인

  • 시크릿 인증 정보와 컨피그맵 설정 파일 하나의 디렉터리에 배치하고 싶을 경우 사용할 수 있다.

$ cat <<EOF > sample-projected.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-projected
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    volumeMounts:
    - name: projected-volume
      mountPath: /srv
  volumes:
  - name: projected-volume
    projected:
      sources:
      - secret:
          name: sample-db-auth
          items:
          - key: username
            path: secret/username.txt
      - configMap:
          name: sample-configmap
          items:
          - key: nginx.conf
            path: configmap/nginx.conf
      - downwardAPI:
          items:
          - path: "podname"
            fieldRef:
              fieldPath: metadata.name
EOF


# /srv 디렉터리 확인
$ kubectl exec -it sample-projected -- ls /srv
configmap  podname  secret


# /srv/configmap 디렉터리 확인
$ kubectl exec -it sample-projected -- ls /srv/configmap
nginx.conf


# /srv/secret 디렉터리 확인
$ kubectl exec -it sample-projected -- ls /srv/secret
username.txt


KUBERNETES 카테고리 내 다른 글 보러가기

댓글 남기기