Kubernetes. PV. Постоянный том. Хранилище для монтирования в контейнеры

Материал из Wiki
Перейти к навигации Перейти к поиску

Описание

Создание и подключение постоянного тома (PV) к POD

Ссылки

https://kb.selectel.ru/docs/solutions-and-partner-services/file-storage/sfs-to-kubernetes/sfs-to-kubernetes-cifs/

Описание

Постоянный том (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 (по умолчанию 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 для контейнеров