Webinar-Reihe: Bereitstellen von Stateful Services in Kubernetes

Einführung

Kubernetes ist ein Open-Source-Container-Orchestrierungs-Tool zum Verwalten von containerisierten Anwendungen. In den vorherigen Teilen dieser Serie haben Sie die Bausteine ​​von Kubernetes und verpackten Containern als Kubernetes ReplicaSets kennengelernt. Während ReplicaSets die Verfügbarkeit zustandsloser Pods sicherstellen, können sie nicht mit statusbehafteten Workloads wie Datenbankclustern verwendet werden.

Während das Paketieren, Bereitstellen, Verwalten und Skalieren von zeitgemäßen cloud-nativen Anwendungen in Kubernetes möglicherweise einfach ist, erfordert das Bereitstellen und Verwalten traditioneller Workloads wie Datenbanken und Content-Management-Systeme in einer containerisierten Umgebung einen anderen Ansatz. StatefulSets bringt die Flexibilität von Kubernetes ReplicaSet auf stateful Workloads.

In der letzten Folge dieser Lernprogrammserie stellen Sie ein hochverfügbares MongoDB ReplicaSet in Kubernetes als StatefulSet unter Verwendung von Helm, einem beliebten Open Source-Paketmanager für Kubernetes, bereit.

Voraussetzungen

Um dieses Tutorial abzuschließen, benötigen Sie:

Schritt 1 - Installieren des Helm-Clients auf dem Entwicklungscomputer

Mit Helm können Administratoren komplexe Kubernetes-Anwendungen mit einem einzigen Befehl bereitstellen. Anwendungen werden als Charts gepackt, mit denen Kubernetes-Anwendungen definiert, installiert und aktualisiert werden. Diagramme bieten eine Abstraktion über Kubernetes-Objekte wie Pods, Bereitstellungen und Dienste.

Helm hat zwei Komponenten - den Server und den Client. Die Serverseite von Helm wird in Kubernetes als Dienst namens Tiller ausgeführt. Der Client ist ein Befehlszeilentool, das mit Tiller interagiert.

Da Sie ein MongoDB ReplicaSet-Helmdiagramm bereitstellen möchten, benötigen Sie die CLI, die mit Tiller, der serverseitigen Komponente von Helm, kommuniziert. StackPointCloud, mit dem Sie Kubernetes auf DigitalOcean eingerichtet haben, wird mit vorinstalliertem Tiller ausgeliefert.

Angenommen, Sie haben Homebrew auf Ihrem Mac installiert und konfiguriert, führen Sie den folgenden Befehl aus, um Helm zu installieren:

brew install kubernetes-helm
Output==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.8.2.high_sierra.bottle.tar.gz
...
==> Summary
🍺  /usr/local/Cellar/kubernetes-helm/2.8.2: 50 files, 121.7MB

Stellen Sie nach der Installation von Helm sicher, dass Sie es ausführen können, indem Sie die aktuelle Version überprüfen.

helm version
OutputClient: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}

Dies bestätigt, dass der Client ordnungsgemäß installiert ist und mit Tiller kommunizieren kann.

Im nächsten Schritt werden wir Helm verwenden, um das MongoDB ReplicaSet in Kubernetes bereitzustellen.

Schritt 2 - Bereitstellung des MongoDB ReplicaSet in Kubernetes

Eine StorageClass in Kubernetes bietet Administratoren die Möglichkeit, die von ihnen angebotenen „Speicherklassen“ zu beschreiben. Wenn Benutzer beispielsweise ein Speicher-Volume anfordern, bestimmt die StorageClass, welche Klasse von Speicher-Back-End von ihnen bereitgestellt wird. Die Klassen können Standard-HDD und eine schnellere SSD enthalten. Hinter den Kulissen interagiert die StorageClass mit der zugrunde liegenden Infrastruktur, z. B. der API eines Cloud-Anbieters, um Speicher bereitzustellen.

Da Sie permanenten Speicher zum Speichern von MongoDB-Daten benötigen, möchten Sie möglicherweise ein DigitalOcean-Blockspeicher-Volume an einen Arbeitsknoten anhängen und den MongoDB-Pod so ausrichten, dass das Speicher-Volume für die Persistenz verwendet wird.

In diesem Fall fungiert die StorageClass als Schnittstelle zwischen dem Pod und dem DigitalOcean-Blockspeicherdienst. Wenn Sie ein Blockspeicher-Volume anfordern, kommuniziert die StorageClass mit dem vorkonfigurierten Treiber, der weiß, wie ein Blockspeicher-Volume zugewiesen wird.

