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
mysqlDocker Container 를 실행할 때 Volume Driver 를 지정해줄 수 있다.
CSI, Container Storage Interface
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 를 사용하는 것이 더 합리적이다.
PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-vol1
spec:
capacity: # PV 의 스토리지 용량
storage: 1Gi
accessModes: # PV 의 접근 모드
- ReadWriteOnce # 'ReadWriteOnce | ReadOnlyMany | ReadWriteMany|ReadWriteOncePod' 몇 대의 Node 가 PV 에 읽고 쓰는지
storageClassName: awsElasticBlockStore # PV 를 구현하는 StorageClass
persistentVolumeReclaimPolicy: Recycle # 'Retain | Recycle | Delete' PVC 제거 후 PV 처리 여부PersistentVolumeClaim
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 Classes
StorageClass
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
resources:
requests:
storage: 500Mi
storageClassName: google-storage # google-storage SC 의 500Mi RWO PV 생성SC 를 생성한 이후 PVC 가 SC 를 참조할 수 있도록 storageClassName 을 설정해주면 된다.