Описание работ
В этой статье будет рассказано как развернуть WordPress в панели управления Managed Kubernetes в Vscale. После прочтения ты научишься создавать и настраивать кластер, а также устанавливать сервисы с помощью манифестов.
Зачем разворачивать WordPress в Kubernetes?
Разворачивание WordPress в Kubernetes имеет несколько важных преимуществ:
- Масштабируемость: Kubernetes позволяет легко масштабировать приложение в зависимости от нагрузки, обеспечивая стабильную работу сайта даже при резких скачках посещаемости.
- Высокая доступность: Благодаря распределению нагрузки и управлению репликами, Kubernetes обеспечивает высокую доступность приложения, минимизируя время простоя.
- Автоматизация: Kubernetes автоматизирует такие задачи, как восстановление контейнеров после сбоев, управление ресурсами, и обновление приложений, что значительно снижает необходимость ручного администрирования.
- Портативность: Kubernetes поддерживает развертывание приложений в различных облачных средах и локальных серверах, что дает свободу выбора инфраструктуры и облегчает миграцию между провайдерами.
- Безопасность: Использование манифестов для развертывания сервисов помогает стандартизировать конфигурации и внедрять лучшие практики безопасности.
Преимущество Managed Kubernetes в Vscale
Использование Managed Kubernetes в Vscale дает дополнительное преимущество:
- Упрощенное управление: Managed Kubernetes освобождает пользователей от необходимости самостоятельно настраивать и управлять мастер-ноды и инфраструктуру кластеров, позволяя сконцентрироваться на разработке и развертывании приложений, а иногда и сэкономить на обслуживании инфраструктуры.
Подготовка кластера к работе
Шаг 1. Создание кластера
Перейди в Панель управления Vscale и выбери Managed Kubernetes → Кластеры → Создать. В окне укажи любое имя для кластера, например sandbox, и последнюю версию Kubernetes.
В разделе Группа воркер-нод 1 установи необходимое количество нод, в нашем примере их будет три. В конце укажи ресурсы для серверов. Чем они мощнее, тем лучше производительность приложений.

Информация об успешно созданном Kubernetes кластере
Шаг 2. Проверка готовности кластера
Когда статус кластера отображается как ACTIVE, это означает, что он готов к работе. Все воркер-ноды можно найти по пути Облако → Серверы. Они будут отмечены логотипом Kubernetes.

Одна из воркер-нод кластера «sandbox»
Шаг 3. Скачивание и настройка kubeconfig
Далее нужно скачать kubeconfig через панель управления и настроить:

Настройка скачанного kubeconfig
mkdir -p $HOME/.kube
cp -i ./config.yaml $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Для повышения удобства стоит обозначить ноды как воркеры, используя команду:
kubectl label node <НАЗВАНИЕ_НОДЫ> node-role.kubernetes.io/worker=worker
Шаг 4: Проверка состояния нод
Теперь можно запустить команду, чтобы получить информацию о нодах:
kubectl get nodes
В окне видим три воркер-ноды и статус Ready. Отлично! Команда работает, доступ есть, а значит можем продолжать настройку.

