ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] 스토리지 - 볼륨
    공부/데이터 2025. 1. 30. 21:46

    쿠버네티스 볼륨은 파드 내의 컨테이너가 파일 시스템을 통해 데이터에 접근하고 공유할 수 있는 방법을 제공합니다. 다양한 목적에 따라 사용할 수 있는 여러 종류의 볼륨이 있습니다. 예를 들어 다음과 같은 용도로 사용할 수 있습니다.

    • ConfigMap 또는 Secret을 기반으로 설정 파일을 채우기
    • 파드를 위한 임시 스크래치 공간 제공
    • 동일한 파드 내의 두 컨테이너 간에 파일 시스템 공유
    • 서로 다른 노드에서 실행되더라도 두 개의 다른 파드 간에 파일 시스템 공유
    • 파드가 다시 시작되거나 교체되더라도 계속 사용할 수 있도록 데이터 영구 저장
    • 컨테이너가 속한 파드의 세부 정보(예: 파드가 실행 중인 네임스페이스)를 기반으로 컨테이너에서 실행되는 앱에 구성 정보 전달 (예: 사이드카 컨테이너에 파드가 실행 중인 네임스페이스 알림)
    • 다른 컨테이너 이미지의 데이터에 읽기 전용 접근 권한 제공

    데이터 공유는 컨테이너 내의 서로 다른 로컬 프로세스 간, 서로 다른 컨테이너 간 또는 파드 간에 이루어질 수 있습니다.

    볼륨 종류

    configMap

    ConfigMap은 설정 데이터를 파드에 주입하는 방법을 제공합니다. ConfigMap에 저장된 데이터는 configMap 유형의 볼륨에서 참조될 수 있으며, 파드에서 실행되는 컨테이너화된 애플리케이션에서 사용될 수 있습니다.

    ConfigMap을 참조할 때 볼륨에 ConfigMap의 이름을 지정합니다. ConfigMap의 특정 항목에 사용할 경로를 사용자 정의할 수 있습니다. 다음 구성은 log-config ConfigMap을 configmap-pod이라는 파드에 마운트하는 방법을 보여줍니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-pod
    spec:
      containers:
        - name: test
          image: busybox:1.28
          command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
          volumeMounts:
            - name: config-vol
              mountPath: /etc/config
      volumes:
        - name: config-vol
          configMap:
            name: log-config
            items:
              - key: log_level
                path: log_level.conf

    log-config ConfigMap은 볼륨으로 마운트되며, log_level 항목에 저장된 모든 내용은 /etc/config/log_level.conf 경로의 파드에 마운트됩니다. 이 경로는 볼륨의 mountPathlog_level 키로 지정된 path에서 파생됩니다.

    빈디렉터리(emptyDir)

    emptyDir 볼륨을 정의하는 파드의 경우, 해당 볼륨은 파드가 노드에 할당될 때 생성됩니다. 이름에서 알 수 있듯이 emptyDir 볼륨은 초기에는 비어 있습니다. 파드의 모든 컨테이너는 emptyDir 볼륨의 동일한 파일에 읽고 쓸 수 있지만, 각 컨테이너에서 동일하거나 다른 경로에 해당 볼륨을 마운트할 수 있습니다. 파드가 어떤 이유로든 노드에서 제거되면 emptyDir의 데이터는 영구적으로 삭제됩니다.

    emptyDir의 몇 가지 사용 사례는 다음과 같습니다.

    • 디스크 기반 병합 정렬과 같은 임시 공간
    • 충돌로부터 복구를 위한 긴 계산의 체크포인트
    • 웹 서버 컨테이너가 데이터를 제공하는 동안 콘텐츠 관리자 컨테이너가 가져오는 파일 저장

    emptyDir.medium 필드는 emptyDir 볼륨이 저장되는 위치를 제어합니다. 기본적으로 emptyDir 볼륨은 환경에 따라 디스크, SSD 또는 네트워크 스토리지와 같은 노드를 지원하는 모든 매체에 저장됩니다. emptyDir.medium 필드를 "Memory"로 설정하면 Kubernetes는 대신 tmpfs(RAM 기반 파일 시스템)를 마운트합니다. tmpfs는 매우 빠르지만 디스크와 달리 작성한 파일은 해당 파일을 작성한 컨테이너의 메모리 제한에 포함된다는 점에 유의해야 합니다.

    기본 매체에 대한 크기 제한을 지정할 수 있으며 이는 emptyDir 볼륨의 용량을 제한합니다. 스토리지는 노드 임시 스토리지에서 할당됩니다. 다른 소스(예: 로그 파일 또는 이미지 오버레이)로 인해 해당 스토리지가 가득 차면 emptyDir는 이 제한 전에 용량이 부족해질 수 있습니다. 크기가 지정되지 않은 경우 메모리 지원 볼륨은 노드 할당 가능 메모리 크기로 조정됩니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: registry.k8s.io/test-webserver
        name: test-container
        volumeMounts:
        - mountPath: /cache
          name: cache-volume
      volumes:
      - name: cache-volume
        emptyDir:
          sizeLimit: 500Mi

    hostPath

    hostPath 볼륨은 호스트 노드(호스트)의 파일 시스템에 있는 파일 또는 디렉터리를 파드에 마운트합니다. emptyDir과 다르게 Pod가 죽어도 볼륨의 데이터는 삭제되지 않습니다. 이는 대부분의 파드에 필요한 것은 아니지만 일부 애플리케이션에 강력한 탈출구(escape hatch)를 제공합니다.

    hostPath의 몇 가지 사용 사례는 다음과 같습니다.

    • 노드 수준 시스템 구성 요소에 액세스해야 하는 컨테이너 실행 (예: 시스템 로그를 중앙 위치로 전송하는 컨테이너, /var/log의 읽기 전용 마운트를 사용하여 해당 로그에 접근)
    • 호스트 시스템에 저장된 구성 파일을 static pod에 읽기 전용으로 제공. 일반 파드와 달리 static pod는 ConfigMap에 접근할 수 없습니다
    ---
    # This manifest mounts /data/foo on the host as /foo inside the
    # single container that runs within the hostpath-example-linux Pod.
    #
    # The mount into the container is read-only.
    apiVersion: v1
    kind: Pod
    metadata:
      name: hostpath-example-linux
    spec:
      os: { name: linux }
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: example-container
        image: registry.k8s.io/test-webserver
        volumeMounts:
        - mountPath: /foo
          name: example-volume
          readOnly: true
      volumes:
      - name: example-volume
        # mount /data/foo, but only if that directory already exists
        hostPath:
          path: /data/foo # directory location on host
          type: Directory # this field is optional

    NFS(Network File System) 볼륨

    nfs 볼륨을 사용하면 기존 NFS (네트워크 파일 시스템) 볼륨을 파드에 마운트 할수 있습니다. 파드를 제거할 때 지워지는 emptyDir 와는 다르게 nfs 볼륨의 내용은 유지되고, 볼륨은 그저 마운트 해제만 됩니다. 이 의미는 NFS 볼륨에 데이터를 미리 채울 수 있으며, 파드 간에 데이터를 공유할 수 있다는 뜻입니다. NFS는 여러 작성자가 동시에 마운트할 수 있습니다. NFS에는 단점이 있는데 이를 보완하기 위해 PV와 PVC를 사용합니다.

    • NFS 볼륨의 마운트는 컨테이너 내부가 아닌 워커 노드에서 발생하므로 서비스의 DNS 이름으로 NFS 서버에 접근할 수 없음
      • 노드에서는 파드의 IP로 통신은 할 수 있지만 쿠버네티스의 DNS를 사용하도록 설정돼 있지는 않기 때문
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: registry.k8s.io/test-webserver
        name: test-container
        volumeMounts:
        - mountPath: /my-nfs-data
          name: test-volume
      volumes:
      - name: test-volume
        nfs:
          server: my-nfs-server.example.com
          path: /my-nfs-volume
          readOnly: true

    secret

    Secret 볼륨은 암호와 같은 민감한 정보를 파드에 전달하는 데 사용됩니다. Kubernetes API에 Secret을 저장하고 Kubernetes에 직접 결합하지 않고 파일로 마운트하여 파드에서 사용할 수 있습니다. secret 볼륨은 tmpfs(RAM 기반 파일 시스템)으로 지원되므로 비휘발성 스토리지에 기록되지 않습니다.

    subPath 사용

    때로는 단일 파드에서 여러 용도로 하나의 볼륨을 공유하는 것이 유용합니다. volumeMounts[*].subPath 속성은 참조된 볼륨의 루트 대신 해당 볼륨 내부의 하위 경로를 지정합니다. 즉, 전체 볼륨을 마운트하지 않고 파일이나 디렉토리 1개를 볼륨에 마운트하는 방식입니다.

    다음 예는 단일 공유 볼륨을 사용하여 LAMP 스택(Linux Apache MySQL PHP)으로 파드를 구성하는 방법을 보여줍니다. 이 샘플 subPath 구성은 프로덕션 환경에서 권장되지 않습니다.

    PHP 애플리케이션의 코드와 자산은 볼륨의 html 폴더에 매핑되고 MySQL 데이터베이스는 볼륨의 mysql 폴더에 저장됩니다. 예를 들어 다음과 같습니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-lamp-site
    spec:
        containers:
        - name: mysql
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            value: "rootpasswd"
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql
        - name: php
          image: php:7.0-apache
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-lamp-site-data

    레퍼런스

    https://kubernetes.io/docs/concepts/storage/volumes/

    댓글