Storage in Docker


Container Storage ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ 07. Docker Storage ์„ ์‚ดํŽด๋ณด์ž.

Volume Driver Plugins in Docker

Container ๋‚ด์—์„œ ์ €์žฅ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Volume ์„ ๋งˆ์šดํŒ…ํ•  ๋•Œ Volume Driver ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Local Driver Plugin ์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค์–‘ํ•œ Driver ๊ฐ€ ์กด์žฌํ•œ๋‹ค. RexRay Driver ์˜ ๊ฒฝ์šฐ AWS EBS ์™€ S3 ๋ฅผ Volume ์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ์“ฐ์ธ๋‹ค.

docker run -it \
  --name mysql
  --volume-driver rexray/ebs
  --mount src=ebs-vol,target=/var/lib/mysql
  mysql

Docker Container ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ Volume Driver ๋ฅผ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Container Storage Interface (CSI)

K8s ๊ฐ€ CRI ๋ฅผ ํ†ตํ•ด Docker ์™ธ์—๋„ rkt, cri-o ๋“ฑ์„ Container Runtime ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋“ฏ์ด Container Storage ๋ฅผ ์œ„ํ•œ Interface ๋ฅผ CSI ๋กœ ์ œ๊ณตํ•œ๋‹ค. CSI ๋Š” K8s ์—๋งŒ ์ข…์†์ ์ธ ๊ฒƒ์ด ์•„๋‹Œ Universal Standard ์ด๊ธฐ์— Storage Provider ๋“ค์ด CSI ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ Mesos ๊ฐ™์€ ๋‹ค๋ฅธ Container Orchestration ํˆด์—๋„ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

Persistent Volumes


Volumes

apiVersion: v1
kind: Pod
metadata:
  name: random-number-generator
spec:
  containers:
  - image: alpine
    name: alpine
    command: ["/bin/sh", "-c"]
    args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
    volumeMounts:
    - mountPath: /opt
      name: data-volume
  volumes:
  - name: data-volume
    hostPath:
      path: /data
      type: Directory

Pod ๋‚ด Container ์—๊ฒŒ Volume ์„ ๋งˆ์šดํŒ…ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„ ๋‚ด์šฉ์€ Node ์˜ /data ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ Volume ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  Container ๋‚ด /opt ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ ๋งˆ์šดํŒ…ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

volumes:
- name: data-volume
  awsElasticBlockStore:
    volumeID: <volume-id>
    fsType: ext4

Node ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ Volume ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค EBS ๋“ฑ์˜ Storage ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ํ•ฉ๋ฆฌ์ ์ด๋‹ค.

Persistent Volumes

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vol1
spec:
  accessModes: [ "ReadWriteOnce" ]
  capacity:
    storage: 1Gi
  awsElasticBlockStore:
    volumeID: <volume-id>
    fsType: ext4

๊ฐ Pod Definition ๋งˆ๋‹ค Volume ์„ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด ๊ด€๋ฆฌํฌ์ธํŠธ๊ฐ€ ๋Š˜์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์ด์ƒ์ ์ด์ง€ ์•Š๋‹ค. ๋•Œ๋ฌธ์— Pod ๊ฐ€ ๊ฐ์ž ํ•„์š”ํ•œ ๋งŒํผ ๋‚˜๋ˆ ์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” Persistent Volume ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Persistent Volume Claims

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes: [ "ReadWriteOnce" ]
  resources:
    requests:
      storage: 1Gi

์ƒ์„ฑ๋œ Persistent Volume ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  Persistent Volume Claim ์„ ์ƒ์„ฑํ•ด์ค˜์•ผ ํ•œ๋‹ค. Persistent Volume Claim ์€ Storage Capacity, Access Mode ๋“ฑ์„ ๋น„๊ตํ•˜์—ฌ ์ ์ ˆํ•œ Persistent Volume ์„ ์ฐพ๊ณ  ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. ๋งŒ์•ฝ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” Persistent Volume ์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ PVC ๋Š” Pending State ๋กœ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋œ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - image: nginx
    name: myfrontend
    volumeMounts:
    - mountPath: "/var/www/html"
      name: mypd
  volumes:
  - name: mypd
    persistentVolumeClaim
      claimName: myclaim

PVC ๊ฐ€ ์ƒ์„ฑ๋œ ์ดํ›„ Pod ์™€ ๋งˆ์šดํŒ…ํ•˜๊ธฐ ์œ„ํ•ด์„  ์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

Storage Class


apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: google-storage
provisioner: kubernetes.io/gce-pd

AWS EBS ๋“ฑ์„ PV ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด AWS EBS ๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ Static Provisioning ์ด๋ผ ํ•˜๋Š”๋ฐ PVC ๊ฐ€ PV ๋ฅผ ์š”๊ตฌํ•  ๋•Œ ์ž๋™์œผ๋กœ EBS ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ฒƒ์„ Dynamic Provisioning ์ด๋ผ ํ•˜๋ฉฐ Storage Class ๋ฅผ ํ†ตํ•ด ์ด๋ค„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes: [ "ReadWriteOnce" ]
  storageClassName: google-storage       
  resources:
    requests:
      storage: 500Mi

SC ๋ฅผ ์ƒ์„ฑํ•œ ์ดํ›„ PVC ๊ฐ€ SC ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

References