- Volumes ← 오늘 볼 내용
- Persistent Volumes(PV)
- Projected Volumes
- Ephemeral Volumes
- Storage Classes
1. Volumes
https://kubernetes.io/ko/docs/concepts/storage/volumes/
컨테이너는 각기 자신만의 파일시스템을 가지고 있다.
하지만 이 파일시스템은 불안정하여 컨테이너에 충돌이 생기면 파드는 컨테이너를 초기화하고 다시 시작한다.
그렇게 되면 컨테이너 내 파일시스템에 있던 기존의 데이터는 사라지고 완전 초기 상태로 돌아가는 것이다.
이런 상황을 해결하기 위해서 볼륨이라는 개념이 있다.
쿠버네티스는 다양한 볼륨이 있으며 그 중 임시 볼륨은 파드가 제거되면 함께 사라지는 볼륨이다.
그러나 파드가 제거되더라도 죽지 않고 계속 살아있는 볼륨이 있는데 이를 퍼시스턴트 볼륨(PV)이라고 한다.
볼륨은 container 필드와 같은 레벨에서 지정하고 컨테이너 내부에서 지정했던 볼륨을 마운트하여 활용할 수 있다.
즉, .spec.volumes 으로 파드에 제공할 볼륨을 지정, .spec.containers[*].volumeMounts 로 해당 볼륨을 컨테이너에 마운트할 위치를 선언한다.
위 목차에 해당하는 볼륨을 각각 대략적으로 설명하자면 다음과 같다.
- Persistent Volumes(PV) : 영속성을 가지는 볼륨으로 쿠버네티스 API 오브젝트인 PersistentVolume과 PersistentVolumeClaim을 사용하여 컨테이너의 파일 시스템이 아닌 쿠버네티스가 노드의 스토리지를 개별적인 볼륨으로 생성하여 컨테이너들이 각각 해당 볼륨에 마운트하여 쓸 수 있도록 하는 것.
일반적인 컨테이너가 자신의 파일 시스템에서 디렉토리 일부를 공유하여 사용하는 것과 다른 개념. - Projected Volumes : configmap, secret, downwardAPI를 한번에 투영하여 사용할 수 있도록 하는 볼륨.
자체적인 쿠버네티스 API 오브젝트로 정의하는 것이 아니라 .spec.volumes.projected 와 같이 템플릿에 일부 구성요소로만 정의되기에 프로젝티드 볼륨의 수명은 파드의 라이프사이클동안만 유지된다. - Ephemeral Volumes : emptyDir이라는 빈 디렉토리를 정의하여 파드가 생성될 때 함께 생성하거나 configmap, secret, downwardAPI를 포함하여 정의 혹은 csi임시 볼륨 등이 임시 볼륨에 속하며 수명은 당연히 파드의 라이프사이클동안만 유지된다.
- Storage Classes : 클라우드 환경에서 쿠버네티스를 운영하는 경우 동적 프로비저닝을 가능하게 하기 위해 사용된다.
퍼시스턴트 볼륨의 동적인 생성과 관리를 간편하게 할 수 있다.
참고:
볼륨을 정의하고 마운트할 때 컨테이너가 실행될 때 기존 파일 시스템에서 존재하는 디렉토리를 지정하면 해당 디렉토리에 마운트되며 기존의 데이터는 덮어쓰기 되고, 존재하지 않는 디렉토리를 지정하면 쿠버네티스가 새로 디렉토리를 생성하여 마운트한다.
이제 볼륨에 대한 기초와 사용 예시에 대해 알아보자.
1. Configmap
우리가 정의한 볼륨에 configmap을 포함하여 파일로 저장할 수 있다.
컨피그맵은 이전 포스트로 직접 다룬 적이 있었는데 거기서도 동일하게 볼륨을 잠깐 활용했었다.
컨피그맵은 yaml 파일로 정의해도 되고 kubectl 명령어로 직접 입력해도 된다.
아래는 기본적인 컨피그맵의 yaml 구조다.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
key1: value1
key2: value2
다음 yaml 코드를 통해 볼륨을 생성한 후 컨피그맵을 볼륨에 적용시킨다.
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: configmap-test
mountPath: /etc/configmap
volumes:
- name: configmap-test
configMap:
name: my-configmap
items:
- key: key1
path: my-key1
- key: key2
path: my-key2
컨테이너 내로 직접 접근해서 내용을 확인하면 실제로 yaml 코드에 서 정의한 my-key1과 my-key2라는 이름으로 심볼릭 링크 파일이 생성된다.
링크는 실제로 컨피그맵의 key1을 가리키고 있으므로 파일 내 값은 value1이 들어있을 것이다.
여기서 정의한 볼륨은 일반적인 컨피그맵을 사용한 볼륨으로 파드가 종료되면 함께 사라진다.
하지만 볼륨이 사라지는 것뿐 컨피그맵 자체는 사라지지 않는다.
2. emptyDir
나중에 볼 임시 볼륨 중 하나다.
emptyDir과 같이 빈 디렉토리를 하나 생성해서 해당 디렉토리를 여러 파드가 공유하여 사용할 수도 있다.
이름과 같이 파드가 생존해 있는 동안만 유지되는 볼륨이므로 파드가 제거되면 함께 사라진다.
아래 yaml파일은 용량제한이 500Mi인 빈 디렉토리를 생성하는 것이다.
apiVersion: v1
kind: Pod
metadata:
name: empty-vol
spec:
containers:
- name: test
image: nginx:1.25
volumeMounts:
- name: empty-vol
mountPath: /etc/empty
volumes:
- name: empty-vol
emptyDir:
sizeLimit: 500Mi
공식문서에서는 hostPath, nfs, local PersistentVolume, subPath 등 다양한 케이스로 볼륨을 활용하는 사례가 많다.
하지만 이 사례들까지 확인하는 것은 기초의 범위를 넘어서는 것이므로 설명으로 대신할 것이다.
나도 공부해 봐야 할 부분이므로 자세하게 실습으로 알려줄 수는 없다.
3. hostPath
hostPath는 파드가 호스트 노드의 파일 시스템에 마운트하여 데이터를 주고 받는 역할을 한다.
하지만 이는 많은 보안 위협이 존재하기에 사용하는 것을 권장하지 않으며 반드시 사용해야 한다면 접근 권한을 ReadOnly로 설정하거나 특정 파일이나 디렉토리에 한해서 접근의 범위를 최대한 제한해야 한다.
하지만 hostPath를 사용하는 대신 비슷한 역할을 하는 local 필드로 경로를 지정하는 것이 좋다.
4. nfs
nfs는 파드 스펙에 nfs 마운트 옵션을 기재할 수 없다(공식문서에는파드 스펙에 nfs라는 필드가 있는데 무엇이 맞는지 모르겠다).
사용하려면 마운트 옵션을 서버에서 설정하거나, /etc/nfsmount.conf를 사용해야 한다. 마운트 옵션을 설정할 수 있게 허용하는 퍼시스턴트볼륨을 통해 NFS 볼륨을 마운트할 수도 있다.
nfs로 파일을 공유하려면 공유로 내보낸 nfs서버가 실행중이어야 한다.
5. PersistentVolume
이는 우리나 나중에 알아볼 내용이지만 공식 문서에는 스토리지 클래스를 적용하여 로컬 환경에서 볼륨을 사용하는 사례를 표현하였다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
공식 문서에서 제공하는 yaml 코드로 보면 다음과 같은데 여기서는 PersistentVolume API 오브젝트에 기존에 생성한 스토리지 클래스 API를 사용하는 코드인데 그냥 보더라도 무슨 소리인지 감이 잘 잡히지 않는다.
일단 우리가 이전에 공부했던 노드 어피니티로 볼륨이 마운트되는 노드를 한정하는 것으로 보이지만 아직까지 정확하게 알 수 없으니 나중에 따로 포스터를 올려서 연구해보기로 하자.
6. subPath
단일 파드에서 여러 용도의 볼륨을 공유하는 경우에 유용하게 사용된다.
volumeMounts.subPath 속성을 사용해서 root 대신 참조하는 볼륨 내의 하위 경로를 지정할 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
yaml 코드는 다음과 같은 형태이며 아파치와 mysql 이미지로 컨테이너를 생성하여 mysql에는 환경 변수로 MYSQL_ROOT_PASSWORD를 주입하고 각 컨테이너에 퍼시스턴트 볼륨을 마운트하여 아파치는 /var/www/html에서, mysql은 /var/lib/mysql에서 볼 수 있도록 경로를 지정하였다.
클라우드 관련하여 동적 프로비저닝을 위한 볼륨 활용법도 있고 몇몇 볼륨은 사용이 중단된 것도 있다.
자세한 내용은 포스터 상단에 기재한 쿠버네티스 공식 문서에서 확인해보자.
'Kubernetes' 카테고리의 다른 글
Kubernetes 기초 - Storage(3) (0) | 2024.01.22 |
---|---|
Kubernetes 기초 - Storage(2) (0) | 2024.01.20 |
Kubernetes 기초 - Scheduling(6) (0) | 2024.01.10 |
Kubernetes 기초 - Scheduling(5) (0) | 2024.01.09 |
Kubenets 기초 - Scheduling(4) (0) | 2024.01.06 |