Bereitstellen einer PHP-Anwendung mit Kubernetes unter Ubuntu 18.04

Der Autor hat Electronic Frontier Foundation ausgewählt, um eine Spende im Rahmen von Write for DOnations zu erhalten Programm.

Einführung

Kubernetes ist ein Open Source Container Orchestrierungssystem. Sie können Container erstellen, aktualisieren und skalieren, ohne sich um Ausfallzeiten sorgen zu müssen.

Um eine PHP-Anwendung auszuführen, fungiert Nginx als Proxy für PHP-FPM. Das Containerisieren dieses Setups in einem einzelnen Container kann ein mühsamer Prozess sein, aber Kubernetes unterstützt Sie bei der Verwaltung beider Services in separaten Containern. Mit Kubernetes können Sie Ihre Container wiederverwenden und austauschen, und Sie müssen Ihr Container-Image nicht jedes Mal neu erstellen, wenn eine neue Version von Nginx oder PHP verfügbar ist.

In diesem Lernprogramm stellen Sie eine PHP 7-Anwendung auf einem Kubernetes-Cluster bereit, wobei Nginx und PHP-FPM in separaten Containern ausgeführt werden. Sie erfahren auch, wie Sie Ihre Konfigurationsdateien und den Anwendungscode außerhalb des Container-Images halten, indem Sie DigitalOceans Block Storage -System verwenden. Mit diesem Ansatz können Sie das Nginx-Image für jede Anwendung wiederverwenden, die einen Web- / Proxyserver benötigt, indem Sie ein Konfigurations-Volume übergeben, anstatt das Image neu zu erstellen.

Voraussetzungen

  • Ein grundlegendes Verständnis von Kubernetes-Objekten. Weitere Informationen finden Sie in unserem Artikel Introduction to Kubernetes.

  • Ein Kubernetes-Cluster unter Ubuntu 18.04. Sie können dies einrichten, indem Sie der https://www.digitalocean.com/community/tutorials/how-to-create-a-kubernetes-cluster- using-kubeadm-on-ubuntu-18-04[How To Create a Kubernetes 1.14 Cluster Mit Kubeadm unter Ubuntu 18.04] Tutorial.

  • Ein DigitalOcean-Konto und ein API-Zugriffstoken mit Lese- und Schreibberechtigungen zum Erstellen unseres Speichervolumens. Wenn Sie kein API-Zugriffstoken haben, können Sie es unter create it from here erstellen.

  • Ihr Anwendungscode, der auf einer öffentlich zugänglichen URL wie https://github.com [Github] gehostet wird.

Schritt 1 - Erstellen der PHP-FPM- und Nginx-Dienste

In diesem Schritt erstellen Sie die Dienste PHP-FPM und Nginx. Ein Dienst ermöglicht den Zugriff auf eine Reihe von Pods innerhalb des Clusters. Dienste innerhalb eines Clusters können direkt über ihren Namen kommunizieren, ohne dass IP-Adressen erforderlich sind. Der PHP-FPM-Dienst ermöglicht den Zugriff auf die PHP-FPM-Pods, während der Nginx-Dienst den Zugriff auf die Nginx-Pods ermöglicht.

Da Nginx-Pods die PHP-FPM-Pods als Proxy verwenden, müssen Sie dem Service mitteilen, wie er sie findet. Anstatt IP-Adressen zu verwenden, können Sie die automatische Diensterkennung von Kubernetes nutzen, um lesbare Namen zu verwenden, um Anforderungen an den entsprechenden Dienst weiterzuleiten.

Um den Service zu erstellen, erstellen Sie eine Objektdefinitionsdatei. Jede Kubernetes-Objektdefinition ist eine YAML-Datei, die mindestens die folgenden Elemente enthält:

  • + apiVersion +: Die Version der Kubernetes-API, zu der die Definition gehört.

  • + kind +: Das Kubernetes-Objekt, das diese Datei darstellt. Zum Beispiel ein "+ pod" oder "+ service".

  • + Metadaten +: Dies enthält den + Namen + des Objekts zusammen mit allen + Bezeichnungen +, die Sie möglicherweise auf das Objekt anwenden möchten.

  • + spec +: Dies enthält eine bestimmte Konfiguration, die von der Art des Objekts abhängt, das Sie erstellen, z. B. das Container-Image oder die Ports, über die auf den Container zugegriffen werden kann.

Zuerst erstellen Sie ein Verzeichnis für die Kubernetes-Objektdefinitionen.

Stellen Sie eine SSH-Verbindung zu Ihrem * Masterknoten * her und erstellen Sie das Verzeichnis + definitions +, das Ihre Kubernetes-Objektdefinitionen enthält.

mkdir definitions

Navigieren Sie zum neu erstellten Verzeichnis + definitions +:

cd definitions

Erstellen Sie Ihren PHP-FPM-Dienst, indem Sie eine + php_service.yaml + -Datei erstellen:

nano php_service.yaml

Stellen Sie "+ kind " als " Service +" ein, um anzugeben, dass dieses Objekt ein Service ist:

php_service.yaml

apiVersion: v1
kind: Service

Nennen Sie den Dienst "+ php +", da er den Zugriff auf PHP-FPM ermöglicht:

php_service.yaml

...
metadata:
 name: php

Sie werden verschiedene Objekte mit Beschriftungen logisch gruppieren. In diesem Lernprogramm werden Sie Beschriftungen verwenden, um die Objekte in „Ebenen“ zu gruppieren, z. B. Frontend oder Backend. Die PHP-Pods werden hinter diesem Dienst ausgeführt, daher kennzeichnen Sie ihn als "+ tier: backend +".

php_service.yaml

...
 labels:
   tier: backend

Ein Dienst bestimmt mithilfe von "+ Selector +" - Labels, auf welche Pods zugegriffen werden soll. Ein Pod, der diesen Labels entspricht, wird gewartet, unabhängig davon, ob der Pod vor oder nach dem Service erstellt wurde. Sie werden später im Lernprogramm Beschriftungen für Ihre Pods hinzufügen.

Verwenden Sie das Label "+ tier: backend ", um den Pod der Backend-Schicht zuzuweisen. Sie fügen auch das Label " app: php " hinzu, um anzugeben, dass dieser Pod PHP ausführt. Fügen Sie diese beiden Bezeichnungen nach dem Abschnitt " Metadaten +" hinzu.

php_service.yaml

...
spec:
 selector:
   app: php
   tier: backend

Geben Sie als Nächstes den Port an, über den auf diesen Dienst zugegriffen werden soll. In diesem Tutorial werden Sie Port + 9000 + verwenden. Fügen Sie es der Datei "+ php_service.yaml " unter " spec +" hinzu:

php_service.yaml

...
 ports:
   - protocol: TCP
     port: 9000

Ihre fertige "+ php_service.yaml +" -Datei sieht folgendermaßen aus:

php_service.yaml

apiVersion: v1
kind: Service
metadata:
 name: php
 labels:
   tier: backend
spec:
 selector:
   app: php
   tier: backend
 ports:
 - protocol: TCP
   port: 9000

Drücken Sie "+ STRG + O ", um die Datei zu speichern, und dann " STRG + X", um "+ nano" zu beenden.

Nachdem Sie die Objektdefinition für Ihren Dienst erstellt haben, verwenden Sie zum Ausführen des Dienstes den Befehl "+ kubectl apply " zusammen mit dem Argument " -f " und geben die Datei " php_service.yaml +" an.

Erstellen Sie Ihren Service:

kubectl apply -f php_service.yaml

Diese Ausgabe bestätigt die Serviceerstellung:

Outputservice/php created

Stellen Sie sicher, dass Ihr Dienst ausgeführt wird:

kubectl get svc

Sie werden sehen, wie Ihr PHP-FPM-Dienst ausgeführt wird:

OutputNAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    10m
php          ClusterIP   10.100.59.238   <none>        9000/TCP   5m

Es gibt verschiedene service types, die Kubernetes unterstützt. Ihr "+ php" -Dienst verwendet den Standarddiensttyp "+ ClusterIP". Dieser Diensttyp weist eine interne IP zu und macht den Dienst nur innerhalb des Clusters erreichbar.

Nachdem der PHP-FPM-Dienst fertig ist, erstellen Sie den Nginx-Dienst. Erstellen und öffnen Sie eine neue Datei mit dem Namen "+ nginx_service.yaml +" mit dem Editor:

nano nginx_service.yaml

Dieser Service zielt auf Nginx-Pods ab, daher nennen Sie ihn "+ nginx ". Sie fügen auch ein " tier: backend +" - Label hinzu, wie es in der Backend-Schicht enthalten ist:

nginx_service.yaml

apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
   tier: backend

Ähnlich wie beim "+ php " - Dienst sollten Sie die Pods mit den Auswahlbezeichnungen " app: nginx" und "+ tier: backend" ausrichten. Stellen Sie diesen Dienst auf Port "+ 80 +", dem Standard-HTTP-Port, bereit.

nginx_service.yaml

...
spec:
 selector:
   app: nginx
   tier: backend
 ports:
 - protocol: TCP
   port: 80

Der Nginx-Dienst ist über die öffentliche IP-Adresse Ihres Droplets für das Internet öffentlich zugänglich. ++ finden Sie unter https://cloud.digitalocean.com [DigitalOcean Control Panel]. Fügen Sie unter + spec.externalIPs + Folgendes hinzu:

nginx_service.yaml

...
spec:
 externalIPs:
 -

Ihre + nginx_service.yaml + Datei sieht folgendermaßen aus:

nginx_service.yaml

apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
   tier: backend
spec:
 selector:
   app: nginx
   tier: backend
 ports:
 - protocol: TCP
   port: 80
 externalIPs:
 -

Speichern und schließen Sie die Datei. Erstellen Sie den Nginx-Dienst:

kubectl apply -f nginx_service.yaml

Sie sehen die folgende Ausgabe, wenn der Dienst ausgeführt wird:

Outputservice/nginx created

Sie können alle ausgeführten Dienste anzeigen, indem Sie Folgendes ausführen:

kubectl get svc

In der Ausgabe werden sowohl die PHP-FPM- als auch die Nginx-Dienste aufgelistet:

OutputNAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    13m
nginx        ClusterIP   10.102.160.47    80/TCP     50s
php          ClusterIP   10.100.59.238   <none>        9000/TCP   8m

Bitte beachten Sie, dass Sie zum Löschen eines Dienstes Folgendes ausführen können:

kubectl delete svc/

Nachdem Sie Ihre PHP-FPM- und Nginx-Dienste erstellt haben, müssen Sie angeben, wo Sie den Anwendungscode und die Konfigurationsdateien speichern möchten.

Schritt 2 - Installieren des DigitalOcean-Speicher-Plug-Ins

Kubernetes bietet verschiedene Speicher-Plug-Ins, mit denen Sie Speicherplatz für Ihre Umgebung schaffen können. In diesem Schritt installieren Sie das DigitalOcean-Speicher-Plug-in, um block storage auf DigitalOcean zu erstellen . Sobald die Installation abgeschlossen ist, wird eine Speicherklasse mit dem Namen "+ do-block-storage" hinzugefügt, die Sie zum Erstellen Ihres Blockspeichers verwenden werden.

Sie konfigurieren zunächst ein Kubernetes Secret-Objekt zum Speichern Ihres DigitalOcean-API-Tokens. Geheime Objekte werden verwendet, um vertrauliche Informationen wie SSH-Schlüssel und Kennwörter mit anderen Kubernetes-Objekten im selben Namespace zu teilen. Mit Namespaces können Sie Ihre Kubernetes-Objekte logisch trennen.

Öffnen Sie eine Datei mit dem Namen "+ secret.yaml +" mit dem Editor:

nano secret.yaml

Sie benennen Ihr geheimes Objekt "+ digitalocean" und fügen es dem Namespace "+ kube-system" hinzu. Der Namespace "+ kube-system +" ist der Standardnamespace für die internen Dienste von Kubernetes und wird auch vom DigitalOcean-Speicher-Plug-In zum Starten verschiedener Komponenten verwendet.

secret.yaml

apiVersion: v1
kind: Secret
metadata:
 name: digitalocean
 namespace: kube-system

Anstelle eines "+ spec " - Schlüssels verwendet ein Secret einen " data" - oder "+ string data" -Schlüssel, um die erforderlichen Informationen zu speichern. Der Parameter + data + enthält base64-codierte Daten, die beim Abrufen automatisch decodiert werden. Der Parameter + stringData + enthält nicht codierte Daten, die beim Erstellen oder Aktualisieren automatisch codiert werden, und gibt die Daten beim Abrufen von Secrets nicht aus. In diesem Tutorial verwenden Sie zur Vereinfachung "+ stringData +".

Fügen Sie das "+ Access-Token" als "+ String-Daten" hinzu:

secret.yaml

...
stringData:
 access-token:

Speichern und schließen Sie die Datei.

Ihre + secret.yaml + -Datei sieht folgendermaßen aus:

secret.yaml

apiVersion: v1
kind: Secret
metadata:
 name: digitalocean
 namespace: kube-system
stringData:
 access-token:

Erstelle das Geheimnis:

kubectl apply -f secret.yaml

Sie werden diese Ausgabe bei der geheimen Erstellung sehen:

Outputsecret/digitalocean created

Sie können das Geheimnis mit dem folgenden Befehl anzeigen:

kubectl -n kube-system get secret digitalocean

Die Ausgabe sieht ungefähr so ​​aus:

OutputNAME           TYPE      DATA      AGE
digitalocean   Opaque    1         41s

Der Typ "+ Opaque " bedeutet, dass dieses Geheimnis schreibgeschützt ist, was für " stringData " - Geheimnisse Standard ist. Weitere Informationen finden Sie unter https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/secrets.md[Secret design spec]. Das Feld " DATA " zeigt die Anzahl der in diesem Secret gespeicherten Elemente an. In diesem Fall wird " 1 +" angezeigt, da Sie einen einzelnen Schlüssel gespeichert haben.

Nachdem Ihr Secret eingerichtet ist, installieren Sie das DigitalOcean-Blockspeicher-Plug-In:

kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v1.1.0.yaml

Sie sehen eine Ausgabe ähnlich der folgenden:

Outputcsidriver.storage.k8s.io/dobs.csi.digitalocean.com created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotclasses.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotcontents.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshots.snapshot.storage.k8s.io created
storageclass.storage.k8s.io/do-block-storage created
statefulset.apps/csi-do-controller created
serviceaccount/csi-do-controller-sa created
clusterrole.rbac.authorization.k8s.io/csi-do-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-do-provisioner-binding created
clusterrole.rbac.authorization.k8s.io/csi-do-attacher-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-do-attacher-binding created
clusterrole.rbac.authorization.k8s.io/csi-do-snapshotter-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-do-snapshotter-binding created
daemonset.apps/csi-do-node created
serviceaccount/csi-do-node-sa created
clusterrole.rbac.authorization.k8s.io/csi-do-node-driver-registrar-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-do-node-driver-registrar-binding created
error: unable to recognize "https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v1.1.0.yaml": no matches for kind "VolumeSnapshotClass" in version "snapshot.storage.k8s.io/v1alpha1"

In diesem Lernprogramm können Sie die Fehler ignorieren.

Nachdem Sie das DigitalOcean-Speicher-Plug-In installiert haben, können Sie einen Blockspeicher für den Anwendungscode und die Konfigurationsdateien erstellen.

Schritt 3 - Erstellen des beständigen Volumes

Nachdem Sie Ihr Secret installiert und das Blockspeicher-Plug-In installiert haben, können Sie jetzt Ihr Persistent Volume erstellen. Ein persistentes Volume (PV) ist ein Blockspeicher einer bestimmten Größe, der unabhängig vom Lebenszyklus eines Pods ist. Wenn Sie ein beständiges Volume verwenden, können Sie Ihre Pods verwalten oder aktualisieren, ohne sich Gedanken über den Verlust Ihres Anwendungscodes machen zu müssen. Auf ein persistentes Volume wird mit einem "+ PersistentVolumeClaim +" oder PVC zugegriffen, mit dem die PV am erforderlichen Pfad eingehängt wird.

Öffnen Sie eine Datei mit dem Namen "+ code_volume.yaml +" mit Ihrem Editor:

nano code_volume.yaml

Nennen Sie das PVC "+ code +", indem Sie die folgenden Parameter und Werte zu Ihrer Datei hinzufügen:

code_volume.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: code

Das "+ spec +" für ein PVC enthält die folgenden Elemente:

  • + accessModes +, die je nach Anwendungsfall variieren. Diese sind:

  • + ReadWriteOnce + - Hängt das Volume von einem einzelnen Knoten als Lese- / Schreibzugriff ein

  • + ReadOnlyMany + - Aktiviert das Volume für viele Knoten als schreibgeschützt

  • + ReadWriteMany + - Hängt das Volume von vielen Knoten als schreibgeschützt an

  • + resources + - der von Ihnen benötigte Speicherplatz

Der DigitalOcean-Blockspeicher wird nur auf einem einzelnen Knoten gemountet, daher setzen Sie "+ accessModes " auf " ReadWriteOnce ". In diesem Lernprogramm erfahren Sie, wie Sie eine kleine Menge Anwendungscode hinzufügen. In diesem Anwendungsfall ist also 1 GB ausreichend. Wenn Sie eine größere Menge an Code oder Daten auf dem Volume speichern möchten, können Sie den Parameter " storage +" an Ihre Anforderungen anpassen. Sie können die Speicherkapazität nach der Volume-Erstellung erhöhen, das Verkleinern der Festplatte wird jedoch nicht unterstützt.

code_volume.yaml

...
spec:
 accessModes:
 - ReadWriteOnce
 resources:
   requests:
     storage:

Geben Sie als Nächstes die Speicherklasse an, mit der Kubernetes die Volumes bereitstellt. Sie verwenden die Klasse "+ do-block-storage +", die vom DigitalOcean-Blockspeicher-Plug-In erstellt wurde.

code_volume.yaml

...
 storageClassName: do-block-storage

Ihre + code_volume.yaml + Datei sieht folgendermaßen aus:

code_volume.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: code
spec:
 accessModes:
 - ReadWriteOnce
 resources:
   requests:
     storage:
 storageClassName: do-block-storage

Speichern und schließen Sie die Datei.

Erstellen Sie den + Code von PVC mit + kubectl:

kubectl apply -f code_volume.yaml

Die folgende Ausgabe gibt an, dass das Objekt erfolgreich erstellt wurde und Sie bereit sind, Ihre 1 GB PVC als Volume bereitzustellen.

Outputpersistentvolumeclaim/code created

So zeigen Sie verfügbare permanente Volumes (PV) an:

kubectl get pv

Sie sehen Ihre PV aufgelistet:

OutputNAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM          STORAGECLASS       REASON    AGE
pvc-ca4df10f-ab8c-11e8-b89d-12331aa95b13   1Gi        RWO            Delete           Bound     default/code   do-block-storage             2m

Die obigen Felder sind eine Übersicht über Ihre Konfigurationsdatei, mit Ausnahme von "+ Rückforderungsrichtlinie " und " Status ". Die " Rückforderungsrichtlinie" definiert, was mit dem PV nach dem Löschen des darauf zugreifenden PVCs gemacht wird. + Delete + entfernt die PV von Kubernetes sowie die DigitalOcean-Infrastruktur. Weitere Informationen zu den Rückforderungsrichtlinien und dem Status finden Sie unter Kubernetes PV documentation.

Sie haben erfolgreich ein beständiges Volume mit dem DigitalOcean-Blockspeicher-Plug-In erstellt. Nachdem Ihr beständiges Volume fertig ist, erstellen Sie Ihre Pods mithilfe einer Bereitstellung.

Schritt 4 - Erstellen einer PHP-FPM-Bereitstellung

In diesem Schritt erfahren Sie, wie Sie mithilfe eines Deployments Ihren PHP-FPM-Pod erstellen. Bereitstellungen bieten eine einheitliche Möglichkeit zum Erstellen, Aktualisieren und Verwalten von Pods mithilfe von ReplicaSets. Wenn ein Update nicht wie erwartet funktioniert, werden die Pods einer Bereitstellung automatisch auf ein vorheriges Image zurückgesetzt.

Mit der Deployment-Taste + spec.selector + werden die Beschriftungen der zu verwaltenden Pods aufgelistet. Außerdem wird die Taste "+ template +" verwendet, um die erforderlichen Pods zu erstellen.

In diesem Schritt wird auch die Verwendung von Init-Containern eingeführt. Init Containers Führe einen oder mehrere Befehle vor den regulären Containern aus, die unter der Taste "+ template " des Pods angegeben sind. In diesem Tutorial ruft Ihr Init-Container mit ` wget ` eine Beispieldatei ` index.php +` von https://gist.github.com [GitHub Gist] ab. Dies sind die Inhalte der Beispieldatei:

index.php

<?php
echo phpinfo();

Öffnen Sie zum Erstellen Ihrer Bereitstellung eine neue Datei mit dem Namen "+ php_deployment.yaml +" mit Ihrem Editor:

nano php_deployment.yaml

Diese Bereitstellung verwaltet Ihre PHP-FPM-Pods, sodass Sie das Bereitstellungsobjekt "+ php " nennen. Die Pods gehören zur Back-End-Ebene, sodass Sie die Bereitstellung in diese Gruppe gruppieren, indem Sie das Label ` tier: backend +` verwenden:

php_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 name: php
 labels:
   tier: backend

Für die Bereitstellung "+ spec " geben Sie an, wie viele Kopien dieses Pods mit dem Parameter " replicas +" erstellt werden sollen. Die Anzahl der Replikate hängt von Ihren Anforderungen und den verfügbaren Ressourcen ab. In diesem Lernprogramm erstellen Sie ein Replikat:

php_deployment.yaml

...
spec:
 replicas: 1

Diese Bereitstellung verwaltet Pods, die den Bezeichnungen "+ app: php " und " tier: backend " entsprechen. Fügen Sie unter ` Selector +` Folgendes hinzu:

php_deployment.yaml

...
 selector:
   matchLabels:
     app: php
     tier: backend

Als Nächstes erfordert die Deployment-Spezifikation "" die Vorlage "" für die Objektdefinition Ihres Pods. Diese Vorlage definiert die Spezifikationen, aus denen der Pod erstellt werden soll. Zuerst fügen Sie die Bezeichnungen hinzu, die für den "+ php" -Dienst "+ selectors" und das Deployment "+ matchLabels" angegeben wurden. Fügen Sie unter + template.metadata.labels` + app: php` und + tier: backend hinzu:

php_deployment.yaml

...
 template:
   metadata:
     labels:
       app: php
       tier: backend

Ein Pod kann mehrere Container und Volumes haben, aber jedes benötigt einen Namen. Sie können Volumes selektiv in einem Container bereitstellen, indem Sie für jedes Volume einen Bereitstellungspfad angeben.

Geben Sie zunächst die Volumes an, auf die Ihre Container zugreifen sollen. Sie haben ein PVC mit dem Namen "+ code " erstellt, das Ihren Anwendungscode enthält. Nennen Sie dieses Volume also auch " code ". Fügen Sie unter ` spec.template.spec.volumes +` Folgendes hinzu:

php_deployment.yaml

...
   spec:
     volumes:
     - name: code
       persistentVolumeClaim:
         claimName: code

Geben Sie als Nächstes den Container an, den Sie in diesem Pod ausführen möchten. Sie finden verschiedene Bilder unter the Docker store, aber in diesem Tutorial verwenden Sie das Bild + php: 7-fpm +.

Fügen Sie unter "+ spec.template.spec.containers +" Folgendes hinzu:

php_deployment.yaml

...
     containers:
     - name: php
       image: php:7-fpm

Als Nächstes mounten Sie die Volumes, auf die der Container zugreifen muss. Dieser Container führt Ihren PHP-Code aus und benötigt daher Zugriff auf das Volume "+ code ". Sie werden auch " mountPath " verwenden, um " / code +" als Einhängepunkt anzugeben.

Fügen Sie unter + spec.template.spec.containers.volumeMounts + Folgendes hinzu:

php_deployment.yaml

...
       volumeMounts:
       - name: code
         mountPath: /code

Nachdem Sie Ihr Volume aktiviert haben, müssen Sie den Anwendungscode auf dem Volume abrufen. Möglicherweise haben Sie zuvor FTP / SFTP verwendet oder den Code über eine SSH-Verbindung geklont. In diesem Schritt erfahren Sie jedoch, wie Sie den Code mithilfe eines Init-Containers kopieren.

Abhängig von der Komplexität Ihres Installationsprozesses können Sie entweder ein einzelnes "+ initContainer " zum Ausführen eines Skripts verwenden, das Ihre Anwendung erstellt, oder Sie können ein " initContainer " pro Befehl verwenden. Stellen Sie sicher, dass die Volumes im ` initContainer +` gemountet sind.

In diesem Tutorial verwenden Sie einen einzelnen Init-Container mit "+ busybox ", um den Code herunterzuladen. ` busybox ` ist ein kleines Bild, das das Hilfsprogramm ` wget +` enthält, das Sie dazu verwenden werden.

Fügen Sie unter "+ spec.template.spec " Ihr " initContainer " hinzu und geben Sie das Bild " busybox +" an:

php_deployment.yaml

...
     initContainers:
     - name: install
       image: busybox

Ihr Init-Container benötigt Zugriff auf das Volume "+ code ", damit er den Code an diesem Speicherort herunterladen kann. Hängen Sie unter " spec.template.spec.initContainers" das Volume "+ code " in den Pfad " / code +" ein:

php_deployment.yaml

...
       volumeMounts:
       - name: code
         mountPath: /code

Jeder Init Container muss einen + Befehl + ausführen. Ihr Init-Container lädt mit + wget + the code von https://github.com/do-community herunter / php-kubernetes [Github] in das + / code + Arbeitsverzeichnis. Die Option "+ -O " gibt der heruntergeladenen Datei einen Namen und Sie benennen diese Datei mit " index.php +".

Fügen Sie unter dem Container "+ install" in "+ spec.template.spec.initContainers" die folgenden Zeilen hinzu:

php_deployment.yaml

...
       command:
       - wget
       - "-O"
       - "/code/index.php"
       -

Ihre fertige "+ php_deployment.yaml +" -Datei sieht folgendermaßen aus:

php_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 name: php
 labels:
   tier: backend
spec:
 replicas: 1
 selector:
   matchLabels:
     app: php
     tier: backend
 template:
   metadata:
     labels:
       app: php
       tier: backend
   spec:
     volumes:
     - name: code
       persistentVolumeClaim:
         claimName: code
     containers:
     - name: php
       image: php:7-fpm
       volumeMounts:
       - name: code
         mountPath: /code
     initContainers:
     - name: install
       image: busybox
       volumeMounts:
       - name: code
         mountPath: /code
       command:
       - wget
       - "-O"
       - "/code/index.php"
       - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php

Speichern Sie die Datei und beenden Sie den Editor.

Erstellen Sie das PHP-FPM-Deployment mit + kubectl +:

kubectl apply -f php_deployment.yaml

Bei der Erstellung der Bereitstellung wird die folgende Ausgabe angezeigt:

Outputdeployment.apps/php created

Zusammenfassend beginnt diese Bereitstellung mit dem Herunterladen der angegebenen Images. Es fordert dann das "+ PersistentVolume " von Ihrem " PersistentVolumeClaim " an und führt Ihre " initContainers " seriell aus. Sobald der Vorgang abgeschlossen ist, werden die Container ausgeführt und mounten die ` Volumes +` am angegebenen Mountpunkt. Sobald alle diese Schritte abgeschlossen sind, ist Ihr Pod betriebsbereit.

Sie können Ihre Bereitstellung anzeigen, indem Sie Folgendes ausführen:

kubectl get deployments

Sie sehen die Ausgabe:

OutputNAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
php       1         1         1            0           19s

Diese Ausgabe kann Ihnen dabei helfen, den aktuellen Status der Bereitstellung zu verstehen. Ein "+ Deployment " ist https://kubernetes.io/docs/concepts/workloads/controllers/deployment/[einer der Controller], der einen gewünschten Status beibehält. Das von Ihnen erstellte " template " gibt an, dass der Status " DESIRED " 1 " Replikate " des Pods mit dem Namen " php " enthält. Das Feld " CURRENT" gibt an, wie viele Replikate ausgeführt werden. Daher sollte dies dem Status "+ DESIRED" entsprechen. Weitere Informationen zu den verbleibenden Feldern finden Sie in der Dokumentation zu Kubernetes Deployments.

Sie können die Pods anzeigen, die diese Bereitstellung mit dem folgenden Befehl gestartet hat:

kubectl get pods

Die Ausgabe dieses Befehls hängt davon ab, wie viel Zeit seit dem Erstellen der Bereitstellung vergangen ist. Wenn Sie es kurz nach der Erstellung ausführen, sieht die Ausgabe wahrscheinlich folgendermaßen aus:

OutputNAME                   READY     STATUS     RESTARTS   AGE
php-86d59fd666-bf8zd   0/1       Init:0/1   0          9s

Die Spalten stellen die folgenden Informationen dar:

  • + Bereit +: Die Anzahl von + Replikaten +, die diesen Pod ausführen.

  • + Status +: Der Status des Pods. + Init + zeigt an, dass die Init-Container ausgeführt werden. In dieser Ausgabe sind 0 von 1 Init-Containern beendet.

  • + Neustart +: Wie oft wurde dieser Prozess neu gestartet, um den Pod zu starten. Diese Anzahl erhöht sich, wenn einer Ihrer Init-Container ausfällt. Die Bereitstellung wird neu gestartet, bis der gewünschte Status erreicht ist.

Abhängig von der Komplexität Ihrer Startskripte kann es einige Minuten dauern, bis der Status zu "+ podInitializing +" wechselt:

OutputNAME                   READY     STATUS            RESTARTS   AGE
php-86d59fd666-lkwgn   0/1       podInitializing   0          39s

Dies bedeutet, dass die Init-Container abgeschlossen sind und die Container initialisiert werden. Wenn Sie den Befehl ausführen, während alle Container ausgeführt werden, ändert sich der Pod-Status in "+ Running +".

OutputNAME                   READY     STATUS            RESTARTS   AGE
php-86d59fd666-lkwgn   1/1       Running   0          1m

Sie sehen nun, dass Ihr Pod erfolgreich ausgeführt wird. Wenn Ihr Pod nicht startet, können Sie mit den folgenden Befehlen debuggen:

  • Detaillierte Informationen zu einem Pod anzeigen:

kubectl describe pods
  • Von einem Pod generierte Protokolle anzeigen:

kubectl logs
  • Anzeigen von Protokollen für einen bestimmten Container in einem Pod:

kubectl logs

Ihr Anwendungscode ist angehängt und der PHP-FPM-Dienst kann jetzt Verbindungen herstellen. Sie können jetzt Ihre Nginx-Bereitstellung erstellen.

Schritt 5 - Erstellen der Nginx-Bereitstellung

In diesem Schritt verwenden Sie eine ConfigMap, um Nginx zu konfigurieren. Eine ConfigMap enthält Ihre Konfiguration in einem Schlüsselwertformat, auf das Sie in anderen Kubernetes-Objektdefinitionen verweisen können. Dieser Ansatz gibt Ihnen die Flexibilität, das Bild bei Bedarf wiederzuverwenden oder durch eine andere Nginx-Version zu ersetzen. Durch das Aktualisieren der ConfigMap werden die Änderungen automatisch auf alle Pod-Mounts repliziert.

Erstellen Sie mit Ihrem Editor eine + nginx_configMap.yaml + - Datei für Ihre ConfigMap:

nano nginx_configMap.yaml

Nennen Sie die ConfigMap "+ nginx-config " und gruppieren Sie sie in " tier: backend +" micro-service:

nginx_configMap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
 name: nginx-config
 labels:
   tier: backend

Als nächstes werden Sie die + Daten für die ConfigMap hinzufügen. Nennen Sie den Schlüssel "+ config +" und fügen Sie den Inhalt Ihrer Nginx-Konfigurationsdatei als Wert hinzu. Sie können die Nginx-Beispielkonfiguration unter https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04#step- verwenden. Drei-Server-Block-Dateien-für-jede-Domain erstellen [dieses Tutorial].

Da Kubernetes Anforderungen an den entsprechenden Host für einen Dienst weiterleiten kann, können Sie den Namen Ihres PHP-FPM-Dienstes im Parameter "+ fastcgi_pass " anstelle seiner IP-Adresse eingeben. Fügen Sie Ihrer Datei ` nginx_configMap.yaml +` Folgendes hinzu:

nginx_configMap.yaml

...
data:
 config : |
   server {
     index index.php index.html;
     error_log  /var/log/nginx/error.log;
     access_log /var/log/nginx/access.log;
     root ;

     location / {
         try_files $uri $uri/ /index.php?$query_string;
     }

     location ~ \.php$ {
         try_files $uri =404;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_pass ;
         fastcgi_index index.php;
         include fastcgi_params;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_param PATH_INFO $fastcgi_path_info;
       }
   }

Ihre + nginx_configMap.yaml + Datei sieht folgendermaßen aus:

nginx_configMap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
 name: nginx-config
 labels:
   tier: backend
data:
 config : |
   server {
     index index.php index.html;
     error_log  /var/log/nginx/error.log;
     access_log /var/log/nginx/access.log;
     root /code;

     location / {
         try_files $uri $uri/ /index.php?$query_string;
     }

     location ~ \.php$ {
         try_files $uri =404;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_pass php:9000;
         fastcgi_index index.php;
         include fastcgi_params;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_param PATH_INFO $fastcgi_path_info;
       }
   }

Speichern Sie die Datei und beenden Sie den Editor.

Erstellen Sie die ConfigMap:

kubectl apply -f nginx_configMap.yaml

Sie werden die folgende Ausgabe sehen:

Outputconfigmap/nginx-config created

Sie haben die Erstellung Ihrer ConfigMap abgeschlossen und können nun Ihre Nginx-Bereitstellung erstellen.

Öffnen Sie zunächst eine neue Datei + nginx_deployment.yaml + im Editor:

nano nginx_deployment.yaml

Nennen Sie das Deployment + nginx und fügen Sie das Label` + tier: backend` hinzu:

nginx_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx
 labels:
   tier: backend

Geben Sie an, dass Sie ein "+ Replikate " in der Bereitstellung " spec " möchten. Diese Bereitstellung verwaltet Pods mit den Bezeichnungen " app: nginx" und "+ tier: backend". Fügen Sie die folgenden Parameter und Werte hinzu:

nginx_deployment.yaml

...
spec:
 replicas: 1
 selector:
   matchLabels:
     app: nginx
     tier: backend

Fügen Sie als nächstes das Pod + template hinzu. Sie müssen dieselben Bezeichnungen verwenden, die Sie für das Deployment + selector.matchLabels + hinzugefügt haben. Fügen Sie Folgendes hinzu:

nginx_deployment.yaml

...
 template:
   metadata:
     labels:
       app: nginx
       tier: backend

Geben Sie Nginx Zugriff auf das zuvor erstellte "+ code " - PVC. Fügen Sie unter ` spec.template.spec.volumes +` Folgendes hinzu:

nginx_deployment.yaml

...
   spec:
     volumes:
     - name: code
       persistentVolumeClaim:
         claimName: code

Pods können eine ConfigMap als Volume bereitstellen. Wenn Sie einen Dateinamen und einen Schlüssel angeben, wird eine Datei mit ihrem Wert als Inhalt erstellt. Um die ConfigMap zu verwenden, setzen Sie "+ path " auf den Namen der Datei, die den Inhalt der " key " enthält. Sie möchten eine Datei " site.conf " mit dem Schlüssel " config " erstellen. Fügen Sie unter ` spec.template.spec.volumes +` Folgendes hinzu:

nginx_deployment.yaml

...
     - name: config
       configMap:
         name: nginx-config
         items:
         - key: config
           path: site.conf

Als Nächstes geben Sie das Bild an, aus dem Sie Ihren Pod erstellen möchten. In diesem Tutorial wird aus Stabilitätsgründen das Image + nginx: 1.7.9 + verwendet. Andere Nginx-Images finden Sie jedoch unter the Docker store. Stellen Sie außerdem Nginx auf dem Port "+ 80 " zur Verfügung. Unter ` spec.template.spec +` hinzufügen:

nginx_deployment.yaml

...
     containers:
     - name: nginx
       image:
       ports:
       - containerPort: 80

Nginx und PHP-FPM müssen auf die Datei unter demselben Pfad zugreifen. Hängen Sie also das Volume "+ code " unter " / code +" ein:

nginx_deployment.yaml

...
       volumeMounts:
       - name: code
         mountPath: /code

Das Image + nginx: 1.7.9 + lädt automatisch alle Konfigurationsdateien in das Verzeichnis + / etc / nginx / conf.d +. Wenn Sie das + config + - Volume in dieses Verzeichnis laden, wird die Datei + / etc / nginx / conf.d / site.conf + erstellt. Fügen Sie unter + volumeMounts + Folgendes hinzu:

nginx_deployment.yaml

...
       - name: config
         mountPath: /etc/nginx/conf.d

Ihre + nginx_deployment.yaml + Datei sieht folgendermaßen aus:

nginx_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx
 labels:
   tier: backend
spec:
 replicas: 1
 selector:
   matchLabels:
     app: nginx
     tier: backend
 template:
   metadata:
     labels:
       app: nginx
       tier: backend
   spec:
     volumes:
     - name: code
       persistentVolumeClaim:
         claimName: code
     - name: config
       configMap:
         name: nginx-config
         items:
         - key: config
           path: site.conf
     containers:
     - name: nginx
       image:
       ports:
       - containerPort: 80
       volumeMounts:
       - name: code
         mountPath: /code
       - name: config
         mountPath: /etc/nginx/conf.d

Speichern Sie die Datei und beenden Sie den Editor.

Erstellen Sie die Nginx-Bereitstellung:

kubectl apply -f nginx_deployment.yaml

Die folgende Ausgabe gibt an, dass Ihre Bereitstellung jetzt erstellt wurde:

Outputdeployment.apps/nginx created

Listen Sie Ihre Bereitstellungen mit diesem Befehl auf:

kubectl get deployments

Sie sehen die Nginx- und PHP-FPM-Bereitstellungen:

OutputNAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            0           16s
php       1         1         1            1           7m

Listen Sie die von beiden Bereitstellungen verwalteten Pods auf:

kubectl get pods

Sie sehen die Pods, die ausgeführt werden:

OutputNAME                     READY     STATUS    RESTARTS   AGE
nginx-7bf5476b6f-zppml   1/1       Running   0          32s
php-86d59fd666-lkwgn     1/1       Running   0          7m

Nachdem alle Kubernetes-Objekte aktiv sind, können Sie den Nginx-Dienst in Ihrem Browser aufrufen.

Listen Sie die ausgeführten Dienste auf:

kubectl get services -o wide

Holen Sie sich die externe IP für Ihren Nginx-Service:

OutputNAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE       SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    39m       <none>
nginx        ClusterIP   10.102.160.47    80/TCP     27m       app=nginx,tier=backend
php          ClusterIP   10.100.59.238   <none>        9000/TCP   34m       app=php,tier=backend

Besuchen Sie in Ihrem Browser Ihren Server, indem Sie "+ http: // " eingeben. Sie sehen die Ausgabe von " phpinfo () +" und haben bestätigt, dass Ihre Kubernetes-Dienste aktiv sind.

Fazit

In diesem Handbuch haben Sie die Dienste PHP-FPM und Nginx zusammengefasst, damit Sie sie unabhängig verwalten können. Dieser Ansatz verbessert nicht nur die Skalierbarkeit Ihres Projekts während Sie wachsen, sondern ermöglicht es Ihnen auch, Ressourcen effizient zu nutzen. Sie haben Ihren Anwendungscode auch auf einem Volume gespeichert, damit Sie Ihre Dienste in Zukunft problemlos aktualisieren können.

Related