Magento 2 auf Kubernetes – wie funktioniert das?

In diesem Artikel nehmen wir die Herausforderung an, Magento 2 auf Kubernetes zum Laufen zu bringen. Lassen Sie uns direkt einsteigen!

Voraussetzungen

Dieser Artikel setzt voraus, dass Sie bereits grundlegende Kenntnisse in der Handhabung von Magento 2, Containerisierung (Docker) und den grundlegenden Konzepten von Kubernetes besitzen.

Für die Umsetzung benötigen Sie einen aktiven Kubernetes-Cluster mit:

Tipp

Kind, Minikube und Docker Desktop sind alle geeignete Optionen für die lokale Entwicklung unter Kubernetes.

Zusätzlich werden wir folgende Tools nutzen:

  • kubectl, korrekt konfiguriert für den richtigen Kontext,
  • (optional, aber empfohlen) make

Sobald der Cluster und die Tools bereit sind, können wir mit der Implementierung von Magento beginnen. Alle benötigten Dateien finden Sie in unserem Magento 2 on Kubernetes-Repository auf GitHub.

Lassen Sie uns den Bereitstellungsprozess Schritt für Schritt durchgehen.

Schritt 1: Erstellen einer minimalen Magento 2-Bereitstellung

Magento

Wir benötigen einen Container, in dem Magento operiert. Daher ist es sinnvoll, genau damit zu beginnen.

Zuvor sollten wir jedoch einige Aspekte beleuchten, die bei der Ausführung einer PHP-Webanwendung auf Kubernetes berücksichtigt werden müssen. Dies wird uns dabei helfen, einige der architektonischen Entscheidungen, die in diesem Artikel diskutiert werden, besser zu verstehen.

Muster für PHP-Webanwendungs-Pods

Eine Vielzahl von Mustern steht zur Verfügung, wenn es darum geht, eine PHP-Webanwendung auf Kubernetes bereitzustellen. Diese reichen von Einzelprozess-Einzelcontainer-Lösungen über Mehrprozess-Container bis hin zu mehreren Einzelprozess-Containern.

Komplettlösung in Einem

Die bequemste Methode besteht darin, einen einzigen Container zu nutzen, in dem Apache 2 mit mod_php als einheitlicher Prozess läuft - eine Konfiguration, die in Tutorials häufig zur Anwendung kommt. Obwohl ein Komplett-Container unkompliziert zu konfigurieren und zu verwalten ist, könnte es dennoch sinnvoll sein, die Verwendung von NGINX zur Bereitstellung statischer Inhalte in Erwägung zu ziehen - entweder als spezifizierter Pod oder als Caching-Reverse-Proxy.

Apache 2 with mod_php
Ein Container mit Apache und mod_php

NGINX + PHP-FPM in einem gemeinsamen Container

Falls Sie sich für NGINX entscheiden, ist PHP-FPM eine notwendige Ergänzung. Zusätzlich benötigen Sie entweder ein maßgeschneidertes Skript oder einen Prozessmanager wie zum Beispiel supervisord, um beide in einem gemeinsamen Container laufen zu lassen.

Es ist eine bewährte Methode, relevante Bereiche zu trennen, indem man pro Container einen Dienst verwendet. Dieser Dienst kann sich in mehrere Prozesse aufteilen (wie zum Beispiel der Apache-Webserver, der mehrere Arbeitsprozesse startet). Es ist durchaus akzeptabel, mehrere Prozesse zu haben, jedoch sollten Sie, um den größtmöglichen Nutzen aus Docker zu ziehen, vermeiden, dass ein Container für mehrere Aspekte Ihrer Gesamtanwendung verantwortlich ist. Sie können verschiedene Container über maßgeschneiderte Netzwerke und gemeinsam genutzte Volumes miteinander verbinden.

