Site icon 8HOST.COM

Настройка постоянных томов RWX с помощью NFS в управляемом сервисе Kubernetes

Статическое управление и настройка хранилища Kubernetes – довольно сложная задача, поскольку контейнеры имеют распределенный и динамический характер, а рабочие нагрузки могут перемещаться с одной виртуальной машины (ВМ) на другую за считанные секунды. Чтобы решить эту проблему, Kubernetes управляет томами с помощью системы постоянных томов (Persistent Volumes, PV – это объекты API, представляющие конфигурацию или том хранилища) и PersistentVolumeClaims (PVC – это запросы на хранение, который должен удовлетворять постоянный том). Кроме того, Kubernetes предоставляет драйверы Container Storage Interface (CSI), которые помогают автоматизировать и управлять хранилищами для контейнерных рабочих нагрузок. Эти драйверы отвечают за подготовку, монтирование, размонтирование, удаление и создание быстрых копий томов.

В управляемом сервисе Kubernetes разработчики могут автоматизировать оркестровку томов блочного хранилища для контейнерного приложения. Но иногда приложения требуют, чтобы данные постоянно сохранялись и совместно использовались сразу несколькими серверами. Чаще всего стандартные средства CSI не могут монтировать один том хранилища сразу в несколько серверов. Такие средства называются ReadWriteOnce (RWO) – один том привязан к одной ноде.

Смонтировать том сразу на нескольких серверах позволяет протокол Network File System (NFS). Такой подход называется ReadWriteMany (RWX), поскольку сразу несколько нод могут смонтировать один и тот же том с правами на чтение и запись. Следовательно, в подобных ситуациях можно добавить в кластер сервер NFS.

Этот мануал поможет вам настроить динамическую оркестровку томов NFS в управляемом сервисе Kubernetes. В конце мы для примера попробуем развернуть простое приложение Nginx, чтобы убедиться, что все работает правильно.

Требования

Примечание: Начиная с версии Helm 3.0 для корректной работы Helm больше не требуется Tiller. Если вы используете последнюю версию Helm, обратитесь к официальному мануалу по установке.

1: Развертывание сервера NFS с помощью Helm

Читайте также: Основы работы с Helm, пакетным менеджером Kubernetes

Для развертывания сервера NFS мы используем чарты Helm. Чарты Helm – это автоматизированный аналог пакетов, который быстро развертывается и менее подвержен ошибкам, чем развертывание сервера NFS вручную.

Для начала убедитесь, что у вас есть доступ к стабильному хранилищу чартов по умолчанию:

helm repo add stable https://kubernetes-charts.storage.googleapis.com/

Затем извлеките метаданные только что добавленного репозитория. Это обновит клиента Helm:

helm repo update

Чтобы проверить доступ к репозиторию stable, выполните поиск по чартам:

helm search repo stable

Вы получите подобный список доступных чартов:

NAME                             CHART VERSION APP VERSION     DESCRIPTION
stable/acs-engine-autoscaler      2.2.2         2.1.1           DEPRECATED Scales worker nodes within agent pools
stable/aerospike                  0.3.2         v4.5.0.5        A Helm chart for Aerospike in Kubernetes
stable/airflow                    5.2.4         1.10.4          Airflow is a platform to programmatically autho...
stable/ambassador                 5.3.0         0.86.1          A Helm chart for Datawire Ambassador
...

Этот вывод означает, что клиент Helm запущен и обновлен.

Теперь, когда вы подготовили Helm, установите чарт nfs-server-provisioner, чтобы настроить сервер NFS. Если вы хотите изучить содержимое чарта, посмотрите его документацию на GitHub.

При развертывании чарта нужно установить несколько переменных для вашего сервера NFS, чтобы дополнительно указать конфигурацию вашего приложения. Вы также можете изучить другие параметры конфигурации и настроить их в соответствии с потребностями вашего приложения.

Чтобы установить чарт, используйте следующую команду:

helm install nfs-server stable/nfs-server-provisioner --set persistence.enabled=true,persistence.storageClass=block-storage,persistence.size=200Gi

Эта команда предоставляет серверу NFS следующие параметры конфигурации:

Примечание: Опция persistence.size определяет общий объем всех томов NFS, которые вы сможете оркестровать.

После выполнения этой команды на экране появится примерно такой вывод:

NAME: nfs-server
LAST DEPLOYED: Thu Feb 13 19:30:07 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The NFS Provisioner service has now been installed.
A storage class named 'nfs' has now been created
and is available to provision dynamic volumes.
You can use this storageclass by creating a PersistentVolumeClaim with the
correct storageClassName attribute. For example:
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-dynamic-volume-claim
spec:
storageClassName: "nfs"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi

Чтобы просмотреть сервер NFS, который вы только что оркестровали, введите:

kubectl get pods

На экране появится:

NAME                                                   READY   STATUS    RESTARTS   AGE
nfs-server-nfs-server-provisioner-0                    1/1     Running   0          11m

Теперь запросите storageclass:

kubectl get storageclass
NAME                         PROVISIONER                                         AGE
block-storage (default)      bs.csi.my-block-storage.com                         90m
nfs                          cluster.local/nfs-server-nfs-server-provisioner     3m

Теперь у вас есть сервер NFS, а также storageclass, который вы можете использовать для динамической оркестровки томов. Пора создать развертывание, которое будет использовать это хранилище совместно с несколькими экземплярами.

2: Развертывание приложения с помощью совместно используемого PersistentVolumeClaim

На этом этапе мы создадим тестовое развертывание в кластере Kubernetes, чтобы протестировать настройки хранилища. Это будет приложение веб-сервера Nginx по имени web.

Чтобы развернуть это приложение, сначала создайте файл YAML для настроек развертывания. Откройте файл nginx-test.yaml в текстовом редакторе:

nano nginx-test.yaml

В этот файл добавьте следующие строки, чтобы определить развертывание с помощью PersistentVolumeClaim по имени nfs-data:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:latest
name: nginx
resources: {}
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: nfs-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: nfs

Сохраните и закройте файл.

Это развертывание будет использовать сопровождающий PersistentVolumeClaim nfs-data и монтировать его в /data.

В определении PVC вы увидите, что storageClassName задано значение nfs. Это позволяет кластеру использовать для этого хранилища правила nfs storageClass, который вы создали на предыдущем шаге. Новый PersistentVolumeClaim будет обработан, после чего для удовлетворения запроса будет предоставлен общий постоянный том NFS. Модуль будет пытаться смонтировать этот PVC, как только он будет подготовлен. После завершения монтирования вы можете проверить функциональность ReadWriteMany (RWX).

Запустите развертывание с помощью следующей команды:

kubectl apply -f nginx-test.yaml

Она выдаст следующий вывод:

deployment.apps/web created
persistentvolumeclaim/nfs-data created

Теперь проверьте под web:

kubectl get pods

Вы получите такой вывод:

NAME                                                   READY   STATUS    RESTARTS   AGE
nfs-server-nfs-server-provisioner-0                    1/1     Running   0          23m
web-64965fc79f-b5v7w                                   1/1     Running   0          4m

Теперь, когда развертывание запущено, вы можете масштабировать его до трех экземпляров, используя команду kubectl scale:

kubectl scale deployment web --replicas=3

Появится вывод:

deployment.extensions/web scaled

Снова запустите команду kubectl get:

kubectl get pods

Вы увидите, что количество экземпляров развертывания увеличилось:

NAME                                                   READY   STATUS    RESTARTS   AGE
nfs-server-nfs-server-provisioner-0                    1/1     Running   0          24m
web-64965fc79f-q9626                                   1/1     Running   0          5m
web-64965fc79f-qgd2w                                   1/1     Running   0          17s
web-64965fc79f-wcjxv                                   1/1     Running   0          17s

Теперь у вас есть три экземпляра развертывания Nginx, которые подключены к одному и тому же постоянному тому. Нам осталось убедиться, что они могут обмениваться данными друг с другом.

3: Тестирование настройки

Давайте проверим, могут ли экземпляры, которые подключены к общему ресурсу NFS, совместно использовать данные тома. Для этого мы создадим файл в каталоге /data в одном из подов, а затем посмотрим, появился ли этот файл в каталоге /data другого пода.

Вы можете использовать команду kubectl exec. Она позволяет указать под и выполнить команду внутри этого пода.

Чтобы создать файл по имени hello_world в одном из ваших подов, используйте команду kubectl exec для передачи команды touch. Обратите внимание, строка символов после web в имени пода будет отличаться у вас, поэтому не забудьте заменить наше имя пода своим именем.

kubectl exec web-64965fc79f-q9626 -- touch /data/hello_world

Затем укажите другой под и с помощью команды ls выведите список файлов в его каталоге /data:

kubectl exec web-64965fc79f-qgd2w -- ls /data

В выводе будет файл, который вы создали на первом поде:

hello_world

Это значит, что все поды совместно используют данные по протоколу NFS и ваши настройки работают правильно.

Заключение

В этом мануале вы создали сервер NFS для блочного хранилища. Затем сервер NFS использовал это хранилище для экспорта общих ресурсов NFS в рабочие нагрузки по протоколу, совместимому с RWX. При этом вы смогли обойти техническое ограничение блочного хранилища и совместно использовать одни и те же данные PVC в нескольких подах.