Результат выполнения команды
Установка Ingress Controller и Cert Manager
Зачем нужны Ingress Controller и Cert Manager
Ingress управляет внешними доступами к сервисам внутри кластера. Cert Manager автоматизирует управление сертификатами для обеспечения безопасности через HTTPS. Если они не нужны, можете смело пропускать этот шаг.
Шаг 1: Установка Nginx Ingress
У Vscale уже есть готовая инструкция. Рекомендую ею воспользоваться.
Шаг 2: Установка Cert Manager
Cert Manager помогает автоматизировать управление сертификатами TLS в Kubernetes. Это особенно полезно для обеспечения безопасности будущего WordPress-сайта.
Зачем это нужно? Cert Manager автоматически управляет получением и обновлением сертификатов SSL/TLS, что обеспечивает безопасное соединение для будущего веб-приложения. Это избавляет от необходимости вручную управлять сертификатами и помогает избежать проблем, связанных с устаревшими или недействительными сертификатами.
Примени манифест с помощью данной команды, чтобы установить Cert Manager:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml
Убедись, что все компоненты Cert Manager установлены и запущены. Он состоит из множества компонентов. Они должны успешно запуститься и работать в нужном состоянии:
kubectl get pods -n cert-manager
Все поды должны находиться в состоянии "Running".
Шаг 3: Добавление ClusterIssuer
Чтобы автоматически создавать HTTPS-сертификаты с помощью Let's Encrypt, тебе необходимо добавить ClusterIssuer.
ClusterIssuer – это ресурс Kubernetes, который определяет источник сертификатов и способ их получения. Он позволяет Cert Manager автоматически управлять сертификатами TLS в кластере.
- Создай манифест для продакшен-ClusterIssuer. Этот манифест указывает на использование Let's Encrypt для получения сертификатов:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod # Имя ClusterIssuer
namespace: cert-manager # Namespace, в котором находится ClusterIssuerspec:
acme: # Используем ACME протокол для получения сертификатов
email: <Ваш email адрес>
server: https://acme-v02.api.letsencrypt.org/directory # URL сервера ACME
privateKeySecretRef:
name: letsencrypt-prod # Имя секрета, где будет храниться приватный ключ
solvers:
- http01: # Используем HTTP-01 метод проверки владения доменом
ingress:
class: nginx # Ингресс-контроллер, используемый для прохождения проверок
Примени этот манифест в кластере:
kubectl apply -f path/to/your/cluster-issuer-prod.yaml
- Создай манифест для тестового ClusterIssuer. Этот вариант используется для тестирования и указывает на staging сервер Let's Encrypt:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
email: <Ваш email адрес>
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: nginx
Примени этот манифест в кластере:
kubectl apply -f path/to/your/cluster-issuer-staging.yaml
Зачем это нужно? Создание двух ClusterIssuer (для продакшена и тестирования) решает несколько задач:
- Лимиты на запросы: Let's Encrypt накладывает жесткие ограничения на количество запросов к их продакшен-серверу (например, количество обновлений и выпусков сертификатов). Использование staging сервера позволяет вам тестировать конфигурации и сценарии без риска превышения этих лимитов и блокировки вашего домена.
- Безопасное тестирование: Staging сервер Let's Encrypt использует тестовые сертификаты, которые не считаются доверенными браузерами. Это позволяет безопасно проверять и отлаживать процессы получения и обновления сертификатов перед тем, как перейти на продакшен.
- Профилактика ошибок: Тестирование с использованием letsencrypt-staging позволяет выявить и устранить ошибки в конфигурациях и процессах автоматизации до того, как они попадут в рабочую среду. Это существенно снижает риск сбоев и проблем в продакшене.
Установка MariaDB и Wordpress
Подготовка
Предварительно тебе нужно создать namespace — изолированное пространство для работы, в котором будет развернут WordPress:
kubectl create ns wordpress
Шаг 1. Подготовка PersistentVolume
PersistentVolume (PV) предоставляет приложениям в Kubernetes долгосрочное хранилище данных. В данном случае, и WordPress, и MariaDB нуждаются в постоянном хранилище для данных веб-сайтов и баз данных соответственно.
- Проверь доступные классы памяти.
Введи команду:
kubectl get storageclass