StackPointCloud installiert den DigitalOcean-Speichertreiber und registriert die StorageClass während des Setups bei Kubernetes. Dies erspart uns die Schritte zur Installation und Konfiguration des Treibers und der StorageClass.

Stellen Sie vor der Bereitstellung des MongoDB-Clusters sicher, dass die StorageClass für DigitalOcean-Volumes konfiguriert sind:

kubectl get storageclass

Die Ausgabe bestätigt, dass StorageClass konfiguriert und bereit ist.

[secondary_label Output
NAME                     PROVISIONER                            AGE
digitalocean (default)   digitalocean/flex-volume-provisioner   1d

Als Nächstes konfigurieren und implementieren Sie das MongoDB ReplicaSet basierend auf der DigitalOcean StorageClass.

Erstellen Sie ein neues Verzeichnis für Ihr Projekt und wechseln Sie in das neue Verzeichnis:

mkdir ~/mongo-rs
cd ~/mongo-rs

Klonen Sie das Helm Chart Repository von GitHub:

git clone https://github.com/kubernetes/charts.git

Navigieren Sie zum MongoDB ReplicaSet-Verzeichnis (+ charts / stable / mongodb-replicaset / +) und vergewissern Sie sich, dass die Datei + values.yaml + existiert.

cd charts/stable/mongodb-replicaset/
ls values.yaml
Outputvalues.yaml

Diese Datei enthält die Parameter und die Konfiguration für das Diagramm. Sie müssen diese Datei ändern, um MongoDB ReplicaSet für die Verwendung der DigitalOcean StorageClass zu konfigurieren.

Bearbeiten Sie + values.yaml +:

nano values.yaml

Suchen Sie den folgenden Abschnitt und kommentieren Sie ihn aus:

values.yaml

...
# storageClass: "-"
...

Ersetzen Sie "" - "" durch "" digitalocean "" wie folgt:

values.yaml

...
storageClass:
...

Speichern Sie die Datei und beenden Sie Ihren Editor.

Navigieren Sie nun zum Ordner "+ ~ / mongo-rs +".

cd ~/mongo-rs

Jetzt können Sie das MongoDB ReplicaSet auf Ihrem Kubernetes-Cluster bereitstellen, der über den Blockspeicher von DigitalOcean betrieben wird. Führen Sie den folgenden Befehl aus, um den Datenbankcluster zu starten.

helm install --name= -f charts/stable/mongodb-replicaset/values.yaml stable/mongodb-replicaset

Im vorhergehenden Befehl bezieht sich "+ - name " auf den Namen der Helmkarte. Der Schalter " -f " zeigt auf die in " values.yaml +" gespeicherten Konfigurationseinstellungen.

Sie sehen sofort die Ausgabe, die bestätigt, dass die Diagrammerstellung gestartet wurde.

OutputNAME:   todo
LAST DEPLOYED: Sat Mar 31 10:37:06 2018
NAMESPACE: default
STATUS:

RESOURCES:
==> v1/Service
NAME                     TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)    AGE
 ClusterIP  None        <none>       27017/TCP  1s

==> v1beta1/StatefulSet
NAME                     DESIRED  CURRENT  AGE
 3        1        0s

==> v1/Pod(related)
NAME                       READY  STATUS    RESTARTS  AGE
 0/1    Init:0/2  0         0s

==> v1/ConfigMap
NAME                           DATA  AGE
       1     1s
 1     1s


NOTES:
1. After the statefulset is created completely, one can check which instance is primary by running:

   $ for ((i = 0; i < 3; ++i)); do kubectl exec --namespace default todo-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done

2. One can insert a key into the primary instance of the mongodb replica set by running the following:
   MASTER_POD_NAME must be replaced with the name of the master found from the previous step.

   $ kubectl exec --namespace default MASTER_POD_NAME -- mongo --eval="printjson(db.test.insert({key1: 'value1'}))"

3. One can fetch the keys stored in the primary or any of the slave nodes in the following manner.
   POD_NAME must be replaced by the name of the pod being queried.

   $ kubectl exec --namespace default POD_NAME -- mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"

Führen Sie nun eine Reihe von Befehlen aus, um den Status des Clusters zu verfolgen.

Schauen Sie sich zunächst das StatefulSet an:

kubectl get statefulset

Dieser Befehl bestätigt, dass das MongoDB ReplicaSet als Kubernetes StatefulSet erstellt wurde.