Trotz der Tatsache, dass in dieser Konfiguration mehrere Prozesse innerhalb eines Containers laufen, bleibt die Trennung der Interessen gewahrt. Der Container ist weiterhin zustandslos, vernichtbar, bietet seine Dienste über Portbindung an und verfügt über alle unterstützenden Dienste (einschließlich Speicher) als angehängte Ressourcen.

NGINX and PHP-FPM
NGINX und PHP-FPM in einem gemeinsamen Container

Dies ist die Konfiguration, die wir bevorzugen.

Ein Pod, der zwei Container beherbergt

In dieser Konfiguration sind NGINX und PHP-FPM in getrennten Containern untergebracht und interagieren über das Netzwerk, anstatt über einen Socket. Dies ermöglicht uns, auf den Supervisord zu verzichten, individuelle Bereitschafts- und Lebendigkeitsprüfungen für jeden Container festzulegen und eine präzisere Kontrolle über die Ressourcenverteilung zu haben.

Es gibt allerdings eine Herausforderung: Wir müssen sicherstellen, dass NGINX auf statische Assets zugreifen kann.

Dies kann auf zwei verschiedene Weisen erreicht werden: Entweder durch die Erstellung eines maßgeschneiderten NGINX-Images, das Projektdateien enthält, oder durch das Teilen von Projektdateien zwischen den NGINX- und PHP-Containern mittels eines Volumes.

Die letztere Methode erfordert die Erstellung eines Volumes, das von den Containern im Pod gemeinsam genutzt wird (hier wäre ein emptyDir genau das Richtige) und das Kopieren der Dateien aus dem PHP-Container in das Volume während der Pod-Initialisierung (also in einen init-Container).

Hinweis

Obwohl dies in einigen Fällen eine machbare Option sein kann, schien sie uns zu komplex zu sein.

NGINX and PHP-FPM in separate containers
NGINX und PHP-FPM sind in separaten Containern untergebracht, jedoch innerhalb eines einzigen Pods.

Trennung von Webserver und PHP in individuellen Pods

Dieses Modell ähnelt stark dem vorherigen, bietet uns jedoch die Möglichkeit, PHP und NGINX Pod unabhängig voneinander zu skalieren. In diesem Kontext können wir kein emptyDir-Volume zur Dateiübertragung zwischen den Pods nutzen und müssen stattdessen dauerhafte Volumes für statische Assets konfigurieren.

NGINX and PHP-FPM in separate Pods
NGINX und PHP-FPM in individuellen Pods

Was ist die optimale Wahl?

Auf der einen Seite sind Apache+PHP-Container, die nur einen Prozess ausführen, einfacher zu handhaben. Auf der anderen Seite ist NGINX für seine herausragende Performance bei der Auslieferung statischer Inhalte berühmt. Wenn Sie NGINX und PHP-FPM auf separate Pods verteilen, haben Sie die Möglichkeit, diese unabhängig voneinander zu skalieren.

Dieser Vorteil geht jedoch mit einer erhöhten Komplexität einher. NGINX fügt so minimalen Overhead hinzu, dass eine Skalierung zusammen mit PHP problemlos möglich sein sollte.

Tipp

Es empfiehlt sich häufig, eigene Benchmarks durchzuführen und dabei Aspekte wie das prognostizierte Datenaufkommen, die Nutzung von CDN und das Caching zu berücksichtigen.

Die Entscheidung, welches Modell für ein spezifisches Projekt am besten geeignet ist, obliegt letztendlich Ihnen.

Magento-Container-Abbild

Wie zuvor erläutert, nutzen wir ein Docker-Image. Dieses basiert auf der FPM-Variante des offiziellen PHP-Images und wurde um die Integration von NGINX und Supervisord erweitert.

Konfiguration mittels Umgebungsvariablen

Für die Bereitstellung von Kubernetes-Anwendungen empfiehlt es sich in der Regel, jede Anwendung durch das Festlegen von Umgebungsvariablen in ihrem jeweiligen Container zu konfigurieren.

