Drupal 9 + MySQL 5.7 su Kubernetes

  • Di
  • 2023-11-02 - 5 minuti
banner

Drupal è un CMS piuttosto popolare con una grande community dietro, ed è particolarmente popolare tra le grandi aziende e per i siti web complessi. Infatti, alcuni dei siti più visitati al mondo come Nokia, Wish, NASA utilizzano Drupal come CMS per i loro siti aziendali.

In questo post, andremo a vedere come configurare un’istanza di Drupal versione 9.5 con MySQL 5.7 su Kubernetes.

Spoiler: sarà più lungo l’articolo che la sua effettiva realizzazione!

Questo è lo schema di ciò che otterremo alla fine:

Persistenza

Sappiamo che i container non sono persistenti, quindi è necessario utilizzare dei Persistent Volumes per preservare i dati che Drupal dovrà salvare… Altrimenti, tutte le modifiche scritte nel database o in qualsiasi directory andranno perse dopo il riavvio del container!

Andiamo quindi a definire due PVC, supponendo che il cluster Kubernetes su cui lavoriamo abbia a disposizione un provisioner che si occupa di eseguire il binding tra le claim per lo storage e i volumi persistenti.

In questo caso richiediamo due volumi da 5 GB ciascuno, dove il primo sarà usato per i file del sito web e il secondo per il database MySQL. Chiaramente, questo dimensionamento è adatto a un ambiente di test o di demo, ma possono essere adattati!

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: drupal-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

Invece, per installare l’istanza di MySQL utilizzeremo un Deployment e un Service. Si noti che eseguiamo MySQL con un’utenza amministrativa, che può essere anche cambiata seguendo le indicazioni presenti nella documentazione ufficiale.

Infatti, quando lo si utilizza in produzione, utilizzare credenziali personalizzate e sicure. Peraltro, è buona pratica memorizzare questo tipo di informazioni in un Secret, per cui procediamo con la sua definizione e includiamo la password dell’utente root:

apiVersion: v1
kind: Secret
metadata:
  name: mysql-creds
stringData:
  MYSQL_ROOT_PASSWORD: root_password

Il Deployment di MySQL è piuttosto semplice: utilizza un’immagine mysql nella versione 5.7.8, tra le ultime disponibili e compatibili con la versione 9 di Drupal (vedi documentazione).

Inoltre, definiamo quelle che sono le variabili di ambiente che l’istanza dovrà utilizzare per configurare il database su cui l’istanza Drupal andrà a lavorare, e poi definiamo anche la porta 3306 come porta di ascolto per gli altri servizi e anche il path su cui il volume di MySQL creato in precedenza verrà montato.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-creds
                  key: MYSQL_ROOT_PASSWORD
            - name: MYSQL_DATABASE
              value: drupal-database
          image: "mysql:5.7.8"
          imagePullPolicy: IfNotPresent
          name: mysql
          ports:
            - containerPort: 3306
              name: mysql
              protocol: TCP
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: drupal-pvc
              subPath: dbdata
      volumes:
        - name: drupal-pvc
          persistentVolumeClaim:
            claimName: mysql-pvc
  selector:
    matchLabels:
      app: mysql

Il Deployment di Drupal sarà basato su un container con un’immagine di Drupal dal repository Docker Hub pari all’ultima versione ad oggi disponibile, ossia la 9.5.11.

Inoltre, utilizzeremo anche un container temporaneo (ovvero, un initContainer) la cui missione sarà quella di pre-popolare lo storage persistente con i dati utilizzati da Drupal.

Questo controller esporrà la porta 80 e ugualmente monterà un proprio volume con diverse cartelle per ogni componente necessario a Drupal per lavorare, come i themes, i modules o i sites.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: drupal
  name: drupal
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: drupal
    spec:
      initContainers:
        - name: init-sites-volume
          imagePullPolicy: IfNotPresent
          image: drupal:9.5.11
          command: ['/bin/bash', '-c']
          args: ['cp -r /var/www/html/sites/ /data/; chown www-data:www-data /data/ -R']
          volumeMounts:
            - mountPath: /data
              name: pvc-drupal
      containers:
        - image: drupal:9.5.11
          imagePullPolicy: IfNotPresent
          name: drupal
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /var/www/html/modules
              name: pvc-drupal
              subPath: modules
            - mountPath: /var/www/html/profiles
              name: pvc-drupal
              subPath: profiles
            - mountPath: /var/www/html/sites
              name: pvc-drupal
              subPath: sites
            - mountPath: /var/www/html/themes
              name: pvc-drupal
              subPath: themes

      volumes:
        - name: pvc-drupal
          persistentVolumeClaim:
            claimName: drupal-pvc

  selector:
    matchLabels:
      app: drupal

Ultimo, ma non ultimo, creiamo i Service necessari per permettere ai due componenti di comunicare: quello per MySQL sarà di tipo ClusterIP, dal momento che dovrà interfacciarsi solo con Drupal, mentre quello per Drupal sarà di tipo LoadBalancer.

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  ports:
    - name: mysql
      port: 3306
      protocol: TCP
  selector:
    app: mysql

A seconda del tipo di infrastruttura Kubernetes su cui stiamo lavorando, sarà infatti possibile accedere all’istanza tramite browser: nel caso in cui si usi un cluster EKS su AWS, questo andrà a creare un Application Load Balancer che potremo usare per accedere alla prima pagina di Drupal:

apiVersion: v1
kind: Service
metadata:
  name: drupal-service
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
  selector:
    app: drupal
  type: LoadBalancer

Ora che la nostra soluzione è stata definita e importata, installiamo Drupal. È sufficiente navigare verso l’indirizzo ottenuto nel passaggio precedente e seguire le istruzioni per l’installazione guidata. Utilizzate le credenziali del database configurate in precedenza nel Deployment di MySQL.

Ad esempio, nel nostro caso, ecco i dati da specificare nella schermata di configurazione del database:

  • Nome del database: drupal-database, come la variabile d’ambiente MYSQL_DATABASE nel Deployment di MySQL.
  • Password del database: root_password, come la variabile d’ambiente MYSQL_PASSWORD nel Secret di MySQL.
  • Host: mysql-service, uguale al nome del Service MySQL
  • Porta: 3306, uguale alla porta specificato nel Service MySQL

Questo è tutto!

Ora avete un’istanza di Drupal funzionante, distribuita in meno di 10 minuti.

Post correlati

Iscriviti al TheRedCode.it Corner

La tecnologia corre, e tu devi correre più veloce per rimanere sempre sul pezzo! 🚀

Riceverai una volta al mese (o anche meno) con codici sconto per partecipare agli eventi del settore, quiz per vincere dei gadget e i recap degli articoli più interessanti pubblicati sul blog

Ci sto!

Partners

Community, aziende e persone che supportano attivamente il blog

Logo di Codemotion
Logo di GrUSP
Logo di Python Milano
Logo di Schrodinger Hat
Logo di Python Biella Group
Logo di Fuzzy Brains
Logo di Django Girls
Logo di Improove
Logo del libro open source
Logo di NgRome

Vuoi diventare #tech content writer? 🖊️

Se vuoi raccontare la tua sul mondo #tech con dei post a tema o vuoi condividere la tua esperienza con la community, sei nel posto giusto! 😉

Manda una mail a collaborazioni[at]theredcode.it con la tua proposta e diventa la prossima penna del blog!

Ma sì, facciamolo!