Экосистема Kubernetes очень динамична и включает в себя различные компоненты, взаимодействующие между собой. Управление хранением данных в Kubernetes является отдельной задачей, в рамках которой вводятся понятия Persistent Volumes (постоянных томов, PVs) и Persistent Volume Claims (запросов на выделение постоянного тома, PVCs).
В этой статье мы рассмотрим, как с помощью Storage Class (классов хранилища) автоматически предоставлять NFS (Network File System) в качестве постоянного тома для Kubernetes. Для автоматизации мы будем использовать Ansible для настройки сервера NFS и Terraform вместе с Helm для настройки NFS-клиента.
Начальные условия
Работающий кластер Kubernetes.
Helm, установленный на вашей локальной машине или в кластере Kubernetes
Ansible, установленный на локальной машине
Terraform, установленный на локальной машине.
Настройка NFS-сервера с помощью Ansible
Создайте плейбук Ansible для настройки NFS-сервера. Пример:
---
- hosts: nfs-server
become: yes
tasks:
- name: Update all packages
apt:
update_cache: yes
- name: Install NFS server package
apt:
name: nfs-kernel-server
state: present
- name: Create a directory to share
file:
path: /var/nfs_share
state: directory
mode: '777'
- name: Modify ownership & permissions of the shared directory
file:
path: /var/nfs_share
owner: nobody
group: nogroup
mode: '777'
- name: Add the directory to the NFS configuration file
lineinfile:
path: /etc/exports
line: '/var/nfs_share *(rw,sync,no_subtree_check,no_root_squash)'
- name: Export the shared directory and restart NFS service
command:
cmd: exportfs -a && systemctl restart nfs-kernel-server
Запустите плейбук с помощью Ansible. Вот пример того, как это может выглядеть в вашей командной оболочке:
ansible-playbook -i inventory.ini nfs_server.yaml
Этот плейбук установит NFS-сервер на целевой хост, создаст и сконфигурирует общий каталог (NFS-экспорт), и перезапустит службу NFS.
Настройка NFS-клиента с помощью Terraform и Helm
Для развертывания Helm Charts в кластере Kubernetes можно использовать Terraform. Ниже приведен пример сценария Terraform для установки NFS-клиента с использованием Helm-чарта nfs-subdir-external-provisioner.
Установите провайдер Terraform для работы с Helm:
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
Добавьте репозиторий, содержащий Helm-чарт
“nfs-subdir-external-provisioner”
:
data "helm_repository" "nfs" {
name = "nfs-subdir-external-provisioner"
url = "https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/"
}
Установите клиент NFS provisioner. Замените шаблоны
<nfs-server>
и<nfs-path>
на IP-адрес вашего NFS-сервера и путь к экспортированному NFS-каталогу:
resource "helm_release" "nfs_client_provisioner" {
name = "nfs-client-provisioner"
repository = data.helm_repository.nfs.metadata[0].name
chart = "nfs-subdir-external-provisioner"
set {
name = "nfs.server"
value = "<nfs-server>"
}
set {
name = "nfs.path"
value = "<nfs-path>"
}
}
Выполните сценарий Terraform. Вот пример того, как это может выглядеть в вашей среде:
terraform init
terraform apply
Сценарий Terraform инициализирует Helm-провайдер, добавит Helm-репозиторий, содержащий nfs-subdir-external-provisioner и установит NFS client provisioner в кластер Kubernetes.
Проверка установки
Проверьте, запущен ли NFS client provisioner:
kubectl get pods
Вы должны увидеть pod с названием nfs-client-provisioner-...
в статусе RUNNING.
Проверьте, создан ли Storage Class:
kubectl get sc
В списке должен появиться Storage Class с именем nfs-client
(или тем именем, которое вы указали при установке).
Теперь, когда вы создаете Persistent Volume Claim со Storage Class “nfs-client”
, Kubernetes будет динамически предоставлять Persistent Volume, используя указанный вами NFS-сервер и путь.
Установка Postgresql с помощью провайдера
Создадим ресурс Terraform helm_release
для установки чарта PostgreSQL:
data "helm_repository" "bitnami" {
name = "bitnami"
url = "https://charts.bitnami.com/bitnami"
}
resource "helm_release" "postgresql" {
name = "postgresql"
chart = "bitnami/postgresql"
repository = data.helm_repository.bitnami.metadata[0].name
set {
name = "persistence.storageClass"
value = "nfs-client"
}
set {
name = "persistence.size"
value = "1Gi"
}
}
Этот Helm-чарт создаст Deployment c базой данных PostgreSQL, которая использует PersistentVolumeClaim для хранения данных. PVC использует Storage Class nfs-client, задействующий сервер NFS и путь, указанные в нашем предыдущем сценарии Terraform.
После добавления вышеуказанных ресурсов в сценарий Terraform, вы можете применить конфигурацию:
terraform apply
После завершения работы сценария убедитесь, что Kubernetes Deployment и Service для PostgreSQL запущены:
kubectl get deployments
kubectl get svc
Чтобы дополнительно убедиться в том, что данные PostgreSQL действительно хранятся на NFS-сервере, можно проверить точки подключения пода:
kubectl describe pod <postgresql-pod-name>
Вы увидите подключение (mount) для /bitnami/postgresql
, а его PersistentVolumeClaim должен использовать класс хранения NFS.
Текст подготовлен при помощи инженеров Southbridge
От редакции
Говорить об Ansible можно очень много: этим-то мы и планируем заняться! Уже 10 августа пройдет первая встреча из цикла «IaC с Ansible». Наши инженеры поделятся подходами и покажут практическую сторону дела — решения, которые использовали в реальном продакшене. И их можно забрать в своё пользование!
Первая встреча пройдет 10 августа.
Зарегистрироваться на встречи можно по этой ссылке: https://southbridge.io/iac-ansible-southbridge
atshaman
Не очень понятна цель упражнения - раздать nfs со сторажки в кластер - ок, норм, пусть и не самый сладкий сахарн.
Делать самому... отказоустойчиовсти у решения нет - single point of failure на пустом месте. Делать nfs поверх кластеризованной ФС - того же gluster'а конечно можно - но прям такоЭ. Использовать для stateful-приложений, которые самостоятельно умеют в кластеризацию и репликацию данных - нуууу ооок, но не проще ли тогда local persistent volumes обмазаться - в плане удобства работы\управления\отказоустойчивости то на то будет минус оверхед на nfs. Опять же надо на структуру хранения смотреть - nfsv4 прям не любит большое количество файлов в одном каталоге, в tencent cloud для аналогичного сетапа прям непосредственная рекомендация - приколачивайте гвоздями nfsv3.
Если уж nfs нам зачем-то нужен - то почему kernel реализация, а не nfs-ganesha? Последний определенно быстрее и лучше себя ведет при разрывах связи - с ним я с ситуацией "полного зависания сервера" не сталкивался, а вот с kernel nfs - было.
В общем, троллейбус из буханки конечно почти как настоящий - но зачем?