Obwohl die Möglichkeit besteht, ConfigMaps oder Secrets in Containern als herkömmliche Konfigurationsdateien zu mounten, ist diese Methode nicht optimal. Verschiedene Anwendungen verwenden unterschiedliche Konfigurationsformate und oft ist es notwendig, dass die Werte zwischen mehreren Anwendungen konsistent sind. Die Verwaltung der Konfiguration kann auf diese Weise schnell unnötig komplex werden.

Im Gegensatz dazu müssen Sie bei Umgebungsvariablen alles nur einmal als Schlüssel-Wert-Paar definieren. Diese Werte können dann einfach durch Verweis auf den Schlüssel (den Variablennamen) übertragen werden. Auf diese Weise stellen Sie sicher, dass es eine einzige verlässliche Quelle für jeden benötigten Konfigurationswert gibt.

Die Nutzung von Umgebungsvariablen in Magento

Magento 2 bietet eine Reihe von Funktionen, darunter die Möglichkeit, Einstellungen direkt aus der Umgebung zu importieren. Das Definieren einer Umgebungsvariablen wie <SCOPE>__<SYSTEM__VARIABLE__NAME>erzielt denselben Effekt, als würde man die Einstellung direkt in die Datei app/etc/config.php schreiben.

Nehmen wir an, Sie möchten Elasticsearch als Suchmaschine einrichten. Durch das Setzen der Umgebungsvariablen CONFIG__DEFAULT__CATALOG__SEARCH__ENGINE=elasticsearch7 wird Magento angewiesen, die Suchmaschine für den Katalog auf “Elasticsearch 7” im Standardbereich zu setzen. Zusätzlich wird diese Einstellung in der Administrationsfläche gesperrt, um unbeabsichtigte Änderungen zu verhindern.

Leider ist es nicht möglich, diese Funktion zur Steuerung von umgebungsspezifischen Einstellungen wie Datenbank-Zugangsdaten zu nutzen. Es gibt jedoch einige Lösungsansätze, um dieses Hindernis zu umgehen:

  • Binden Sie app/etc/env.php aus einer ConfigMap oder einem Secret ein.
  • Nutzen Sie bin/magento, um die Konfiguration aus den Umgebungsvariablen zu importieren und sie während der Pod-Initialisierung an Magento zu übergeben. Dies entspricht im Grunde der manuellen Konfiguration einer Magento-Instanz über die CLI, jedoch automatisiert. Beachten Sie jedoch, dass das Speichern der Konfiguration einige Zeit in Anspruch nimmt und dadurch die Startzeit jedes Magento-Pods erheblich verlängert wird.
  • Passen Sie app/etc/env.php an und integrieren Sie sie in das Container-Image. Da env.php eine reguläre PHP-Datei ist, die ein Array mit der Konfiguration zurückgeben muss, eignet sich die in PHP eingebaute Funktion getenv() hervorragend, um während der Ausführung Werte aus der Umgebung zu importieren, z.B. 'dbname' => getenv('DB_NAME').

Protokollverwaltung

Ein weiterer Aspekt, der bei der Implementierung von Magento 2 auf Kubernetes berücksichtigt werden muss, ist die Gewährleistung, dass alle relevanten Protokolle einen Container-Neustart überstehen und leicht zugänglich sind.

Die einfachste Methode wäre die Nutzung eines PersistentVolumes für die Verzeichnisse var/log und var/reports. Ein solches Volume löst zwar das Problem der Protokollpersistenz, kann jedoch bei einer Vielzahl von Magento-Instanzen, die in dieselben Dateien schreiben, zu Leistungsproblemen führen. Darüber hinaus können die Protokolle selbst schnell zu umfangreich werden, um sie effizient durchsuchen zu können.

Um beide Anforderungen zu erfüllen, stehen verschiedene Lösungsansätze zur Verfügung.

Sidecar Container

