데이터 지속성: 컨테이너는 재시작되거나 다른 노드로 이동할 때 내부 데이터를 유지하지 않는다. 상태를 유지하는 애플리케이션(예: 데이터베이스)의 경우, 데이터를 보존하고 접근할 수 있는 외부 스토리지가 필수적이다.
데이터 공유와 협업: 여러 컨테이너가 동일한 데이터에 접근해야 하는 경우(예: 콘텐츠 관리 시스템) 스토리지 솔루션을 통해 데이터를 공유하고, 여러 서비스 간에 협업을 용이하게 한다.
데이터 백업 및 복구: 중요 데이터의 백업 및 복구를 위해 외부 스토리지를 활용하여, 데이터 손실 시 복구를 보장한다.
성능 최적화: 고성능 스토리지를 활용하여 입출력 성능을 향상시키고, 애플리케이션의 전반적인 성능을 최적화할 수 있다.
스케일링 및 관리 용이성: 스토리지 관리 기능(동적 프로비저닝, 자동 확장 등)을 통해 리소스 사용량에 따라 스토리지를 유연하게 조정하고, 운영 효율성을 높일 수 있다.
emptyDir은 파드 내 임시 데이터 공유에, hostPath는 파드가 호스트 머신의 특정 파일이나 디렉토리에 접근해야 할 때 사용된다. local 볼륨은 지속적인 데이터를 필요로 하지만, 특정 노드에 종속된 스토리지를 요구하는 애플리케이션에 사용된다.
emptyDir 볼륨은 파드가 생성될 때 만들어지고, 파드에 속한 모든 컨테이너 간에 데이터를 공유할 수 있는 임시 디렉토리이다. emptyDir 볼륨은 파드가 존재하는 동안에만 유지되며, 파드가 제거되면 emptyDir에 저장된 데이터도 함께 삭제된다.
hostPath 볼륨은 노드의 파일 시스템에 있는 파일이나 디렉토리를 파드에 마운트한다. 이를 통해 파드가 호스트 머신의 파일 시스템에 접근할 수 있게 된다.
local 볼륨은 노드의 지속적인 스토리지에 대한 접근을 제공한다. 이는 hostPath와 유사하지만, PersistentVolumes를 통해 사용된다. local 볼륨을 사용하면, 특정 노드의 스토리지에 바인딩된 PV를 생성하여, PVC를 통해 파드에 지속적인 데이터 스토리지를 제공할 수 있다.
resources 제한은 lint때문에 그냥 설정 (실제 환경이라면 반드시 최적의 값으로 설정해 줘야 한다.)
One or more containers do not have resource limits - this could starve other processes
nginx- service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 80
nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
ports:
- containerPort: 80
name: http
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-deployment.yaml
minikube tunnel
nginx에 /usr/share/nginx/html/index.html 을 변경
kubectl rollout restart deployment nginx-deployment
해당 명령어로 재배포
내용이 저장되지 않고 다시 원본으로 돌아온 것을 알 수 있다.
two-container-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
command: ['/bin/sh']
args: ['-c', 'tail -f /dev/null']
kubectl apply -f two-container-pod.yaml
nginx-container에 접속 후 해당 명령어(ls /usr/share/nginx/html
)를 입력한다.
현재 빈 폴더임을 알 수 있다.
이제 debian-container에 접속 후 해당 명령어(mkdir -p pod-data/test
)를 입력하여 debian-container에 test
폴더를 만들어 준다.
다시 nginx-container에 접속 후 해당 명령어(ls /usr/share/nginx/html
)를 입력한다.
test 폴더 존재
즉, nginx-container와 debian-container가 볼륨을 공유함을 알 수 있다.
그러나 POD을 종료하면 볼륨도 같이 삭제된다.
hostpath-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-test
spec:
containers:
- name: test-container
image: busybox
command: ['sh', '-c', 'tail -f /dev/null']
volumeMounts:
- name: test-volume
mountPath: /mnt/test
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
volumes:
- name: test-volume
hostPath:
path: /home/docker/test
type: Directory
hostPath의 타입은 다음과 같다.
test-container에 접속 후 해당 명령어를 입력하여 hostPath
폴더를 만들어 준다.
이제 minikube ssh
명령어로 minikube에 접속 후 hostPath
폴더가 있는지 확인한다.
이는 호스트 노드의 파일시스템에 디렉터리가 POD와 마운트 됐음을 알 수 있다. 그러므로 POD가 삭제된 후 다시 실행돼도 볼륨을 유지할 수 있다.
그러나 hostPath 볼륨은 특정 노드의 파일 시스템 경로를 POD에 마운트하기 때문에, 해당 노드에서만 접근 가능하며, 다른 노드로 POD이 재스케줄링될 경우 그 볼륨에 더 이상 접근할 수 없게 된다.
local
볼륨과 퍼시스턴트볼륨의 nodeAffinity를 설정하여 이 문제를 해결할 수 있지만 만약 해당 노드가 비정상 상태가 되면 local 볼륨도 접근할 수 없게 되고, POD을 실행할 수 없게 된다.
또한, local
볼륨은 동적 프로비저닝을 지원하지 않는다.
PersistentVolume은 클러스터 내에서의 스토리지 볼륨이다. 이는 일반적인 컴퓨터 파일 시스템이나 네트워크 파일 시스템, 클라우드 기반 스토리지 등 다양한 스토리지 백엔드를 추상화한다.
PersistentVolumeClaim은 사용자가 스토리지에 대해 요청하는 방법이다. 사용자는 필요한 스토리지의 크기와 접근 모드를 PVC를 통해 명시한다.
StorageClass는 동적 스토리지 프로비저닝을 위한 방법을 제공한다. SC는 PV를 생성하기 위해 사용되는 "템플릿"으로, 특정 스토리지 백엔드와 프로비저닝 정책을 정의한다.
동적 프로비저닝은 사용자가 PersistentVolumeClaim(PVC)을 생성할 때, 자동으로 필요한 PersistentVolume(PV)을 생성하고 할당하는 방식이다. 사용자는 스토리지의 크기, 액세스 모드 등 필요한 스펙을 PVC를 통해 정의하고, Kubernetes는 해당 요구 사항을 만족하는 PV를 자동으로 생성하여 PVC에 바인딩한다.
장점: 동적 프로비저닝을 사용하면, 스토리지 관리자가 미리 여러 PV를 생성해 두지 않아도 된다. 사용자의 요구에 따라 필요한 시점에 적절한 스토리지 리소스가 자동으로 프로비저닝된다.
사용 예시: 클라우드 환경에서 EBS 볼륨이나 GCP의 Persistent Disk와 같은 스토리지 리소스를 동적으로 프로비저닝하는 경우
정적 프로비저닝은 스토리지 관리자가 사전에 PV를 생성하고 구성해 두며, 사용자는 PVC를 통해 이러한 기존 PV 중 하나를 요청하는 방식이다. 사용자의 PVC가 생성되면, Kubernetes는 PVC의 요구 사항과 일치하는 기존의 PV를 찾아 바인딩한다.
장점: 정적 프로비저닝을 사용하면, 스토리지 관리자가 스토리지의 물리적 구성, 성능, 비용 등을 미리 제어할 수 있다. 또한, 특정 스토리지 정책이나 보안 요구 사항을 사전에 적용할 수 있다.
사용 예시: 내부 데이터 센터의 NFS 서버나 iSCSI 타겟과 같은 기존 인프라에 스토리지를 정적으로 프로비저닝하는 경우
프로비저닝 방법: 동적 프로비저닝은 사용자의 요청에 따라 자동으로 스토리지 볼륨이 생성되는 반면, 정적 프로비저닝은 미리 생성된 스토리지 볼륨을 사용자의 요청에 할당한다.
관리의 편의성: 동적 프로비저닝은 스토리지 리소스의 관리를 자동화하여 관리의 편의성을 제공하지만, 정적 프로비저닝은 스토리지 관리자가 미리 스토리지를 준비하고 관리해야 한다.
적용 시나리오: 동적 프로비저닝은 클라우드 환경과 같이 스토리지 리소스가 유연하게 확장될 수 있는 환경에 적합하며, 정적 프로비저닝은 기존의 물리적 인프라를 효율적으로 활용해야 하는 경우에 주로 사용된다.
minikube를 사용한다면
standard
StorageClass가 기본적으로 사용 가능합니다.
dp-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dp-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
storageClassName: standard
kubectl apply -f dp-pvc.yaml
pvc가 생성되었다면 pv도 자동적으로 생성됩니다.
dp-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: dp-pod
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- mountPath: '/usr/share/nginx/html'
name: storage
resources:
requests:
cpu: 200m
memory: 250Mi
limits:
cpu: 1000m
memory: 500Mi
volumes:
- name: storage
persistentVolumeClaim:
claimName: dp-pvc
kubectl apply -f dp-pod.yaml
이런 방식으로 동적 프로비저닝을 할 수 있다.