OutputNAME                      DESIRED   CURRENT   AGE
  3         2         2m

Jetzt erforsche die Pods:

kubectl get pods

Die Anzahl der Pods und ihre Namenskonvention zeigen an, dass das MongoDB ReplicaSet erfolgreich konfiguriert wurde:

OutputNAME                        READY     STATUS        RESTARTS   AGE
  1/1       Running       0          3m
  1/1       Running       0          1m
  1/1       Running       0          54s

Beachten Sie, dass jeder Pod ein Suffix hat, das mit einer fortlaufenden Nummer endet, die ein charakteristisches Merkmal eines StatefulSet ist.

Überprüfen wir nun, ob die MongoDB-Instanzen miteinander kommunizieren. Dazu führen wir einen Befehl in der MongoDB-Shell in einem der Pods aus.

Verwenden Sie "+ kubectl ", um die " mongo +" - Konsole auf einem der Hosts zu starten:

kubectl exec -it  mongo

Nach dem Herstellen der Verbindung befinden Sie sich in der MongoDB-Shell:

OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
...

2018-03-31T05:08:20.239+0000 I CONTROL  [initandlisten]

Überprüfen Sie die Konfiguration des ReplicaSets mit dem folgenden Befehl:

rs.conf()

Die Ausgabe bestätigt, dass drei Instanzen von MongoDB als ReplicaSet ausgeführt werden.

