/ kubernetes

Kubernetes Volumes

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

기본적으로 Pod의 컨테이너는 무상태이다. Pod의 상태를 유지하기 위해서나 Pod내의 컨테이너끼리 데이터를 공유하기 위해 Volume을 사용한다.

Background

Docker volume은 host disk를 사용하는 정도였다면 Kubernetes Volume은 좀더 다양한 disk를 제공하고 다양한 제약조건을 추가하게 되었다.

Types of Volumes

emptyDir

Pod안에 있는 컨테이너끼리 데이터 공유가능
Pod 삭제시 디스크에서 삭제됨
컨테이너 크래시나 종료는 삭제되지 않음

  • 계산할때 임시로 사용하는용, 디스크 베이스로 머지 소트 하는 경우
  • 컴퓨테이션이 긴 경우 계산 크래시 대비 체크포인트용
  • 웹서버가 잠깐 파일을 들고 있는 경우

emptyDir은 머신의 스토리지를 기본으로 사용
emptyDir.medium 값을 "Memory"로 주면 tmpfs(RAM-backed filesystem)를 사용

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

hostPath

Pod에서 node 파일시스템에 접근하는 경우 사용

  • Docker internal에 접근이 필요한 경우
  • 컨테이너에서 cAdvisor 실행하는 경우

주의점

  • Pod가 배포 될때 마다 Node가 달라 질수 있음
  • Kubernetes 설정에 따라 지원을 안할수 있음
  • root 권한으로 생성되기 때문에 높은 권한이 필요하거나 퍼미션을 조정해야 쓰기 가능
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data

gcePersistentDisk

사용하기전에 생성해야 함
데이터가 유지가 되는 디스크

  • node가 GCE VM이여야 함
  • GCE의 프로젝트와 zone이 같아야 함

read-only로만 사용하는 경우 동시에 여러군데서 접근 가능
read-write의 경우 한군데 pod에서만 사용 가능

디스크 생성

gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    # This GCE PD must already exist.
    gcePersistentDisk:
      pdName: my-data-disk
      fsType: ext4

gitRepo

빈 디렉토리로 마운트 되어서 해당 respository에서 git clone을 함

apiVersion: v1
kind: Pod
metadata:
  name: server
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /mypath
      name: git-volume
  volumes:
  - name: git-volume
    gitRepo:
      repository: "git@somewhere:me/my-git-repository.git"
      revision: "22f1d8406d464b0c0874075539c1f2e96c253775"

secret

민감한 정보를 마운트 할때 사용 tmpfs(RAM-backed filesystem)에 마운트되어서 디스크에 기록이 남지 않음

persistentVolumeClaim

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

downwardAPI

https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/

projected

다양한 소스를 같은 디렉토리로 제공할때 사용

  • secret
  • downwardAPI
  • configMap

예제

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - downwardAPI:
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "cpu_limit"
              resourceFieldRef:
                containerName: container-test
                resource: limits.cpu
      - configMap:
          name: myconfigmap
          items:
            - key: config
              path: my-group/my-config

여러개의 Secret 사용

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - secret:
          name: mysecret2
          items:
            - key: password
              path: my-group/my-password
              mode: 511

local

1.7+
PersistentVoulme으로 생성해서 사용

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
  annotations:
        "volume.alpha.kubernetes.io/node-affinity": '{
            "requiredDuringSchedulingIgnoredDuringExecution": {
                "nodeSelectorTerms": [
                    { "matchExpressions": [
                        { "key": "kubernetes.io/hostname",
                          "operator": "In",
                          "values": ["example-node"]
                        }
                    ]}
                 ]}
              }'
spec:
    capacity:
      storage: 100Gi
    accessModes:
    - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    storageClassName: local-storage
    local:
      path: /mnt/disks/ssd1

ETC

awsElasticBlockStore, nfs, iscsi, fc(fibre channel), flocker, glusterfs, rbd, cephfs, azureFileVolume, azureDisk, vsphereVolume, Quobyte, PortworxVolume, ScaleIO, StorageOS

subPath 사용하기

한 Pod내에서 한개의 Volume을 여러개로 사용할때 사용
volumeMounts.subPath

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