Im Rahmen des Sidecar-Musters übernimmt ein separater Container innerhalb des Pods die Aufgabe, stetig wachsende Protokolldateien zu lesen und deren Inhalt auf stdout auszugeben.

Tipp

Ein Container pro Logdatei, der mit tail -f die Logs auf stdout ausgibt, funktioniert für eine einfache Magento-Installation durchaus gut. Allerdings stößt diese Methode an ihre Grenzen, wenn es darum geht, eine größere Menge an Dateien zu verarbeiten.

containers:
- image: kiweeteam/magento2
  name: magento-web
  volumeMounts:
  - name: logs
    mountPath: /var/www/html/var/log
- image: busybox
  name: system-log
  command: ["/bin/sh"]
  args:
  - -c
  - |
    touch /var/www/html/var/log/system.log
    chown 33:33 /var/www/html/var/log/system.log
    tail -n+1 -f /var/www/html/var/log/system.log
  resources:
    limits:
      cpu: 5m
      memory: 64Mi
    requests:
      cpu: 5m
      memory: 64Mi
  volumeMounts:
  - name: logs
    mountPath: /var/www/html/var/log
volumes:
- name: logs
  emptyDir: {}
Dieser Ausschnitt aus dem Magento Deployment Manifest zeigt, wie Sidecars definiert sind.

Direkte Protokollierung in stdout

Dank der PSR-3-Kompatibilität von Magento können wir alle wichtigen Log-Handler so anpassen, dass sie direkt in stdout protokollieren. Als Beispiel hierfür nutzen wir das Modul graycoreio/magento2-stdlogging, welches genau diese Funktion erfüllt.

Anmerkung

Eine direkte Protokollierung in stdout entspricht dem Faktor XI der Zwölf-Faktoren-App-Methodik und macht den Einsatz von Sidecar-Containern überflüssig.

Aggregation von Log-Daten

In beiden Szenarien erfasst ein spezielles Werkzeug die Ausgaben aller aktiven Container im Cluster und archiviert diese Protokolle für eine spätere Zugänglichkeit und Analyse.

Cron

Magento verlässt sich auf Cron-Jobs für eine Vielzahl seiner Funktionen.

Würde man ein Bare-Metal-Deployment-Szenario verwenden, wäre es üblich, einen der Hosts mit der Ausführung von Cronjobs zu beauftragen und diese direkt über Crontab zu konfigurieren. Allerdings ist ein solches Setup mit Kubernetes nicht kompatibel, da es keine einzelne Magento-Instanz (Container) gibt, die ständig in Betrieb ist. Daher nutzen wir einen Kubernetes CronJob, um den Befehl bin/magento cron:run jede Minute auszuführen.

Auf diese Art und Weise übertragen wir die Verantwortung für die Planung und Durchführung von Cron-Jobs an Kubernetes. Dieses startet für jede Ausführung einen neuen Pod und führt bestimmte Befehle bis zum erfolgreichen Abschluss aus. Zudem werden diesen Pods individuell Ressourcen zugewiesen, was das Risiko von Leistungseinbußen bei der Durchführung umfangreicher Aufgaben minimiert.

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: magento-cron
spec:
  schedule: '* * * * *'
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  failedJobsHistoryLimit: 20
  successfulJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: magento-cron
            k8s-app: magento
        spec:
          containers:
          - name: magento-cron
            image: kiweeteam/magento2
            command: ["/bin/sh"]
            args:
            - -c
            - php bin/magento cron:run
          restartPolicy: Never
Hier sehen Sie ein abgekürztes CronJob-Manifest zur Durchführung von Magento 2 Cron-Jobs auf Kubernetes.

Hinweise

Falls Sie Magento Cron als Kubernetes CronJob einsetzen möchten, ist es unerlässlich, dass alle Magento Cron-Jobs so konfiguriert sind, dass sie als ein einzelner Prozess ablaufen. Dies lässt sich bequem durch die Festlegung der nachstehenden Umgebungsvariablen erreichen:

CONFIG__DEFAULT__SYSTEM__CRON__INDEX__USE_SEPARATE_PROCESS=0
CONFIG__DEFAULT__SYSTEM__CRON__DEFAULT__USE_SEPARATE_PROCESS=0
CONFIG__DEFAULT__SYSTEM__CRON__CONSUMERS__USE_SEPARATE_PROCESS=0
CONFIG__DEFAULT__SYSTEM__CRON__DDG_AUTOMATION__USE_SEPARATE_PROCESS=0
Die Umgebungsvariablen verhindern das Forking von Magento Cron

Sollte dies nicht der Fall sein, besteht die Gefahr, dass der Cron-Container beendet wird, bevor alle geplanten Aufgaben vollständig ausgeführt wurden.

Zusätzliche Aufgaben

Ein weiterer Objekttyp von Kubernetes, den wir in diesem Projekt einsetzen werden, ist die Aufgabe, oder im Englischen “Job”.

Wir setzen magento-install ein, um die Installation der Anwendung zu automatisieren. Es installiert das Datenbankschema, erzeugt Performance Fixtures, die wir als Beispieldaten für Demonstrationszwecke nutzen, und sorgt dafür, dass alle Indizes im Aktualisierungsmodus “On Schedule” sind.

containers:
- name: magento-setup
  image: kiweeteam/magento2
  command: ["/bin/sh"]
  args:
  - -c
  - |
      set -o errexit
      ./bin/install.sh
      php bin/magento setup:perf:generate-fixtures setup/performance-toolkit/profiles/ce/mok.xml
      magerun --no-interaction index:list | awk '{print $2}' | tail -n+4 | xargs -I{} magerun --no-interaction index:set-mode schedule {}
      magerun --no-interaction index:reset
      magerun --no-interaction cache:flush
Teil des Job-Manifests von magento-install zur Ausführung des Magento-Installationsbefehls

Hinweis

Bitte beachten Sie, dass das Pod-Vorlagenfeld von Jobs unveränderlich ist und daher nicht bei jeder neuen Version aktualisiert werden kann. Sie müssen daher sicherstellen, dass Sie alte Jobs löschen und für jede eingesetzte Revision neue erstellen.

Obwohl eine solche Automatisierung für die Erstinstallation von Magento sehr nützlich ist, ist sie für weitere Einsätze nicht erforderlich. Stattdessen führt der magento-web Pod einen initContainer aus, der bei Bedarf php bin/magento setup:upgrade oder php bin/magento app:config:import ausführt.

initContainers:
- name: setup
  image: kiweeteam/magento2
  command:
  - /bin/bash
  args:
  - -c
  - |
    set -o errexit
    # Update database schema if needed
    php bin/magento setup:db:status || php bin/magento setup:upgrade --keep-generated
    # Fail if database schema is not up-to-date after setup:upgrade
    php bin/magento setup:db:status
    # Import config if needed
    php bin/magento app:config:status || php bin/magento app:config:import
    # Fail if config is not up-to-date after app:config:import
    php bin/magento app:config:status
  envFrom:
  - configMapRef:
      name: config
  - configMapRef:
      name: additional
Konfiguration des initContainer zur Durchführung von Aktualisierungen der Magento-Konfiguration und des Datenbankschemas

Datenbank-Management

In Bezug auf die Datenbank setzen wir auf ein StatefulSet mit Percona, wobei die Daten in einem PersistentVolume abgelegt werden.

Ein solches einfaches StatefulSet ist ideal für einen kleinen lokalen Entwicklungscluster. Für umfangreichere Anwendungen empfehlen wir jedoch die Implementierung eines Xtradb-Clusters, beispielsweise mit dem Percona Kubernetes Operator. Beachten Sie, dass diese Lösung mehr Ressourcen benötigt und die Komplexität erhöht. Es ist daher ratsam, entsprechende Leistungstests durchzuführen, um sicherzustellen, dass sich die Investition auszahlt.

Elasticsearch

Unsere abschließende Anforderung ist die Implementierung von Elasticsearch.

Aufgrund unserer begrenzten Kapazitäten (Entwicklungscluster auf einem Laptop) haben wir uns für einen minimalistischen Elasticsearch-Cluster mit nur einem Knoten und eingeschränkten Ressourcen entschieden. Da er nicht an öffentliche Netzwerke angeschlossen ist, können wir zur Vereinfachung die Authentifizierung und TLS deaktivieren.

Diese Konfiguration erfüllt unsere Anforderungen, aber für umfangreichere Projekte mit höherem Datenverkehr sollten Sie einen Elastic-Cluster mit mehreren Knoten und erweiterten Ressourcen pro Knoten in Betracht ziehen. Es ist stets ratsam, projektspezifische Benchmarks durchzuführen, um sicherzustellen, dass Ihre Konfiguration optimal auf Ihre Bedürfnisse abgestimmt ist.

Tipp

Obwohl es oft ausreichend ist, ein Elasticsearch StatefulSet mit nur einer Instanz bereitzustellen, erleichtert Elastic Cloud on Kubernetes den Prozess der Implementierung komplexerer Elastic Cluster-Konfigurationen erheblich.

Konfiguration von Magento

Jetzt gilt es, Magento so zu konfigurieren, dass es auf die frisch erstellte Elasticsearch-Instanz verweist. Dies lässt sich problemlos bewerkstelligen, indem wir die additional.env-Konfiguration erweitern:

CONFIG__DEFAULT__CATALOG__SEARCH__ELASTICSEARCH7_SERVER_HOSTNAME=elasticsearch
CONFIG__DEFAULT__CATALOG__SEARCH__ELASTICSEARCH7_SERVER_PORT=9200
CONFIG__DEFAULT__CATALOG__SEARCH__ENGINE=elasticsearch7
Beispielhafte Darstellung der Elasticsearch-Konfiguration mithilfe von Umgebungsvariablen in Magento

Für die Zusammenführung von Konfigurationsdateien und deren Übermittlung als Umgebungsvariablen an Magento setzen wir auf Kustomize.

Der Zugriff von außen

Nun fehlt uns nur noch eine Methode, um von extern auf eine funktionierende Magento-2-Instanz auf Kubernetes zuzugreifen.

Wir könnten den Magento-Webdienst einfach freischalten, indem wir seinen Typ entweder auf NodePort setzen, um ihn über einen spezifischen Port zugänglich zu machen, oder auf LoadBalancer, um ihn über einen externen Lastverteiler zu veröffentlichen.

In diesem Fall werden wir jedoch eine Ingress-Ressource nutzen. Dadurch erhalten wir eine sofort einsatzfähige TLS-Terminierung sowie die Möglichkeit, die TLS-Zertifikate auf deklarative Weise zu verwalten (z. B. mit dem cert-manager). Wir könnten sogar zusätzliche Dienste bereitstellen, die auf Pfad- oder (Sub-)Domänen-Routing basieren, sollten wir uns dafür entscheiden.

Unter der Voraussetzung, dass der NGINX Ingress Controller bereits installiert ist, müssen wir hier lediglich eine Ingress-Definition erstellen, die den gesamten Datenverkehr an den HTTP-Port des Magento-Webdienstes weiterleitet.

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.org/proxy-buffer-size: "256k"
    nginx.org/proxy-buffers: "4 256k"
    nginx.org/proxy-read-timeout: "60s"
spec:
  defaultBackend:
    service:
      name: magento-web
      port:
        name: http
  rules:
    - host: magento2.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: magento-web
                port:
                  name: http

Ingress-Manifest

Zusammenführung aller Elemente

Um den bis hierhin diskutierten Stack zu implementieren, führen Sie bitte den Befehl make step-1 im Begleit-Repository aus.

Nun sollten Sie eine funktionierende, wenn auch noch nicht vollständig ausgereifte, Magento-Installation auf Kubernetes vorfinden. Einige wesentliche Komponenten fehlen noch - diese werden in den kommenden Abschnitten ausführlich besprochen.

Schritt 2: Redis und automatische Skalierung

Im vorherigen Abschnitt haben wir alle funktionsrelevanten Komponenten implementiert. Ihnen ist möglicherweise aufgefallen, dass die Performance von Magento noch nicht ganz optimal ist. Keine Sorge - wir haben noch nicht alle Vorteile des Caching ausgeschöpft!

Um es auf den Punkt zu bringen: Wir haben das System zum Laufen gebracht, nun wollen wir es mit Redis und automatischer Skalierung auf Höchstleistung bringen.

Redis

Redis erfüllt zwei entscheidende Funktionen in jedem leistungsfähigen Magento 2-Einsatz:

  • Es ermöglicht eine rasche Speicherung von Sitzungsdaten, sodass mehrere Anwendungsinstanzen die Sitzungsinformationen zwischen den Anfragen nachverfolgen können.
  • Es dient als Cache-Speicher für den internen Magento-Cache (wie z.B. Konfiguration, Layout, HTML-Fragmente).

In diesem Zusammenhang werden wir ein einfaches StatefulSet einsetzen, um eine einzelne Redis-Instanz mit getrennten Datenbanken für Sitzungen und Cache zu betreiben. Da wir keine PersistentVolumes anhängen müssen, werden wir dies auch nicht tun.

Genauso wie bei Elasticsearch müssen wir abschließend Magento dazu anweisen, die neu eingerichtete Redis-Instanz zu nutzen. Wie zuvor fügen wir einige Schlüssel zu additional.env hinzu und lassen Kustomize die Teile zusammenfügen:

REDIS_CACHE_HOST=redis
REDIS_CACHE_PORT=6379
REDIS_CACHE_DB=0
REDIS_SESSION_HOST=redis
REDIS_SESSION_PORT=6379
REDIS_SESSION_DB=2
Umgebungsvariablen zur Einrichtung von Redis als Backend für Cache- und Sitzungsspeicher in Magento.

Horizontale Pod-Autoskalierung

Dank Redis können wir nun mehrere Instanzen von Magento parallel betreiben, die gemeinsam auf Sitzungsinformationen und Cache zugreifen. Natürlich könnten wir die Anzahl der Replikate im Magento-Deployment-Manifest bei Bedarf einfach erhöhen. Aber warum sollten wir nicht die gesamten Vorteile ausschöpfen, die uns das Betreiben von Magento 2 auf Kubernetes bietet?

Lassen Sie uns stattdessen horizontale Pod-Autoskalierer einrichten und Kubernetes selbst die optimale Anzahl an Instanzen zu jedem gegebenen Zeitpunkt bestimmen lassen..

Zu diesem Zweck erstellen wir einen neuen HorizontalPodAutoscaler. Dieser überwacht die Ressourcennutzung der in scaleTargetRef, definierten Pods und initiiert neue Pods, sobald die targetCPUUtilizationPercentage den festgelegten Grenzwert überschreitet, bis die maxReplicas erreicht sind.

---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: magento-web
spec:
  maxReplicas: 5
  minReplicas: 2
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: magento-web
  targetCPUUtilizationPercentage: 75
Manifest des HorizontalPodAutoscalers
Hinweis

In diesem Artikel haben wir den Magento-Pods absichtlich limitierte Ressourcen zugewiesen, um die automatische Skalierung in Aktion zu demonstrieren. Wenn Sie Magento 2 in einer realen Umgebung auf Kubernetes bereitstellen, sollten Sie sicherstellen, dass Sie sowohl die PHP-Einstellungen und Pod-Ressourcenbeschränkungen als auch die Skalierungsregeln in der HorizontalPodAutoscaler-Konfiguration entsprechend anpassen.

Führen Sie einfach make step-3 aus, um Redis und den Auto-Scaler zu implementieren.

Schritt 3: Varnish

Das letzte Puzzleteil ist das Hinzufügen eines Caching-Reverse-Proxys, um Magento zu entlasten. Selbstverständlich verwenden wir dafür Varnish, da es out-of-the-box unterstützt wird.

Ähnlich wie in den vorherigen Schritten starten wir mit der Erstellung einer Varnish-Bereitstellung. Zwei bemerkenswerte Aspekte hierbei sind, dass wir nicht nur einen, sondern zwei Ports freigeben und einen benutzerdefinierten Befehl zum Starten des Containers ausführen, indem wir zuerst Varnish im Daemon-Modus starten und dann varnishncsa ausführen.

Die Freigabe von zwei Ports erlaubt uns, einfache Zugriffsregeln in der Varnish VCL zu konfigurieren, sodass Magento den Cache über einen Port leeren kann, während der andere sicher für den Zugriff von außen bleibt.

Das Ausführen von varnishncsa als Teil des benutzerdefinierten Befehls liefert ein Zugriffsprotokoll direkt auf stdout des Containers.

Als nächstes müssen wir Magento informieren, wie es sich mit Varnish verbinden soll, indem wir die Konfigurationsdatei additional.env wie zuvor erweitern:

VARNISH_HOST=varnish
VARNISH_PORT=80
Umgebungsvariablen zur Konfiguration des Varnish-Cache in Magento
containers:
- image: varnish
  name: varnish
  command: ["/bin/sh"]
  args:
    - -c
    - |
      varnishd -a :80 -a :6091 -f /etc/varnish/default.vcl -s default,512M;
      varnishncsa -F '%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i" %{Varnish:handling}x'
  ports:
  - containerPort: 80
  - containerPort: 6091
Benutzerdefinierte Befehls- und Port-Konfiguration - Element des Varnish-Deployment-Manifests

Letztendlich streben wir an, dass der Ingress sämtliche eingehende Anfragen an Varnish weiterleitet. Hierfür muss der in der Ingress-Definition angegebene Ziel-Dienst entsprechend angepasst werden. Eine unkomplizierte Methode, um die Ingress-Definition zu aktualisieren, stellt die Nutzung von patchesJson6902 von Kustomize dar.

---
- op: replace
  path: /spec/backend/serviceName
  value: varnish
- op: replace
  path: /spec/backend/servicePort
  value: 6091
JSON Patch zur Aktualisierung der Backend-Konfiguration des Ingress

Hinweis

Obwohl Varnish die Last auf andere Komponenten reduziert und die Performance von Seiten, die sich selten ändern, optimiert, verbessert es nicht die Leistung interaktiver Elemente wie Warenkorb, Kasse oder Kundenbereich.

Zur Implementierung und Konfiguration von Varnish führen Sie make step-3 aus.

Zusammenfassung

Das war’s also: Ein umfassender Überblick über alles Notwendige, um Magento 2 auf Kubernetes zu betreiben, mit einer Magento-Deployment-Konfiguration über Umgebungsvariablen, Cronjobs, Elasticsearch, Redis, Autoscaling und Varnish.

Sämtliche Manifeste und Konfigurationsdateien werden von Kustomize verwaltet, was eine bequeme Anpassung an die spezifischen Anforderungen jedes Projekts ermöglicht.

Wir raten Ihnen zwar davon ab, diese Konfiguration sofort in der Produktion einzusetzen, jedoch sollte sie Ihnen einen soliden Ausgangspunkt für die Erstellung einer produktionsreifen Konfiguration für Ihr Projekt bieten.

FacebookTwitterPinterest