Output{
   "_id" : "rs0",
   "version" : 3,
   "protocolVersion" : NumberLong(1),
   "members" : [
       {
           "_id" : 0,
           "host" : ",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 1,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 2,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       }
   ],
   "settings" : {
       "chainingAllowed" : true,
       "heartbeatIntervalMillis" : 2000,
       "heartbeatTimeoutSecs" : 10,
       "electionTimeoutMillis" : 10000,
       "catchUpTimeoutMillis" : -1,
       "catchUpTakeoverDelayMillis" : 30000,
       "getLastErrorModes" : {

       },
       "getLastErrorDefaults" : {
           "w" : 1,
           "wtimeout" : 0
       },
       "replicaSetId" : ObjectId("5abdb4f61d952afc4b0b8218")
   }
}

Beenden Sie die MongoDB-Konsole:

exit

Dadurch werden Sie auch von Ihrem Remote-Host getrennt.

Lassen Sie uns die Gänge wechseln und die DigitalOcean-Systemsteuerung auf die Blockspeicher-Volumes überprüfen, die dem Cluster zugeordnet sind. Melden Sie sich bei Ihrem DigitalOcean-Konto an und wählen Sie die Registerkarte * Volumes *:

image: https: //assets.digitalocean.com/articles/webinar_6_stateful_services/IcNUFQb.jpg [Dashboard mit Volumes]

Sie sehen, dass drei Volumes mit jeweils 10 GB an Kubernetes Worker-Knoten angeschlossen sind. Jeder Pod des MongoDB StatefulSet speichert die Daten in einem der Blockspeicher-Volumes. Die Größe von 10 GB wird in "+ values.yaml " im Abschnitt " persistentVolume +" definiert.

values.yaml

persistentVolume:
 enabled: true
 ## mongodb-replicaset data Persistent Volume Storage Class
 ## If defined, storageClassName: <storageClass>
 ## If set to "-", storageClassName: "", which disables dynamic provisioning
 ## If undefined (the default) or set to null, no storageClassName spec is
 ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
 ##   GKE, AWS & OpenStack)
 ##
 storageClass: digitalocean
 accessModes:
   - ReadWriteOnce

 annotations: {}

Sie haben erfolgreich ein hochverfügbares MongoDB ReplicaSet konfiguriert, das in Kubernetes ausgeführt wird.

Stellen wir nun die Webanwendung bereit, die mit dem MongoDB-Cluster kommuniziert.

Schritt 3 - Bereitstellen und Skalieren der Webanwendung in Kubernetes

Erweitern wir die Anwendung ToDo Node.js, die wir in früheren Teilen dieser Lernprogrammserie verwendet haben, um den MongoDB-Cluster zu nutzen.

Beginnen Sie mit dem Erstellen eines neuen Arbeitsverzeichnisses:

mkdir ~/web-app
cd ~/web-app

Klonen Sie dann das Repository der ToDo-Anwendung, das den Code und die Kubernetes-Artefakte enthält.

git clone https://github.com/janakiramm/todo.git

Wechseln Sie in das Verzeichnis + todo-app / kubernetes +, das die Kubernetes-Konfigurationsdateien enthält.

cd todo-app/kubernetes

Öffnen Sie die Datei "+ web-rs-ss.yaml +" in Ihrem Editor.

nano web-rs-ss.yaml

Beachten Sie den Abschnitt "+ env +" in der YAML-Datei.

web-rs-ss.yaml

     containers:
     - name: web
       image: janakiramm/todo



       ports:
       - containerPort: 3000

Dadurch wird die Datenbankverbindungszeichenfolge zur Laufzeit als Umgebungsvariable an die Anwendung übergeben. Anstatt die Anwendung auf einen einfachen MongoDB-Pod zu verweisen, verwendet diese Version der App das von Ihnen erstellte StatefulSet. Jeder Eintrag im Abschnitt "+ value +" bezieht sich auf einen der Pods des MongoDB StatefulSet.

Verwenden Sie "+ kubectl ", um das " web " - Replikatset zusammen mit dem " web +" - Dienst bereitzustellen

kubectl create -f web-rs-ss.yaml -f web-service.yaml

Sie werden sehen, dass beide erstellt wurden:

Outputreplicaset "web" created
service "web" created

Listen Sie die Pods erneut auf:

kubectl get pods

Sie sehen nun alle Pods von MongoDB und der Web-App.

OutputNAME                        READY     STATUS    RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running   0          26m
todo-mongodb-replicaset-1   1/1       Running   0          24m
todo-mongodb-replicaset-2   1/1       Running   0          23m



Let’s check out the Kubernetes services

​```command
kubectl get svc
OutputNAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
kubernetes                ClusterIP   10.3.0.1     <none>        443/TCP          1d
todo-mongodb-replicaset   ClusterIP   None         <none>        27017/TCP        27m

Die "+ web " - Pods kommunizieren mit dem MongoDB - Cluster über den " todo-mongodb-replicaset " - Dienst. Die Webanwendung ist über den Dienst " web " auf NodePort " 31201 +" verfügbar.

Wenn Sie auf diesen Port auf einem beliebigen Arbeitsknoten zugreifen, wird die Webanwendung angezeigt.

Sie können die Webanwendung skalieren, indem Sie die Anzahl der Pods im ReplicaSet erhöhen.

kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled

Sie können die Anwendung dann auf zwei Pods zurückskalieren.

kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled

Lassen Sie uns nun einige Tests zur Verfügbarkeit durchführen.

Schritt 4 - Testen des MongoDB ReplicaSet auf Hochverfügbarkeit

Einer der Vorteile der Ausführung eines StatefulSet ist die hohe Verfügbarkeit von Workloads. Testen wir dies, indem wir einen der Pods im MongoDB StatefulSet löschen.

kubectl delete pod todo-mongodb-replicaset-2
Outputpod "todo-mongodb-replicaset-2" deleted

Überprüfen Sie die Anzahl der Pods:

kubectl get pods

Sie werden sehen, dass + todo-mongodb-replica set-2 + beendet wird:

OutputNAME                        READY     STATUS        RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running       0          33m
todo-mongodb-replicaset-1   1/1       Running       0          32m

web-t5zzk                   1/1       Running       0          8m
web-x6dh8                   1/1       Running       0          8m

Innerhalb weniger Minuten werden Sie feststellen, dass Kubernetes einen anderen Pod initialisiert, um den gelöschten zu ersetzen.

kubectl get pods

Sie werden sehen, dass + todo-mongodb-replica set-2 + initialisiert wird:

NAME                        READY     STATUS     RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running    0          34m
todo-mongodb-replicaset-1   1/1       Running    0          33m

web-t5zzk                   1/1       Running    0          8m
web-x6dh8                   1/1       Running    0          8m

Jetzt, wo Sie wissen, dass alles funktioniert, können Sie die Dinge aufräumen.

Löschen Sie alle in diesem Lernprogramm erstellten Objekte mit den folgenden Befehlen:

helm delete --purge todo
kubectl delete -f web-rs-ss.yaml -f web-service.yaml
Outputreplicaset "web" deleted
service "web" deleted

Um den Kubernetes-Cluster selbst zu löschen, rufen Sie StackPointCloud auf und klicken Sie in der Systemsteuerung auf.

Fazit

In diesem Lernprogramm haben Sie ein dauerhaftes, beständiges und hochverfügbares MongoDB-Replikatset als Kubernetes StatefulSet bereitgestellt. Sie haben auch gelernt, wie Sie von anderen Anwendungen, die im selben Kubernetes-Cluster implementiert sind, auf das StatefulSet zugreifen.