목표
Pod 안의 컨테이너 간 디렉토리를 공유하는 방법과 컨테이너의 특정 디렉토리를 호스트 디렉토리와 연결하는 방법을 알아보자
- 지금까지 만들었던 컨테이너는 Pod을 제거하면 컨테이너 내부에 저장했던 데이터도 모두 사라졌다.
- MySQL과 같은 데이터베이스는 데이터가 유실되지 않도록 반드시 별도의 저장소에 데이터를 저장하고 컨테이너를 새로 만들 때 이전 데이터를 가져와야 한다.
- 쿠버네티스는 Volume을 이용하여 컨테이너의 디렉토리를 외부 저장소와 연결하고 다양한 플러그인을 지원하여, 흔히 사용하는 대부분의 스토리지를 별도 설정없이 사용할 수 있다.
Volume 만들기
empty-dir
- Pod 안에 속한 컨테이너 간 디렉토리를 공유하는 방법을 알아보자.
- 보통 사이드카(sidecar)라는 패턴를 사용
- 예를 들면, 특정 컨테이너에서 생성되는 로그 파일을 별도의 컨테이너(사이드카)가 수집 할 수 있다.
- 사이드카 패턴
- 원래 사용하려고 했던 기본 컨테이너의 기능을 확장하거나 보조하는 용도의 컨테이너를 추가하는 패턴

# volumeMounts는 pods 안에 name(varlog)볼륨을 mountPath의 경로에 마운트시킨다.
apiVersion: v1
kind: Pod
metadata:
name: sidecar
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- >
while true;
do
echo "$(date)\n" >> /var/log/example.log;
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: sidecar
image: busybox
args: [/bin/sh, -c, "tail -f /var/log/example.log"]
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
배포 후
sidecar
의 로그를 확인kubectl apply -f empty-dir.yml # sidecar 로그 확인 kubectl logs -f sidecar -c sidecar
app
컨테이너에서 생성한 로그파일을 sidecar
컨테이너에서 처리하는 모습을 볼 수 있다.hostpath
- 호스트 디렉토리를 컨테이너 디렉토리에 연결하는 방법을 알아보자. (여기서는 호스트의
/var/log
디렉토리를 연결하여 내용을 확인)

apiVersion: v1
kind: Pod
metadata:
name: host-log
spec:
containers:
- name: log
image: busybox
args: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: varlog
mountPath: /host/var/log
volumes:
- name: varlog
hostPath:
path: /var/log
# persistentVolumeClaim: hostPath에 host의 경로를 쓸수도 있고
# claimName: shared-pvc persistentVolumeClaim를 통해 할당할 수도 있다.
컨테이너에서 마운트 된 디렉토리를 확인
kubectl apply -f hostpath.yml
# 컨테이너 접속 후 /host/var/log 디렉토리를 확인
kubectl exec -it host-log -- sh
ls -al /host/var/log
PV/PVC
- PV는 볼륨 자체를 뜻하며 클러스터 안에서 자원으로 다루어진다.
- 파드와는 별개로 관리되며 별도의 생명 주기가 있다.
- PVC는 사용자가 PV에 하는 요청이다.
- 사용하고 싶은 용량은 얼마인지, 읽기/쓰기는 어떤 모드로 설정하고 싶은지 등을 정해서 요청
- 쿠버네티스 볼륨을 파드에 직접 할당하는 방식이 아니라 중간에 PVC를 두어 파드와 파드가 사용할 스토리지를 분리한다.
- 이런 구조는 파드 각각의 상황에 맞게 다양한 스토리지를 사용할 수 있게 할 수 있음
- 클라우드 서비스를 사용할 때는 본인이 사용하는 클라우드 서비스에서 제공해주는 볼륨 서비스를 사용할 수도 있고, 직접 구축한 스토리지를 사용할 수도 있음
- 이렇게 다양한 스토리지를 PV로 사용할 수 있지만 파드에 직접 연결하는 것이 아니라 PVC를 거쳐서 사용하므로 파드는 어떤 스토리지를 사용하는지 신경 쓰지 않아도 된다
Example
PV 예시
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-hostpath
spec:
capacity:
storage: 2Gi # 스토리지 용량 2GB
volumeMode: Filesystem # 파일 시스템 형식
accessModes: # 읽기/쓰기 옵션
- ReadWriteOnce
storageClassName: manual
persistentVolumeReclaimPolicy: Delete
hostPath:
path: /tmp/k8s-pv # 스토리지를 연결할 Path
- storageClassName은 스토리지 클래스(StorageClass)를 설정하는 필드로 특정 스토리지 클래스가 있는 PV는 해당 스토리지 클래스에 맞는 PVC만 연결된다. (PV에 storageClassName 필드 설정이 없으면 .spec.storageClassName 필드 설정이 없는 PVC와만 연결된다.)
- hostPath 필드는 해당 PV의 볼륨 플러그인을 명시한다. 필드 값을 hostPath로 설정했기 때문에 하위의 hostPath.path 필드는 마운트시킬 로컬 서버의 경로를 설정한다.
PVC 예시
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-hostpath
spec:
accessModes: # AccessModes
- ReadWriteOnce
volumeMode: Filesystem # 파일 시스템 형식
resources:
requests:
storage: 1Gi # 1GB 요청
storageClassName: manual # 스토리지 클래스 명
- resources.requests.storage 필드는 자원을 얼마나 사용할 것인지 요청(request)한다
- 필드 값을 설정할 때는 앞에서 만든 PV의 용량을 초과하면 안됨. 만약 초과하는 경우 사용할 수 있는 PV가 없으므로 PVC를 생성할 수 없는 Pending 상태가 된다.
- storageClassName 필드를 위에서 생성한 PV와 동일하게 생성하여 위의 PV에 정상적으로 연결될 수 있도록 한다.
NFS 적용 PV 참고
- PersistentVolume에 nfs 옵션을 통해 nfs를 volumn으로 사용할 수 있다.
Share article