Список доступных классов памяти
Зачем это нужно? StorageClass определяет, какие типы хранилищ можно использовать для создания PersistentVolume. Это важно для:
- Выбора подходящего типа хранилища: В зависимости от вашего рабочего окружения (например, локальный сервер, или облако) у вас могут быть разные типы хранилищ, такие как SSD, HDD или сетевые файлы.
- Обеспечения производительности и стоимости: Разные классы памяти могут предлагать разные уровни производительности и стоимости. Для базы данных, такой как MariaDB, может потребоваться высокопроизводительное хранилище, тогда как для других целей подойдет более дешевый вариант.
- Автоматического предоставления ресурсов: Некоторые StorageClass поддерживают динамическое предоставление объемов, что может упростить процесс управления хранилищем.
- Выбери предоставленный класс памяти.
Инфраструктура Vscale обо всем позаботилась и предоставляет StorageClass для своего Managed Kubernetes, его можно использовать для создания PersistentVolume и PersistentVolumeClaim, не нагружая стандартные диски воркер-нод.
Зачем это нужно? Использование StorageClass от Vscale позволяет получать автоматические и управляемые объемы хранения, интегрированные с их инфраструктурой напрямую. Это упрощает развертывание PersistentVolume, обеспечивая надежное и производительное хранилище для приложений.
Есть и другие популярные решения, такие как OpenEBS, Rook, Longhorn. Они также предоставляют возможность организации хранилища в Kubernetes-кластере. Однако каждый из этих решений требует:
- Дополнительной установки и настройки: Нужно провести множество шагов по инсталляции и конфигурированию, чтобы эти решения корректно работали в вашем кластере.
- Постоянного обслуживания: Требуется регулярный мониторинг и управление компонентами этих систем, чтобы обеспечить их бесперебойную работу и своевременное обновление.
- Ресурсов на управление: Системные администраторы должны постоянно следить за состоянием хранилищ, управлять масштабированием, выполнять резервное копирование и восстановление данных.
В отличие от этих решений, использование управляемого хранилища от Vscale освобождает от большинства задач по управлению инфраструктурой, предоставляя надежные и простые в использовании PersistentVolume, готовые к мгновенному развертыванию и использованию.
Шаг 2. Установка MariaDB
Создание секретов
В Kubernetes, конфиденциальные данные, такие как логины, пароли и другие чувствительные значения, хранятся в объекте Secrets. Использование Secrets позволяет защитить данные и гарантировать, что они не будут случайно раскрыты. Значения в Secrets должны быть закодированы в формате base64.
Зачем это нужно? Вот несколько причин:
- Безопасность: Секреты предотвращают случайное или несанкционированное раскрытие твоих конфиденциальных данных. Они защищают такие данные от появления в конфигурационных файлах или логах.
- Управляемость: Хранение конфиденциальных данных в Secrets позволяет легко обновлять и управлять ими без необходимости изменять кода приложения.
- Гибкость: Использование Secrets дает возможность назначать различные уровни доступа к чувствительным данным, что повышает уровень безопасности.
Тебе необходимо закодировать значение в формат base64. В Unix-подобных системах это можно сделать с помощью утилиты base64. Закодируем логин и пароль с помощью команды:
echo "текст" | base64
Результат будет что-то вроде:
bXlwYXNzd29yZA==

Результат преобразования значений в base64
Затем, создай файл mariadb-secret.yaml, который будет содержать наши закодированные строки:
apiVersion: v1
kind: Secret
metadata:
name: mariadb-user
namespace: wordpress
labels:
app: mariadb
type: Opaque
data:
password: <Вставить сюда полученное значение для пароля>
username: <Вставить сюда полученное значение для логина>
Создание StatefulSet
StatefulSet — это специальный ресурс Kubernetes, предназначенный для управления состоянием подов. Мы будем использовать StatefulSet для деплоя MariaDB, обеспечивая её устойчивость и надежность.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
namespace: wordpress
spec:
serviceName: "mariadb" # Имя сервиса, к которому будет привязан StatefulSet
selector:
matchLabels:
app: mariadb # Метки для выбора подов, управляемых StatefulSet
replicas: 1 # Количество реплик пода (1 экземпляр MariaDB)
template:
metadata:
labels:
app: mariadb # Метки, которые будут применены к поду
spec:
containers:
- name: mariadb # Имя контейнера
image: mariadb:11.3.2-jammy # Образ Docker для MariaDB
imagePullPolicy: Always # Политика подтягивания образа
ports:
- containerPort: 3306 # Порт, на котором MariaDB будет слушать
env: # Переменные окружения для конфигурации MariaDB
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-user # Имя секрета, который содержит пароль пользователя
key: password
- name: MARIADB_USER
valueFrom:
secretKeyRef:
name: mariadb-user # Имя секрета, который содержит имя пользователя
key: username
- name: MARIADB_DATABASE
value: wordpress # Имя базы данных, которую MariaDB будет использовать
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-user # Имя секрета, который содержит пароль root
key: password
volumeMounts:
- name: storage
mountPath: /var/lib/mysql # Монтирование тома для хранения данных MariaDB
volumeClaimTemplates:
- metadata:
name: storage # Имя PersistentVolumeClaim (PVC)
spec:
accessModes: [ "ReadWriteOnce" ] # Режим доступа: чтение/запись для одного пода
storageClassName: "fast.ru-9a" # Класс хранилища, который будет использоваться
resources:
requests:
storage: 4Gi # Запрошенный объем хранилища на диске (4Gi)
Применяем данный манифест командой:
kubectl apply -f mariadb-statefulset.yaml
Создание Service
Сервис, который будет использоваться для подключения к MariaDB:
apiVersion: v1
kind: Service
metadata:
name: mariadb # Имя сервиса
namespace: wordpress # Пространство имен, в котором будет создан сервис
labels:
app: mariadb # Метка, которая будет применена к сервису
spec:
type: ClusterIP # Тип сервиса (ClusterIP по умолчанию, доступен только внутри кластера)
ports:
- port: 3306 # Порт сервиса, который перенаправляется на порт контейнера MariaDB
selector:
app: mariadb # Метка, используемая для выбора подов, к которым будет подключаться сервис
Применяем данный манифест командой:
kubectl apply -f mariadb-service.yaml
Установка WordPress
Создание PVC
Создание PersistentVolumeClaim (PVC) для хранения WordPress:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-storage # Имя PersistentVolumeClaim (PVC)
namespace: wordpress # Пространство имен, в котором будет создан PVC
labels:
app: wordpress # Метка, которая будет применена к PVC
spec:
storageClassName: fast.ru-9a # Класс хранилища, который будет использоваться
accessModes:
- ReadWriteOnce # Режим доступа: чтение/запись для одного пода
resources:
requests:
storage: 1Gi # Запрошенный объем хранилища на диске (1Gi)
После создания PVC важно проверить их статус, чтобы убедиться, что они готовы к использованию в нашем кластере.
Для этого выполни команду:
kubectl get pvc -n wordpress
Если всё настроено правильно, ты увидишь статус PVC как "Bound", готовых к использованию.

Список PersistentVolumeClaim
Они также отображаются в твоей панели управления кластером.

Список дисков в панели управления
Создание Deployment
Для создания Deployment для WordPress используем следующий манифест:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress # Указываем namespace, в котором создается Deployment
labels:
app: wordpress # Метки для Deployment
spec:
selector:
matchLabels:
app: wordpress # Указываем метки, по которым будут выбраны поды для этого Deployment
strategy:
type: Recreate # Тип стратегии обновления - Recreate, поды будут пересозданы при обновлении
template:
metadata:
labels:
app: wordpress # Метки для подов, созданных этим Deployment
spec:
containers:
- image: wordpress:apache # Контейнер с образом WordPress версии Apache
name: wordpress # Имя контейнера
env: # Список переменных окружения для контейнера
- name: WORDPRESS_DB_HOST
value: mariadb # Адрес базы данных (имя сервиса, что мы создавали ранее)
- name: WORDPRESS_DB_NAME
value: wordpress # Имя базы данных
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: mariadb-user # Ссылка на secret для имени пользователя базы данных
key: username # Ключ в secret
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-user # Ссылка на secret для пароля базы данных
key: password # Ключ в secret
resources: # Ресурсы, запрашиваемые и ограничиваемые контейнером
requests:
memory: 512Mi # Запрашиваемое количество памяти
cpu: 500m # Запрашиваемое количество CPU
limits:
memory: 1024Mi # Максимально допустимое количество памяти
cpu: 1000m # Максимально допустимое количество CPU
ports:
- containerPort: 80 # Открываемый порт контейнера (порт для WordPress)
name: wordpress # Имя порта
volumeMounts:
- name: static-storage # Имя монтируемого тома
mountPath: /var/www/html # Точка монтирования в контейнере
volumes:
- name: static-storage # Имя тома
persistentVolumeClaim:
claimName: wordpress-storage # Ссылка на PersistentVolumeClaim для хранения данных WordPress
Создание Service
Теперь создадим Service для WordPress.
apiVersion: v1
kind: Service
metadata:
name: wordpress # Имя Service
labels:
app: wordpress # Метки для Service
annotations:
loadbalancer.openstack.org/keep-floatingip: "true" # Аннотация для сохранения плавающего IP в OpenStack
loadbalancer.openstack.org/flavor-id: 3265f75f-01eb-456d-9088-44b813d29a60 # Аннотация для указания flavor ID в OpenStack
spec:
ports:
- port: 80 # Порт, по которому Service будет доступен
selector:
app: wordpress # Выбирает поды с меткой app: wordpress
type: LoadBalancer # Тип Service, создающий внешний LoadBalancer
Подробнее о настройке LoadBalancer можно узнать в документации.
После применения манифеста видим, что у нас появился балансировщик в панели управления:

Новый балансировщик
Увидеть все Service можно тоже через консоль:
kubectl get svc -n wordpress

Список Service
Доступ по IP-адресу
Чтобы твой WordPress-сайт был доступен извне, необходимо назначить публичный IP-адрес на одну из воркер-нод Kubernetes-кластера. Например, ты можешь использовать IP-адрес 31.129.57.55. Этот шаг важен, так как без публичного IP-адреса сайт будет доступен только внутри локальной сети кластера, что не позволит пользователям из интернета посещать твой сайт.
Если тебе нужен доступ по домену, то следующим шагом будет создание A-записи у DNS-провайдера и создание Ingress.Это действие связывает твой публичный IP-адрес с доменным именем сайта. Например, если твой домен mysite.ru, создание A-записи позволит пользователям вводить этот адрес в браузере и попадать на данный сайт.
Код манифеста Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress
namespace: wordpress
annotations:
kubernetes.io/ingress.class: nginx # Определяем класс Ingress, указывая nginx в качестве контроллера
cert-manager.io/cluster-issuer: letsencrypt-prod # Аннотация для использования ClusterIssuer от cert-manager
spec:
tls:
- hosts:
- "wordpress.mysite.ru" # Перечисляем хосты для использования TLS
secretName: wordpress-tls # Имя секрета, в котором будут храниться сертификаты TLS
rules:
- host: wordpress.mysite.ru # Хост, для которого действует правило Ingress
http:
paths:
- path: / # Путь, для которого действует правило
pathType: Prefix # Тип пути (Prefix означает, что правило будет применяться ко всем подуровням)
backend:
service:
name: wordpress # Имя сервиса, на который будет перенаправляться трафик
port:
number: 80 # Номер порта сервиса, на который будет перенаправляться трафик
Благодаря ранее добавленному Service с типом LoadBalancer теперь у WordPress появился порт, по которому он доступен вне кластера, — это 31036. По нему ты можешь передавать свои данные прямо из браузера.
Для тестов мне предпочтительнее работать напрямую с IP-адресом, потому что это позволяет удостовериться, что сервис доступен независимо от возможных проблем с DNS или настройками доменных имен. Поэтому можно смело обратиться из браузера по адресу http://31.129.57.55:31036. Если все настроено правильно, у тебя откроется страница установки WordPress.

Установка Wordpress. Выбор языка
Введи свои данные и следуй инструкциям на сайте для завершения установки.

Установка пользователя с правами администратора

Успешное сообщение об установке CMS WordPress
Завершение

Главная страница только что установленной CMS WordPress
Поздравляем! У тебя получилось установить WordPress в Kubernetes.