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 툴에도 적용될 수 있다.
Ephemeral Volumes
emptyDir
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- image: alpine
name: alpine
command: ["/bin/sh", "-c"]
args: ["shuf -i 0-100 -n 1 >> /opt/number.out;"]
volumeMounts:
- mountPath: /opt
name: temp-storage
volumes:
- name: temp-storage
emptyDir: {}
Pod 가 생성될 때 빈 디렉터리로 시작하고 모든 컨테이너가 데이터를 읽고 쓸 수 있다. Pod 삭제 시 데이터도 삭제된다.
hostPath
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: DirectoryPod 내 Container 에게 Volume 을 마운팅해주기 위해 위와 같이 설정할 수 있다. 위 내용은 Node 의 /data 디렉터리를 Volume 으로 사용하고 Container 내 /opt 디렉터리와 마운팅하겠다는 의미다. hostPath 의 경우 Pod 가 재시작 시 다른 Node 에 Scheduling 되는 상황이 발생할 수 있기 때문에 Ephemeral Volume 이라고 생각할 수 있다.
Persistent 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
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4Node 의 디렉터리를 Volume 으로 사용하는 것은 앞서 설명하였듯이 동일한 Node 에서 Pod 가 재시작한다는 보장이 없기 때문에 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 을 사용할 수 있다.
PV 의 주요 필드는 아래와 같다.
capacity- PV 의 스토리지 용량을 정의한다
- PVC 는 이 용량을 요청하여 사용할 수 있다
accessModes- PV 의 접근 모드를 정의한다
ReadWriteOnce: 하나의 Node 에서 읽기/쓰기가 가능ReadOnlyMany: 여러 Node 에서 읽기만 가능ReadWriteMany: 여러 Node 에서 읽기/쓰기가 가능
- PV 의 접근 모드를 정의한다
storageClassName- PV 에 적용되는
StorageClass를 정의한다 - 위 예시에선
awsElasticBlockStore를 사용한다
- PV 에 적용되는
persistentVolumeReclaimPolicy- PVC 가 제거된 후 PV 를 어떻게 처리할지 정의한다
Retain: 데이터를 보존하고 불필요 시 관리자가 수동으로 정리한다Recycle: 데이터를 삭제하고 PV 를 재사용한다Delete: PV 와 데이터를 모두 제거한다
- PVC 가 제거된 후 PV 를 어떻게 처리할지 정의한다
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: myclaimPVC 가 생성된 이후 Pod 와 마운팅하기 위해선 위와 같이 설정해주면 된다.
Storage Class
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: google-storage
provisioner: kubernetes.io/gce-pdAWS 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: 500MiSC 를 생성한 이후 PVC 가 SC 를 참조할 수 있도록 설정해주면 된다.