Kubernetes. PV. Постоянный том. Хранилище для монтирования в контейнеры
Описание
Создание и подключение постоянного тома (PV) к POD
Ссылки
https://habr.com/ru/company/southbridge/blog/519642/
Описание
Постоянный том (Persistent Volume, PV) — это блочное хранилище заданного размера, которое существует независимо от жизненного цикла пода.
Использование постоянного тома позволит вам управлять или обновлять поды, не беспокоясь о потере кода приложения.
Доступ к постоянному тому можно получить с помощью PersistentVolumeClaim, или PVC, который монтирует постоянный том по требуемому пути.
Настройка
SMB
Установка CSI-драйвера для Samba
Для установки драйвера нужен пакетный менеджер helm.
Скачайте пакетный менеджер helm chart и CSI-драйвер с GitHub Kubernetes CSI.
Установите последнюю версию драйвера
helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts
helm install csi-driver-smb csi-driver-smb/csi-driver-smb --namespace kube-system --version v1.4.0
Проверьте, что поды установлены и запущены:
kubectl --namespace=kube-system get pods --selector="app=csi-smb-controller"
Создание секрета для доступа к SMB ресурсу
Создайте секрет для хранения логина и пароля на сервере SMB (по умолчанию guest/guest)
kubectl create secret generic smbcreds --from-literal username=user1 --from-literal password=PassWord
Создать манифест для StorageClass
nano ./sfs_storage_class.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: smb provisioner: smb.csi.k8s.io parameters: source: "//192.168.1.1/share/code" csi.storage.k8s.io/provisioner-secret-name: "smbcreds" csi.storage.k8s.io/provisioner-secret-namespace: "default" csi.storage.k8s.io/node-stage-secret-name: "smbcreds" csi.storage.k8s.io/node-stage-secret-namespace: "default" reclaimPolicy: Delete volumeBindingMode: Immediate mountOptions: - dir_mode=0777 - file_mode=0777
Примените манифест
kubectl apply -f ./sfs_storage_class.yaml
Проверьте, что StorageClass создался:
kubectl get storageclass
Создать манифест для PersistentVolumeClaim
storage: 10Gi — размер файлового хранилища
nano ./sfs_persistent_volume_claim.yaml:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code annotations: volume.beta.kubernetes.io/storage-class: smb spec: accessModes: ["ReadWriteMany"] resources: requests: storage: 10Gi
Примените манифест в кластер
kubectl apply -f ./sfs_persistent_volume_claim.yaml
Проверьте, что PersistentVolumeClaim создался:
kubectl get pvc
... NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE code Bound pvc-bf00cd44-2c4e-4be0-a588-277c9ff62307 1Gi RWX smb 66m ...
kubectl get pv
... NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-bf00cd44-2c4e-4be0-a588-277c9ff62307 1Gi RWX Delete Bound default/code smb 67m ...
Смотрим что на шаре создалась директория
\\192.168.199.174\share\code\pvc-480016f0-1351-42c9-ba4e-146397c7cd1d\
Подключить хранилище PV в POD (через Deployment)
nano nginx02.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx02 spec: replicas: 2 selector: matchLabels: app: nginx02 strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate template: metadata: labels: app: nginx02 spec: volumes: - name: code persistentVolumeClaim: claimName: code containers: - image: nginx:1.16 name: nginx02 volumeMounts: - name: code mountPath: /code
Применяем
kubectl apply -f nginx02.yaml
Смотрим
kubectl get pods -o wide
... NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx02-69bc47fc78-k6gpz 1/1 Running 0 3s 172.16.213.219 kub-node-3 <none> <none> nginx02-69bc47fc78-zq6q4 1/1 Running 0 3s 172.16.213.187 kub-node-1 <none> <none> ...
Можно зайти в контейнер и убедиться что директория "code" примонтировалась
kubectl exec -i -t pods/nginx02-69bc47fc78-k6gpz -- /bin/bash
root@php-58bd8849c6-bgxz2:/var/www/html# ls -lh /code/
А также создать файл посмотреть что на шаре он появился
root@php-58bd8849c6-bgxz2:/var/www/html# echo 123 > /code/test.txt
Смотрим шару
\\192.168.199.174\share\code\pvc-480016f0-1351-42c9-ba4e-146397c7cd1d\test.txt
Таким образом мы создали постоянное хранилище SMB для контейнеров
CephFS
CEPH сервер
Получаем ключ админа
ceph auth get-key client.admin
... AQAvoRlj44oJDhAApP3iMHMRBCdvh5Xr7346Jg== ...
Получаем ID кластера и IP хостов
ceph mon dump
... fsid 33f476b0-2f4c-11ed-896a-00505682bc3e ... 0: [v2:192.168.199.122:3300/0,v1:192.168.199.122:6789/0] mon.ceph02 1: [v2:192.168.199.123:3300/0,v1:192.168.199.123:6789/0] mon.ceph03 2: [v2:192.168.199.121:3300/0,v1:192.168.199.121:6789/0] mon.ceph01 ...
KUBERNETES сервер управления
Устанавливаем csi драйвер для работы с ceph
helm repo add ceph-csi https://ceph.github.io/csi-charts
Генерируем файл настройки
helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml
Меняем значения в файле cephfs.yml
nano cephfs.yml
... csiConfig: - clusterID: "33f476b0-2f4c-11ed-896a-00505682bc3e" monitors: - "192.168.199.121:6789" - "192.168.199.122:6789" - "192.168.199.123:6789" ... nodeplugin: httpMetrics: enabled: true containerPort: 8091 ... podSecurityPolicy: enabled: true ... provisioner: replicaCount: 1 ... podSecurityPolicy: enabled: true ...
Устанавливаем чарт
helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml
Создаем secret
nano secret.yaml
--- apiVersion: v1 kind: Secret metadata: name: csi-cephfs-secret stringData: # Required for dynamically provisioned volumes adminID: admin adminKey: AQAvoRlj44oJDhAApP3iMHMRBCdvh5Xr7346Jg==
Применяем
kubectl create -f secret.yaml
Создаем storageClass
nano storageclass.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: csi-cephfs-sc provisioner: cephfs.csi.ceph.com parameters: clusterID: 33f476b0-2f4c-11ed-896a-00505682bc3e fsName: cephfs01 csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret csi.storage.k8s.io/provisioner-secret-namespace: default csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret csi.storage.k8s.io/controller-expand-secret-namespace: default csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret csi.storage.k8s.io/node-stage-secret-namespace: default reclaimPolicy: Delete allowVolumeExpansion: true mountOptions: - debug
Применяем
kubectl create -f storageclass.yaml
Создаем PVC
nano pvc.yaml
--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: csi-cephfs-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi storageClassName: csi-cephfs-sc
Применяем
kubectl create -f pvc.yaml
Проверяем
kubectl get pvc
... NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE csi-cephfs-pvc Bound pvc-02520c2a-d5e9-40b6-ae96-5501bcee1c38 1Gi RWX csi-cephfs-sc 3m38s ...
kubectl get pv
... NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-02520c2a-d5e9-40b6-ae96-5501bcee1c38 1Gi RWX Delete Bound default/csi-cephfs-pvc csi-cephfs-sc 3m33s ...
Разворачиваем deployment
Деплоим тестовый деплой с подами
Монтировать cephfs01 внутри пода будем по пути /code
nano nginx02.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx02 spec: replicas: 2 selector: matchLabels: app: nginx02 strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate template: metadata: labels: app: nginx02 spec: volumes: - name: csi-cephfs-pvc persistentVolumeClaim: claimName: csi-cephfs-pvc containers: - image: nginx:1.16 name: nginx02 volumeMounts: - name: csi-cephfs-pvc mountPath: /code
Применяем
kubectl apply -f nginx02.yaml
Зайдем в деплоймент и убедимся что /code смонтирован
kubectl exec -i -t deployments/nginx02 -- /bin/bash
Запишем что-нибудь в /code
echo test > /code/123.txt
Теперь смонтируем на какой-нибудь машине нашу cephfs01 в /mnt/cephfs/ и увидим что по пути
/mnt/cephfs/volumes/csi/csi-vol-b2af5ccc-53c5-11ed-9c10-3ef262910d56/5ba704e9-db75-4143-be0d-e621cbfd0064/
появился файл:
ls -lh /mnt/cephfs/volumes/csi/csi-vol-b2af5ccc-53c5-11ed-9c10-3ef262910d56/5ba704e9-db75-4143-be0d-e621cbfd0064/
... -rw-r--r-- 1 root root 4 Oct 24 21:08 test.txt ...
Удалим и снова создадим деплоймент nginx02
kubectl delete deployments.apps nginx02
kubectl apply -f nginx02.yaml
Зайдем в контейнер и убедимся что наш файл на месте
kubectl exec -i -t deployments/nginx02 -- /bin/bash
ls -lh /code/
... -rw-r--r-- 1 root root 4 Oct 24 18:08 test.txt ...
Таким образом мы создали постоянное хранилище CephFS для контейнеров
EMPTYDIR
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}