Развертывание 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, а затем перенаправлять обычный трафик на сервер ранчера.

Хотите попробовать развертывание в собственном кластере? Полный код доступен на Гитхаб.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *