Joomla в k8s на примере данного сайта (YAML manifests)

02 February 2025

В этой статье разберём, как развернуть Joomla и MySQL в кластере Kubernetes с помощью YAML-манифестов. Все примеры основаны на реальной конфигурации devopz.tech.


Будем использовать:

  • StorageClass / PV / PVC — постоянное хранилище
  • Secrets — для хранения паролей и токенов
  • Deployments и Services — для MySQL и Joomla

1. StorageClass — локальное хранилище

Мы используем локальное хранилище с kubernetes.io/no-provisioner, что означает ручное управление томами. Необходимо заранее создать директории на узлах кластера (например: /mnt/k8s/mysql-data и /mnt/k8s/joomla-data).

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

2. PersistentVolume и PersistentVolumeClaim

Создадим PV и PVC для MySQL и Joomla. Важно: storage в PVC не должен превышать capacity в PV.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /mnt/k8s/mysql-data
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: joomla-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /mnt/k8s/joomla-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-storage
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: joomla-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-storage

3. Secrets — безопасное хранение данных

В секрете gldr-secrets хранится dockerconfig для приватного реестра. Также создаются отдельные секреты для MySQL и Joomla с паролями и пользователями (в base64).

apiVersion: v1
data:
  .dockerconfigjson: <base64>
kind: Secret
metadata:
  name: gldr-secrets
type: kubernetes.io/dockerconfigjson
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
type: Opaque
data:
  mysql-root-password: <base64>
  mysql-user: <base64>
  mysql-password: <base64>
---
apiVersion: v1
kind: Secret
metadata:
  name: joomla-secrets
type: Opaque
data:
  JOOMLA_DB_PASSWORD: <base64>
  JOOMLA_DB_USER: <base64>

Секреты кодируются командой:

echo -n "root" | base64

4. MySQL Deployment + Service

MySQL поднимается как отдельный Deployment с PVC для хранения данных и доступом по ClusterIP без внешнего IP.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: registry.devopz.space/kowalski/devopz/mysql:5.7
        resources:
          limits:
            cpu: "100m"
            memory: "100Mi"
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: mysql-root-password
        - name: MYSQL_DATABASE
          value: jdb
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: mysql-user
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: mysql-password
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      imagePullSecrets:
      - name: gldr-secrets
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  selector:
    app: mysql
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306
  clusterIP: None

5. Joomla Deployment + Service

Joomla контейнер подключается к БД через внутренний сервис mysql, получает креды из секретов, использует PVC для хранения данных сайта (медиа, плагины и т.д.).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: joomla
spec:
  replicas: 1
  selector:
    matchLabels:
      app: joomla
  template:
    metadata:
      annotations:
        rollme: "now"
      labels:
        app: joomla
    spec:
      containers:
      - name: joomla
        image: registry.devopz.space/kowalski/devopz/joomla:3.10.11-php7.4-apache
        resources:
          limits:
            cpu: "100m"
            memory: "100Mi"
        env:
        - name: JOOMLA_DB_HOST
          value: mysql
        - name: JOOMLA_DB_USER
          valueFrom:
            secretKeyRef:
              name: joomla-secrets
              key: JOOMLA_DB_USER
        - name: JOOMLA_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: joomla-secrets
              key: JOOMLA_DB_PASSWORD
        - name: JOOMLA_DB_NAME
          value: jdb
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: gldr-secrets
      volumes:
      - name: joomla-persistent-storage
        persistentVolumeClaim:
          claimName: joomla-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: joomla
spec:
  selector:
    app: joomla
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort

6. Применение манифестов

Соберём все файлы в директорию k8s/joomla и применим:

kubectl apply -f k8s/joomla/
kubectl get pods
kubectl get svc

После старта вы получите Joomla, работающую внутри Kubernetes, с постоянным хранилищем, приватным реестром и секретами.


Заключение

  • StorageClass + PV/PVC — для сохранения данных MySQL и Joomla
  • Secrets — защита паролей и токенов
  • Deployments & Services — оркестрация Joomla и MySQL

Такой подход позволяет легко переносить сайт между средами, масштабировать, обновлять и бэкапить данные без ручного вмешательства.

Следующий шаг — добавить Ingress с доменом и TLS (например, через cert-manager).

Leave a comment

Popular Posts

Advertisement

Headlines