Введение

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

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

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

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

nfs illustration for: Предварительные требования

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

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

Примечание. Начиная с версии 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

				
			

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

				
					
[secondary_label Output]

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, необходимо установить таблицу 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 и выше поддерживает расширение тома, поэтому изменение размера этого тома необходимо выполнять вручную, если вы используете более раннюю версию. Если это так, необходимо учитывать будущие потребности при установке данного размера.

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

				
					
[secondary_label Output]

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

				
			

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

				
					
[secondary_label Output]

NAME READY STATUS RESTARTS AGE

nfs-server-nfs-server-provisioner-0 1/1 Running 0 11m

				
			

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

				
					
kubectl get storageclass

				
			

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

				
					
[secondary_label Output]

NAME PROVISIONER AGE

do-block-storage (default) www.progressiverobot.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:

				
					
[label 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

				
			

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

				
					
[secondary_label Output]

deployment.apps/web created

persistentvolumeclaim/nfs-data created

				
			

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

				
					
kubectl get pods

				
			

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

				
					
[secondary_label Output]

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

				
			

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

				
					
[secondary_label Output]

deployment.extensions/web scaled

				
			

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

				
					
kubectl get pods

				
			

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

				
					
[secondary_label Output]

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

В последнем шаге вы должны будете убедиться, что все три экземпляра, смонтированные на часть 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

				
			

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

				
					
[secondary_label Output]

hello_world

				
			

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

Заключение

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

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