Kubernetes wspiera różne typy wolumenów (jest to odpowiednik wolumenów Docker w świecie Kubernetes). Główny podział to na te efemeryczne (związane mocno z cyklem życia podów) oraz trwałe (persistent volumes).
Efemeryczne wolumeny (ephemeral volumes)
Wolumeny efemeryczne bardzo przypominają standardowe mechanizmy wolumenów Dockerowych – istnieją przez czas życia instancji Dockera (silnika Docker) czyli dopóki ta instancja nie zostanie usunięta. A w klastrze Kubernetes, Docker jest zainstalowany w ramach każdego poda. No i tak dochodzimy do powiązania wolumenów efemerycznych z podami. Pod może być usunięty na przykład przy błędzie aplikacji (automatycznie jest uruchamiana nowa instancja poda a stara usuwana), a co za tym idzie usuwane są także efemeryczne wolumeny (bo istnieją w ramach instancji Dockera, która zostaje usunięta z wraz z podem).
Czasami takie wolumeny mogą być pożądanym rozwiązaniem, na przykład gdy mówimy o cachowaniu albo testowaniu (na przykład zapis do pliku).
Listę wolumenów efemerycznych można znaleźć tutaj.
Czy nie mogę użyć wolumenów Dockerowych?
Okazuje się, że Kubernetes nie wspiera możliwości używania natywnych dla Dockera wolumenów. Po prostu używa własnej obsługi wolumenów, a podyktowane jest to innymi poziomami abstrakcji (przykładowo w Kubernetes najmniejszym elementem jest pod).
Trwałe wolumeny (persistent volumes)
Trwałe wolumeny, jak sama nazwa wskazuje, pozwalają na trwały zapis danych, takich jak na przykład składowanie plików, czy składowanie logów.
Listę trwałych wolumenów można znaleźć tutaj.
Przykłady
emptyDir
emptyDir jest wolumenem działającym w ramach poda (jest wolumenem efemerycznym). Jest to zbliżona opcja do Dockerowego bind mounts z tym, że jak sama nazwa mówi na początku skonfigurowany katalog jest pusty. Sam wolumen jest tworzony wykorzystując składnię:
volumes:
- name: your-volume-name
emptyDir: {}a użycie go w ramach kontenera definiowane jest w następujący sposób:
containers:
- name: your-container-name
image: your-image
volumeMounts:
- name: your-volume-name
mountPath: /app/data gdzie mountPath wskazuje na ścieżkę w kontenerze, która to będzie powiązana z zdefiniowaną w ramach wolumenu (początkowo pustą) ścieżką.
Pełna konfiguracja deploymentu:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: your-container-name
image: your-image
volumeMounts:
- name: your-volume-name
mountPath: /app/data
volumes:
- name: your-volume-name
emptyDir: {}
hostPath jest wolumenem działającym w ramach node’a. Jest to także podobna opcja do Dockerowego bind mounts, z tym, że tutaj katalog nie musi być pusty.
Co ciekawe jest to typ trwały wolumenów, ale w dokumentacji można przeczytać, że jest to trwały rodzaj wolumenu tylko gdy używamy jednego node’a.
Taki wolumen konfigurujemy w następujący sposób:
volumes:
- name: your-volume-name
hostPath:
path: /your/host/path
type: DirectoryOrCreategdzie path wskazuje na konkretną ścieżkę w ramach node’a a type: DirectoryOrCreate mówi o tym, żeby sięgnąć do wcześniej zdefiniowanej ścieżki lub ją stworzyć jeśli jej nie ma.
Użycie wolumenu w ramach kontenera jest podobne jak w innych przypadkach:
ontainers:
- name: your-container-name
image: your-image
volumeMounts:
- name: your-volume-name
mountPath: /app/datagdzie mountPath, jest ścieżką w kontenerze powiązaną ze ścieżką hostPath.path.
Pełna konfiguracja deploymentu:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: your-container-name
image: your-image
volumeMounts:
- name: your-volume-name
mountPath: /app/data
volumes:
- name: your-volume-name
hostPath:
path: /your/host/path
type: DirectoryOrCreate
Oczywiście możliwe jest skonfigurowanie powyższych za pomocą Persistent Volume oraz Persistent Volume Claim.
