Настройка постоянных томов ReadWriteMany (RWX) с помощью NFS в DigitalOcean Kubernetes

Введение

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

digitalocean-csi объединяет кластер Kubernetes с блочным хранилищем DigitalOcean. Разработчик может использовать этот инструмент для динамического предоставления томов блочного хранилища для контейнеризованных приложений в Kubernetes. Однако иногда приложениям может требоваться сохранение данных и их передача в нескольких разных дроплетах. Предоставляемое DigitalOcean по умолчанию решение CSI блочного хранилища поддерживает монтирование тома одного блочного хранилища на несколько дроплетов одновременно. Это означает, что это решение ReadWriteOnce (RWO), поскольку том ограничивается одним узлом. Протокол сетевой файловой системы (NFS), напротив, поддерживает экспорт этой же части многим потребителям. Это решение называется ReadWriteMany (RWX), поскольку несколько узлов могут монтировать том для чтения и записи. Поэтому мы можем использовать сервер NFS в нашем кластере, чтобы предоставить хранилище, которое может опираться на надежную основу в виде блочного хранилища DigitalOcean наряду с гибкостью долей NFS.

В этом обучающем руководстве вы настроите динамическое предоставление томов NFS внутри кластера DigitalOcean Kubernetes (DOKS), где экспортируемые данные хранятся в томах блочного хранилища DigitalOcean. Затем вы развернете несколько экземпляров демо-приложения Nginx и протестируете обмен данными между каждым экземпляром.

Предварительные требования

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

  • Интерфейс командной строки kubectl, установленный на локальном компьютере. Дополнительную информацию об установке и настройке kubectl можно найти в официальной документации.

  • Кластер DigitalOcean Kubernetes с вашим подключением, настроенным с помощью kubectl по умолчанию. Процесс создания кластера Kubernetes в DigitalOcean см. в нашем кратком руководстве по работе с Kubernetes. Инструкции по настройке kubectl описаны в шаге Подключение кластера, где вы создадите ваш кластер.

  • Менеджер пакетов Helm, установленный на локальном компьютере, и Tiller, установленный на кластере. Для этого нужно выполнить шаги 1 и 2 руководства Установка программного обеспечения на кластеры Kubernetes с помощью менеджера пакетов Helm.

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

Шаг 1 — Развертывание сервера NFS с Helm

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

Во-первых, необходимо убедиться, что используемый по умолчанию репозиторий таблицы stable доступен для вас, добавив репозиторий:

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

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

  • helm repo update

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

  • helm search repo stable

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

OutputNAME                                 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, необходимо установить таблицу Helm nfs-server-provisioner для настройки сервера NFS. Если вы хотите просмотреть содержимое таблицы, ознакомьтесь с документацией на GitHub.

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

Чтобы установить таблицу Helm, нужно использовать следующую команду:

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

Данная команда позволяет получить сервер NFS со следующими вариантами конфигурации:

  • Добавляет постоянный том для сервера NFS с флагом --set. Это гарантирует, что все совместно используемые данные NFS будут сохраняться при перезапуске пода.
  • Для постоянного хранилища используется класс хранилища do-block-storage.
  • Предоставляет в общей сложности 200Gi, чтобы сервер NFS мог выполнять разбивку при экспорте.

Примечание. Вариант persistence.size будет определять общую емкость всех томов NFS, которые вы можете предоставить. На момент написания этой статьи только версия DOKS 1.16.2-do.3 и выше поддерживает расширение тома, поэтому изменение размера этого тома необходимо выполнять вручную, если вы используете более раннюю версию. Если это так, необходимо учитывать будущие потребности при установке данного размера.

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

OutputNAME: 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

В результате вы получите следующий вывод:

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

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

  • kubectl get storageclass

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

OutputNAME                         PROVISIONER                                       AGE do-block-storage (default)   dobs.csi.digitalocean.com                         90m nfs                          cluster.local/nfs-server-nfs-server-provisioner   3m 

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

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

На этом шаге вы создадите пример развертывания вашего кластера DOKS для проверки настройки вашего хранилища. В этом случае мы будем использовать веб-сервер Nginx с именем web.

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

  • nano nginx-test.yaml

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

nginx-test.yaml

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

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

  • kubectl apply -f nginx-test.yaml

Результат будет выглядеть следующим образом:

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

Теперь убедитесь, что под web запущен:

  • kubectl get pods

В результате вы получите следующий вывод:

OutputNAME                                                   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

Результат будет выглядеть следующим образом:

Outputdeployment.extensions/web scaled 

Теперь запустите команду kubectl get еще раз:

  • kubectl get pods

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

OutputNAME                                                   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

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

Чтобы выполнить эту задачу, воспользуйтесь командой kubectl exec. Эта команда позволяет вам указывать под и запускать команды внутри этого пода. Дополнительную информацию о проверке ресурсов с помощью kubectl можно найти в нашей шпаргалке по kubectl.

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

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

Затем измените имя пода и используйте команду ls, чтобы вывести список файлов в директории /data другого пода:

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

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

Outputhello_world 

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

Заключение

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

Если вы хотите узнать больше о Kubernetes, ознакомьтесь с нашей серией обучающих материалов Kubernetes для разработчиков широкого профиля, или изучите документацию для DigitalOcean Kubernetes.