Развертывание NextCloud в Kubernetes с помощью Kustomize
Кредит: Автор/Pixabay
Развертывание Nextcloud с Redis и MariaBD в Kubernetes стало проще благодаря Kustomize. Найдите полный код на Гитхаб.
Одно из простых удовольствий в жизни — взять несколько старых компьютеров из подвала и вернуть их к жизни, настроив собственный кластер Kubernetes. Жужжание вентиляторов, ненужное мигание индикаторов сервера и чересчур красочные графики на дашборде Grafana радуют сердце.
Хорошо, я признаю, было не так просто настроить Kubernetes, очень мало о нем зная. Но с помощью Интернета и владелец ранчомой кластер с одним узлом запущен и работает на сервере Ubuntu, проксируемом nginx с Raspberry Pi.
Было здорово наблюдать за работой Kubernetes. Но как только новизна прошла, я обнаружил, что не знаю, что делать с кластером. Так что же дальше? Как получить больше опыта работы с Kubernetes? Какие еще интересные вещи я могу сделать с ним? Установка Nextcloud казалась хорошим следующим шагом.
Войти Nextcloud, облачное хранилище с открытым исходным кодом и общее клиент-серверное решение, которое можно установить на частный сервер. Nextcloud похож на личный личный Dropbox с хранилищем, ограниченным только размером жестких дисков хоста. Но что еще более важно, Nextcloud имеет разнообразную архитектуру, что делает его отличным кандидатом для расширения знаний о Kubernetes.
Nextcloud предлагает несколько вариантов установки. Тот, который я выбрал здесь, состоит из следующих компонентов:
- Веб-приложение Nextcloud (PHP + Apache)
- MariaDB для хранения метаданных
- Cron для повторяющихся задач обслуживания
- Redis для распределенного кэширования
Кроме того, веб-приложению требуется постоянное хранилище, в котором оно будет сохранять контент, Cron требует доступа к тому же хранилищу для обслуживания, а Nextcloud необходимо обмениваться данными с MariaDB и Redis.
Будучи разработчиком программного обеспечения с большим стажем, я всегда думаю о структуре и организации кода. Многие проекты по кодированию начинаются с малого, а затем имеют тенденцию к росту, иногда экспоненциальному. Без правильной структуры и инструментов управление этими проектами превращается в кошмар. Чтобы избежать этой потенциальной проблемы, я решил пойти с настроить, решение для настройки шаблонов Kubernetes с открытым исходным кодом.
Шлем— еще один (более популярный) вариант шаблонов для Kubernetes. Тем не менее, он требует некоторой дополнительной настройки и более крутой кривой обучения из-за его более широкого набора функций, поэтому было принято решение начать с Kustomize и отложить изучение Helm на данный момент.
С помощью Kustomize манифесты можно разделить по типу, а затем сгруппировать в папки по компонентам. С корневым файлом настройки создание развертываемого манифеста становится таким же простым, как выполнение одной команды:
kustomize build
В приведенных ниже примерах для краткости опущено большинство метаданных и других посторонних деталей. Они доступны в репозитории GitHub, указанном в конце статьи.
Учитывая зависимости между компонентами, я решил начать с того, у которого нет зависимостей: Redis. Развертывание довольно простое: используйте образ redis:alpine Docker для контейнера и откройте порт 6379.
Redis/deployment.yaml
apiVersion: apps/v1
kind: Deployment ...
spec: ...
template: ...
spec:
containers:
- image: redis:alpine
name: redis
ports:
- containerPort: 6379
...
И предоставьте его как сервис, который будет использоваться веб-приложением Nextcloud.
Службы позволяют обнаруживать контейнеры без прямой ссылки на селектор контейнера или IP-адрес. Другие контейнеры будут ссылаться на Redis с помощью селектора службы, а не селектора контейнера.
Redis/service.yaml
apiVersion: v1
kind: Service ...
spec:
ports:
- port: 6379
...
Нам также нужен файл настройки, чтобы указать Kustomize собрать воедино манифесты. Это простой список файлов yaml в качестве ресурсов Kustomize:
kustomization.yaml — это файлы инструкций для Kustomize. Наличие одного в каждой папке позволяет нам ссылаться на саму папку как на ресурс в корневом файле настройки.
Redis/настройка.yaml
resources:
- deployment.yaml
- service.yaml
MariaDB немного более вовлечен. Развертывание начинается с mariadb:latest с открытым портом 3306. Nextcloud требует, чтобы несколько аргументов командной строки были переданы в базу данных как часть команды запуска. Нам также нужен том постоянного хранилища (с использованием утверждения постоянного тома) и учетные данные базы данных (из секрета K8s). Вот как это выглядит:
mariadb/deployment.yaml
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
spec:
containers:
- name: db
image: mariadb:latest
ports:
- containerPort: 3306
args:
- --transaction-isolation=READ-COMMITTED
- --binlog-format=ROW
- --max-connections=1000
env:
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
key: MYSQL_DATABASE
name: db-secrets
...
volumeMounts:
- mountPath: /var/lib/mysql
name: db-persistent-storage
restartPolicy: Always
volumes:
- name: db-persistent-storage
persistentVolumeClaim:
claimName: db-pvc
Секреты — это один из способов хранения секретов в Kubernetes. Не рекомендуется возвращать файл secret.yaml в систему управления версиями, поскольку учетные данные там не зашифрованы. Лучшим решением было бы использовать Запечатанные секреты Битнами.
mariadb/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secrets
type: Opaque
data:
MYSQL_DATABASE: bmV4dGNsb3Vk #nextcloud
MYSQL_USER: bmV4dGNsb3Vk #nextcloud
MYSQL_PASSWORD: <any-base64-encoded-password>
MYSQL_ROOT_PASSWORD: <a-different-base64-encoded-password>
По умолчанию контейнеры Kubernetes получают эфемерное хранилище (то есть хранилище, которое исчезает при удалении контейнера). Чтобы получить постоянное хранилище, контейнер может инициировать Persistent Volume Claim (или PVC) и позволить Kubernetes предоставить том через обработчик хранилища (я использую OpenEBS).
mariadb/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
и сервис, чтобы сделать его легко доступным из веб-приложения:
mariadb/service.yaml
apiVersion: v1
kind: Service
...
spec:
ports:
- port: 3306
selector:
component: db
Завязываем все вместе с файлом кастомизации
mariadb/настройка.yaml
resources:
- secret.yaml
- pvc.yaml
- deployment.yaml
- service.yaml
Наконец, когда зависимости готовы, мы можем заняться веб-приложением и его помощником cron. Развертывание использует образ nextcloud:apache, ссылается на карту db-secret, созданную ранее, и требует постоянного тома (большого, чтобы вместить содержимое).
Nextcloud использует учетные данные базы данных в карте Secrets, созданной ранее, для входа в MariaDB, создания базы данных nextcloud, а затем доступа к базе данных для обычных операций.
nextcloud/deployment.yaml
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
...
spec:
containers:
- image: nextcloud:apache
name: app
ports:
- containerPort: 80
env:
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
key: MYSQL_DATABASE
name: db-secrets
...
volumeMounts:
- mountPath: /var/www/html
name: app-persistent-storage
restartPolicy: Always
volumes:
- name: app-persistent-storage
persistentVolumeClaim:
claimName: app-pvc
nextcloud/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
Нам также нужен сервис для упрощения обнаружения.
nextcloud/service.yaml
apiVersion: v1
kind: Service
...
spec:
ports:
- port: 80
selector:
component: app
Наконец, будучи точкой входа в наше приложение, пользователям нужен своего рода URL-адрес для доступа к нему. Для этого мы создаем Ingress, который указывает на службу приложений nextcloud. Этот конкретный использует cloud.example.com, поэтому вам следует изменить его, прежде чем продолжить.
Ingress — это объект Kubernetes, который управляет внешним доступом к кластеру. Хотя поды внутри кластера могут ссылаться друг на друга через внутренние IP-адреса и службы, они, как правило, недоступны из сетей, внешних по отношению к Kubernetes, без записи Ingress. Я использую вход nginx по умолчанию.
nextcloud/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: default
spec:
rules:
- host: cloud.example.com
http:
paths:
- backend:
serviceName: app
servicePort: 80
Затем мы связываем все это вместе с помощью простого файла настройки.
nextcloud/настройка.yaml
resources:
- pvc.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
Последний компонент — cron. Контейнер использует тот же образ nextcloud:apache, и ему требуется доступ к постоянному хранилищу веб-приложения.
cron/deployment.yaml
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
...
spec:
containers:
- image: nextcloud:apache
name: cron
command:
- /cron.sh
volumeMounts:
- name: app-persistent-storage
mountPath: /var/www/html
restartPolicy: Always
volumes:
- name: app-persistent-storage
persistentVolumeClaim:
claimName: app-pvc
и файл настройки
cron/настройка.yaml
resources:
- deployment.yaml
Теперь, когда все компоненты готовы к работе, как нам заставить Nextcloud видеть mariadb и redis? это легко, вроде. Установите переменные среды MYSQL_HOST и REDIS_HOST в контейнере nextcloud, и образ Docker обнаружит их и автоматически настроит приложение. Но как тогда установить эти значения? с варами конечно!
Мы используем Kustomize «vars», которые позволяют нам установить переменную в ссылку на объект для последующего использования в сборке Kustomize. В kustomization.yaml в корне нашего проекта мы устанавливаем две переменные для сервисных контейнеров для mariadb и redis:
Атрибут bases ссылается на папки, содержащие файл kustomization.yaml.
настройка.yaml
namespace: nextcloud
namePrefix: nextcloud-
commonLabels:
app: nextcloud
version: "15"
bases:
- redis
- mariadb
- nextcloud
- cron
patchesStrategicMerge:
- patch.yaml
vars:
- name: DB_SERVICE
objref:
apiVersion: v1
kind: Service
name: db
- name: REDIS_SERVICE
objref:
apiVersion: v1
kind: Service
name: redis
Затем мы используем патч Kustomize, чтобы установить переменные среды в контейнере приложения nextcloud в значения, захваченные переменными:
патч.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
containers:
- name: app
env:
- name: MYSQL_HOST
value: $(DB_SERVICE)
- name: REDIS_HOST
value: $(REDIS_SERVICE)
Вот и все! Мы готовы к развертыванию.
Благодаря Kustomize развернуть 15+ Kubernetes очень просто. В корне папки проекта просто запустите:
kustomize build | kubectl apply -f -
Войдите в Rancher или используйте kubectl, чтобы проверить, готово ли приложение, а затем перейдите по входному URL-адресу, чтобы загрузить Nextcloud.
Чтобы быть доступным из Интернета, Nextcloud требует HTTPS-соединения. Эта настройка предполагает, что завершение TLS происходит за пределами Rancher и Kubernetes. В моей настройке я использую отдельный компьютер (Raspberry Pi) с nginx и Let’s Encrypt для обработки TLS, а затем перенаправлять обычный трафик на сервер ранчера.
Хотите попробовать развертывание в собственном кластере? Полный код доступен на Гитхаб.