Schritt für Schritt

Tutorial: CrateDB Cluster mit Kubernetes aufsetzen

Mika Naylor

© Shutterstock / ESB Professional

Dank ihrer horizontal skalierbaren Shared-Nothing-Architektur eignet sich die Datenbank CrateDB sehr gut, um mit Container-Technologien wie Docker zu arbeiten. Im praktischen Leben erweist es sich zumeist als sinnvoll, Docker um eine Container-Orchestrierungs-Lösung zu ergänzen – einfach weil die Anzahl der Container schnell wächst und Runtime-Abhängigkeiten untereinander entstehen, die aufeinander abgestimmt werden müssen. Eine dieser Lösungen ist Kubernetes, wie Mika Naylor in diesem Tutorial zeigt.

Kubernetes ist ein Open-Source-Werkzeug mit großer, aktiver Community und namhaften Unterstützern. Einen CrateDB Cluster mit Kubernetes aufzusetzen, ist in wenigen Schritten machbar. Scale-Out und Scale-In sind unkompliziert, was den Cluster besonders flexibel macht.

Kubernetes: von Pods, Controllern und Services

Hinter dem Begriff „Container-Orchestrierung“ steckt das Management, das Deployment und die Skalierung von containerisierten Systemen. Im Prinzip ist Kubernetes ein System von Prozessen, die verteilt über alle zum Kubernetes Cluster gehörenden Nodes laufen. Mindestens ein Knoten muss dabei als Master fungieren, die Anzahl der Slaves ist dabei beliebig. Die Container, die die Software zum Laufen bringen, die deployt werden soll, werden dann intelligent auf alle Kubernetes Nodes verteilt. Je nach Funktion des jeweiligen Servers laufen unterschiedliche Komponenten von Kubernetes darauf. So entstehen praktisch diverse Instanzen dieser Komponenten, die sich über mehrere Maschinen hinweg koordinieren. Um den Zustand eines Kubernetes Clusters zu definieren, sind vor allem drei Konzepte von Bedeutung: Pods, Controller und Services.

Ein Pod repräsentiert eine einzelne Recheneinheit und damit den grundlegenden Baustein jedes Systems. Das kann ein einzelner Container sein oder mehrere eng miteinander verbundene. Wird beispielsweise eine Webapplikation deployt, so führt ein Pod eine einzelne Instanz der Anwendung aus. Pods lassen sich horizontal skalieren, indem zum Beispiel Replica Pods hinzugefügt oder – bei einem Scale-In – entsprechend entfernt werden. Komplexere Anwendungen benötigen oft mehr als einen Container. Alle Container in einem Pod teilen sich eine gemeinsame Netzwerkschnittstelle, und jeder Container hat Zugriff auf die dem Pod zugeordneten Speichervolumen. Das offizielle CrateDB Docker Image eignet sich sehr gut als Single Container Pod, aus einer Kombination von mehreren kann ein CrateDB Cluster beliebiger Größe entstehen.

Pods werden normalerweise nicht von Hand erstellt, sondern Controller kreieren sie. Controller managen ein Set von Pods gemäß einer vorgegebenen Spezifikation. Kubernetes stellt von Haus aus mehrere Controller für unterschiedliche Zwecke bereit. Ein Beispiel: Idealerweise sollten Container stateless sein, damit es keine negativen Auswirkungen hat, wenn etwa ein Container zerstört, neu gebaut oder auf einen anderen Server verschoben wird. Aber: Zustandslose Container eignen sich zwar für Webanwendungen, die den Zustand gegenüber einer externen Datenbank aufrechterhalten. Die Datenbanken selbst erfordern jedoch eine persistente Speicherung: Die Daten sollen nicht verloren gehen, nur weil ein Container neu geschedult wurde. Kubernetes stellt den StatefulSet Controller bereit, der jedem Pod eine feste Identität und einen festen Speicherplatz zuweist, die bei Neustarts und Re-Scheduling erhalten bleiben. Der Controller erstellt dabei alle Pods innerhalb eines StatefulSets aus derselben Vorlage, dennoch sind sie nicht austauschbar.

Da die Pods gestoppt, gestartet und auf jeden beliebigen Kubernetes-Knoten neu verplant werden können, ändern sich die zugewiesenen IP-Adressen im Laufe der Zeit. Client-Anwendungen sollen jedoch nicht mit wechselnden IP-Adressen zurechtkommen müssen. Dafür gibt es die Kubernetes-Services: statische Interfaces, um Zugang zu einem oder mehreren Pods zu erhalten. Ein typischer Service ist ein Load Balancer, der die ankommenden Queries auf den gesamten Cluster verteilt. Das Verständnis für die beschriebenen Kubernetes-Konzepte ist notwendig, um die Konfigurationen für den CrateDB Cluster nachvollziehen zu können.

Den Kubernetes Cluster aufsetzen

Für einen unkomplizierten und trotzdem leistungsfähigen Start eignet sich Minikube, mit dem Kubernetes einfach lokal ausgeführt werden kann. Minikube ist in der Lage, mit verschiedenen Hypervisoren als VM-Laufzeit zu arbeiten, standradmäßig ist aber alles für die Arbeit mit VirtualBox – einer populären Cross-Plattform – vorbereitet. Wenn ein kompatibler Hypervisor wie VirtualBox auf dem System installiert ist, erkennt Minikube diesen und setzt die VM automatisch auf. Darüber hinaus wird die Standard-Kommandozeile kubectl benötigt, mit der sich Kubernetes Cluster Anweisungen geben lassen.

Sind alle drei Komponenten installiert, kann das System gestartet werden. Per Default weist Minikube der VM 1GB Speicher zu. Dies kann nach Bedarf angepasst werden, wie im folgenden Beispiel mit --memory 4096.

$ minikube start --memory 4096

Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Downloading Minikube ISO
160.27 MB / 160.27 MB [======================================] 100.00% 0s
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

Um den neu geschaffenen Kubernetes Cluster verwenden zu können, konfiguriert Minikube nun automatisch kubectl. Mit folgendem Befehl lässt sich das überprüfen:

$ kubectl get nodes
 
NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     master    4m        v1.10.0

Mit der Hilfe von Namespaces unterteilt Kubernetes den physischen Cluster in mehrere Bereiche. Technisch gesehen muss für den CrateDB Cluster kein extra Namensraum angelegt werden, es empfiehlt sich aber, um den Überblick über die Ressourcen zu bewahren. Mit dem folgenden Kommando wird ein neuer Namespace kreiert:

$ kubectl create namespace crate

namespace/crate created

Fragt man die vorhandenen Namespaces nun ab, taucht der neu geschaffene (crate) unter den üblichen Namespaces auf. Während der Namespace default immer dann genutzt wird, wenn kein anderer spezifiziert wurde, steht kube-public für alle Ressourcen, die öffentlich verfügbar sind und kube-system für die intern von Kubernetes genutzten Ressourcen.

$ kubectl get namespaces
 
NAME          STATUS    AGE
default       Active    32m
kube-public   Active    31m
kube-system   Active    32m
crate         Active    59s

Die CrateDB Services einrichten

Damit CrateDB arbeiten kann, muss jeder CrateDB-Knoten mit den anderen Nodes des Clusters kommunizieren können. Dafür wird ein Kubernetes-Service mit dem Namen crate-internal-service.yaml erzeugt, der auf alle Pods abgebildet wird, die das Label app:crate tragen. Label sind Key/Value-Wertepaare, die an Objekten (wie z. B. Pods) kleben, um sie mit Attributen zu versehen ohne die Semantik zu ändern. In einem weiteren Schritt müssen dann noch alle CrateDB Pods mit dem app:crate-Label versehen werden. Zudem wird mit dem folgenden Code eine feste IP-Adresse festgelegt und zugleich definiert, dass der Dienst auf Port 4300 zur Verfügung gestellt wird, dem Standardport, den CrateDB für die Kommunikation zwischen den Nodes verwendet. Hier die Konfiguration:

kind: Service
apiVersion: v1
metadata:
  name: crate-internal-service
  labels:
    app: crate
spec:
  # A static IP address is assigned to this service. This IP address is
  # only reachable from within the Kubernetes cluster.
  type: ClusterIP
  ports:
    # Port 4300 for inter-node communication.
  - port: 4300
    name: crate-internal
  selector:
    # Apply this to all nodes with the `app:crate` label.
    app: crate

Nun kann der Service erzeugt werden:

$ kubectl create -f crate-internal-service.yaml --namespace crate

service/crate-internal created

Kubernetes erzeugt die SRV Records, mit deren Hilfe über den DNS propagiert werden kann, welche Services der Cluster bietet. In einem späteren Schritt können diese verwendet werden, um CrateDB Unicast Host Discovery einzurichten.

Damit auch Clients Abfragen auf der CrateDB ausführen können, müssen die Pods von extern angesprochen werden können. Hierfür wird ein externer Service (crate-external-service) geschaffen, der genau wie der interne Service auf alle Pods mit app:crate-Label verweist. Kubernetes wird nun einen externen Load Balancer erzeugen. Normalerweise ist ein solcher Service nur bei einer gehosteten Lösung verfügbar. In diesem Fall aber nutzt Kubernetes den Load Balancer, den die gehostete Lösung bereitstellt. Es ergibt sich folgende Konfiguration:

kind: Service
apiVersion: v1
metadata:
  name: crate-external-service
  labels:
    app: crate
spec:
  # Create an externally reachable load balancer.
  type: LoadBalancer
  ports:
    # Port 4200 for HTTP clients.
  - port: 4200
    name: crate-web
    # Port 5432 for PostgreSQL wire protocol clients.
  - port: 5432
    name: postgres
  selector:
    # Apply this to all nodes with the `app:crate` label.
    app: crate

Nun kann der externe Service erzeugt werden:

$ kubectl create -f crate-external-service.yaml --namespace crate

service/crate-external created

Den CrateDB Controller definieren

Mit den Services sind nun die Interfaces zum CrateDB Cluster erzeugt worden. Nun wird noch ein Controller benötigt, mit dem der Cluster zusammengesetzt und verwaltet wird. Die Konfiguration für crate-controller.yaml ist etwas umfangreicher und enthält folgende Punkte:

 

  • Der Kubernetes-Controller erzeugt Pods: crate-0, crate-1, crate-2, etc.
  • Der Controller erzeugt ein StatefulSet namens crate-set. Dafür sind drei CrateDB Pods mit fester Identität und persistentem Speicher notwendig.
  • Jeder Pod trägt das app:crate-Label, damit es mit den zuvor erzeugten Services angesprochen werden kann.
  • Es werden InitContainer (spezialisierte Container, die innerhalb eines Pods vor dem App-Container laufen) genutzt, um das passende Memory Map Limit zu konfigurieren, so dass CrateDB den Bootstrap Check besteht. Solche Checks werden automatisiert durchgeführt, um rechtzeitig Laufzeit-Probleme zu erkennen.
  • Jedem Pod werden 512 MB zugewiesen, so dass der Cluster 1,5 GB der insgesamt 4 GB nutzt. So bleibt noch Raum für Wachstum.
  • Die CrateDB Container, die jeden Pod zum Laufen bringen, werden definiert. Es kommt die Version 4.1.4 des CrateDB Docker Images zum Einsatz.
  • Der crate-internal-service erstellt die SRV Records.
  • Jeder Pod stellt verschiedene Ports zur Verfügung: Port 4300 für die Kommunikation innerhalb jedes Knotens, Port 4200 für HTTP Clients und Port 5432 für PostgreSQL Wire Protocol Clients.
  • Nun werden noch einige Environment Variables – Variablen, deren Wert außerhalb des Programms gesetzt werden – definiert. CrateDB erkennt die Größe des nutzbaren Memorys (CRATE HEAP SIZE), mit 256 MB sind das 50 Prozent des zur Verfügung stehenden Speichers. Die Command Line Options nutzen den Rest.
  • Um schnell starten zu können, kommt RAM Drive als temporäre Speicherlösung zum Einsatz.
kind: StatefulSet
apiVersion: "apps/v1"
metadata:
  # This is the name used as a prefix for all pods in the set.
  name: crate
spec:
  serviceName: "crate-set"
  # Our cluster has three nodes.
  replicas: 3
  selector:
    matchLabels:
      # The pods in this cluster have the `app:crate` app label.
      app: crate
  template:
    metadata:
      labels:
        app: crate
    spec:
      # InitContainers run before the main containers of a pod are 
      # started, and they must terminate before the primary containers 
      # are initialized. Here, we use one to set the correct memory
      # map limit.
      initContainers:
      - name: init-sysctl
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      # This final section is the core of the StatefulSet configuration. 
      # It defines the container to run in each pod.
      containers:
      - name: crate
        # Use the CrateDB 4.1.4 Docker image.
        image: crate:4.1.4
        # Pass in configuration to CrateDB via command-line options. 
        # Give the initial master nodes by their node names.
        # This has just to be done by initial cluster creation.
        command:
          - /docker-entrypoint.sh
          - -Cnode.name=${POD_Name}
          - -Ccluster.name=${CLUSTER_NAME}
          - -Ccluster.initial_master_nodes=crate-0,crate-1,crate-2
          - -Cdiscovery.seed_providers=srv
          - -Cdiscovery.srv.query=_crate-internal._tcp.crate-internal-service.${NAMESPACE}. svc.cluster.local
          - -Cgateway.recover_after_nodes=2
          - -Cgateway.expected_nodes=${EXPECTED_NODES}
          - -Cpath.data=/data
        volumeMounts:
              # Mount the `/data` directory as a volume named `data`.
            - mountPath: /data
              name: data
        resources:
          limits:
            # How much memory each pod gets.
            memory: 512Mi
        ports:
          # Port 4300 for inter-node communication.
        - containerPort: 4300
          name: crate-internal
          # Port 4200 for HTTP clients.
        - containerPort: 4200
          name: crate-web
          # Port 5432 for PostgreSQL wire protocol clients.
        - containerPort: 5432
          name: postgres
        # Environment variables passed through to the container.
        env:
          # This is variable is detected by CrateDB.
        - name: CRATE_HEAP_SIZE
          value: "256m"
          # The rest of these variables are used in the command-line
          # options.
        - name: EXPECTED_NODES
          value: "3"
        - name: CLUSTER_NAME
          value: "my-crate"
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      volumes:
        # Use a RAM drive for storage which is fine for testing, but must
        # not be used for production setups!
        - name: data
          emptyDir:
            medium: "Memory"

Nachdem die Konfiguration gespeichert wurde, kann der Controller erzeugt werden:

$ kubectl create -f crate-controller.yaml --namespace crate

statefulset.apps/crate-controller created

Der StatefulSet Controller bringt jeden CrateDB Pod einzeln hervor. Mit dem folgenden Kommando lässt sich dieser Prozess beobachten:

$ kubectl get pods --namespace crate
 
NAME      READY     STATUS            RESTARTS   AGE
crate-0   0/1       PodInitializing   0          36s

Schließlich ist der CrateDB Cluster vollständig initialisiert:

$ kubectl get pods --namespace crate
 
NAME      READY     STATUS    RESTARTS   AGE
crate-0   1/1       Running   0          2m
crate-1   1/1       Running   0          1m
crate-2   1/1       Running   0          1m

Access zum CrateDB Cluster

Bevor jemand auf CrateDB zugreifen kann, muss sichergestellt werden, dass der externe Service läuft:

$ kubectl get service --namespace crate
 
NAME                    TYPE          CLUSTER-IP      EXTERNAL-IP  PORT(S)                        AGE
crate-external-service  LoadBalancer  10.96.227.26        4200:31159/TCP,5432:31316/TCP  44m
crate-internal-service  ClusterIP     10.101.192.101         4300/TCP                       44m

Die Spalte „PORT (S)“ zeigt, dass der Kubernetes Port 31159 mit dem CrateDB Port 4200 (HTTP) verbunden ist sowie der Kubernetes Port 31316 mit dem CrateDB Port 5432 (PostgreSQL Wire Protocol). Aufgrund einer Eigenart von Minikube, ist der Status der externen IP noch mit „pending“ angegeben. Hierfür ist ein Workaround notwendig.

Zunächst werden die Minikube-Services gesondert abgefragt:

$ minikube service list --namespace crate
 
|------------|------------------------|--------------------------------|
| NAMESPACE  |          NAME          |              URL               |
|------------|------------------------|--------------------------------|
| my-cratedb | crate-external-service | http://192.168.99.100:31159    |
|            |                        | http://192.168.99.100:31316    |
| my-cratedb | crate-internal-service | No node port                   |
|------------|------------------------|--------------------------------|

Zwei Ports (192.168.99.100) werden angezeigt, jedoch beide mit HTTP als Spezifikation. Für den CrateDB HTTP Port ist das korrekt, jedoch nicht für den PostgreSQL Port. Für das hier beschriebene Beispiel ist der HTTP Port interessant (31159), dessen Funktionstüchtigkeit mit einem einfachen HTTP Request überprüft werden kann. Sieht die HTTP-API-Antwort so aus, funktioniert alles wie erwartet:

$ curl 192.168.99.100:31159
 
{
  "ok" : true,
  "status" : 200,
  "name" : "Regenstein",
  "cluster_name" : "my-crate",
  "version" : {
   "number" : "4.1.4",
   "build_hash" : "6a9f8ebc5fefd63f666caa6f28e29b4b214ac7fc",
   "build_timestamp" : "2020-03-20T10:40:21Z",
   "build_snapshot" : false,
   "lucene_version" : "8.4.0"
 }
}

Die Netzwerkadresse (hier im Tutorial ist es 192.168.99.100:31159) kann nun in den Browser kopiert werden. Folgendes CrateDB Admin UI sollte erscheinen

Mit einem Klick auf den Cluster Screen im linken Navigationsmenü, wird ersichtlich, dass der CrateDB Cluster wie erwartet drei Nodes hat:

Im „Getting Started“ Guide von Crate.io finden sich weitere Details über den Import von Testdaten und die Erstellung von Queries.

Persistenten Speicher konfigurieren

In der Praxis ist es wünschenswert, wenn die Daten im Cluster typische Power-Cycling-Szenarien (Aus- und wieder Anschalten der Hardware) unbeschadet überstehen. Bisher sehen die letzten Zeilen der beispielhaften Controller-Datei crate-controller.yaml so aus:

	volumes:
    	# Use a RAM drive for storage which is fine for testing, but must
    	# not be used for production setups!
    	- name: data
      	emptyDir:
        	medium: "Memory"

Um einen persistenten Disk-Speicher einzurichten, stellt Kubernetes das Subsystem Persistent Volumes zur Verfügung. Es stellt APIs für User und Administratoren bereit, die Details über die Bereitstellung von Speicher von der Art und Weise abstrahiert, wie dieser verbraucht wird. Eines dieser APIs ist PersistentVolumesClaim. Dieses weist Kubernetes an, Speicherplatz von der zugrundeliegenden Infrastruktur anzufordern. Hinsichtlich der Implementierungsdetails ist Kubernetes agnostisch.

Der oben beschriebene Teil (ab volumes:) der Controller-Datei muss nun durch eine neue Konfiguration ersetzt werden. Im folgenden Beispiel wird 1GB persistenter Speicher pro Pod angefordert – es kann natürlich auch eine andere Speichergröße gewählt werden. Die folgende Config Section gehört dabei auf dieselbe Einrückebene wie serviceName: "crate-set", also deutlich weiter nach links:

  volumeClaimTemplates:
	# Use persistent storage.
	- metadata:
    	name: data
  	spec:
    	accessModes:
    	- ReadWriteOnce
    	resources:
      	requests:
        	storage: 1Gi

Leider können die bereits existierenden Pods nicht geupdatet werden, da das Storage Device geändert werden soll. Im Zuge dieser Änderung gehen also alle Daten verloren, die bisher in CrateDB geschrieben wurden. So muss der Controller gelöscht und neu erzeugt werden:

$ kubectl replace --force -f crate-controller.yaml --namespace crate
 
statefulset.apps "crate" deleted
statefulset.apps/crate replaced

Ob den Pods nun jeweils 1GB zur Verfügung steht, lässt sich mit folgendem Befehl verifizieren:

$ kubectl get pvc --namespace crate
 
NAME       	STATUS	VOLUME                                 	CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-crate-0   Bound 	pvc-281c14ef-a47e-11e8-a3df-080027220281   1Gi    	RWO        	standard   	3m
data-crate-1   Bound 	pvc-53ec50e1-a47e-11e8-a3df-080027220281   1Gi    	RWO        	standard   	2m
data-crate-2   Bound 	pvc-56d3433e-a47e-11e8-a3df-080027220281   1Gi    	RWO        	standard   	2m

Horizontal auf fünf Knoten skalieren

Das vorgefertigte CrateDB-Paket, welches sich jeder von der Website Crate.io herunterladen kann, ist auf 3 Nodes begrenzt. Eine Überschreitung dieser Begrenzung führt zu Funktionsstörungen. Wer nicht auf die deutlich leistungsfähigere, aber auch kostenpflichtige Enterprise Edition zurückgreifen möchte, kann seinen Cluster dennoch erweitern, in dem er die CrateDB Community Edition „from the source“ nutzt.

Mit dem folgenden Code lässt sich die CrateDB aufbauen:

sh$ git clone https://github.com/crate/crate
sh$ cd crate
sh$ git submodule update --init
sh$ git checkout <TAG>
sh$ ./gradlew clean communityEditionDistTar

Als <TAG> muss nun der Commit Hash des Git-Tags eingefügt werden, der der Version entspricht, die genutzt werden soll. Sobald der gradlew-Befehl erfolgreich ausgeführt wurde, liegt das gewünschte CrateDB CE Release als komprimiertes Tarball-Archiv in dem Verzeichnis app/build/distributions.

Durch die Erhöhung oder die Verringerung (für ein Scale-In) der Anzahl der verwendeten Replicas kann die horizontale Skalierung nun einfach umgesetzt werden. In diesem Beispiel hier wurden in der Controller-Konfiguration zunächst drei Replicas definiert:

# Our cluster has three nodes.
replicas: 3

Die Anzahl lässt sich verändern, während der Cluster läuft. Das ist besonders praktisch, wenn beispielsweise Traffic Peaks schnell abgefangen werden müssen. Soll dies eine permanente Änderung sein, ist dieses Vorgehen allerdings nicht ideal, das CrateDB Admin UI wird eine entsprechende Warnung anzeigen.

In der Datei crate-controller.yaml werden nun folgende Änderungen vorgenommen: Die Anzahl der Replicas wird von 3 auf 5 gesetzt:

# Our cluster has five nodes.
replicas: 5

Den Rest übernimmt CrateDB automatisch: Die Expected_Nodes werden auf den Wert 5 gesetzt und sowohl Minimum_Master_Nodes als auch die Recover_After_Nodes angepasst. Diese sollten mindestens so groß sein, wie die halbe Cluster-Größe plus 1. Sprich: Das System setzt sie nun von 2 auf 3.

Weil diesmal nur die Sektionen Replicas und Container geändert wurden, kann die Controller-Konfiguration direkt geupdatet werden:

$ kubectl replace -f crate-controller.yaml --namespace crate
 
statefulset.apps/crate replaced

Mit dem kubectl-Befehl kann auch dieser Prozess beobachtet werden, während er stattfindet. Kubernetes beendet die bisher laufenden Pods zunächst, startet sie aber dann erneut mit derselben Identität und demselben Speicher. Schließlich wird folgendes Ergebnis sichtbar:

$ kubectl get pods --namespace crate
 
NAME  	READY 	STATUS	RESTARTS   AGE
crate-0   1/1   	Running   0      	11m
crate-1   1/1   	Running   0      	11m
crate-2   1/1   	Running   0      	10m
crate-3   1/1   	Running   0      	2m
crate-4   1/1   	Running   0      	2m

Auch im Admin-Browserfenster sind nun alle fünf Nodes zu sehen:

Scale-In: einen Knoten aus dem Cluster nehmen

Bei CrateDB gibt es keinen Unterschied, ob ein Knoten aus dem Cluster genommen werden soll oder ob er unerwartet ausfällt. In beiden Fällen wird ein Knoten aus dem Cluster entfernt, und CrateDB erledigt den Rest automatisch. Um dies zu testen, empfiehlt es sich, zunächst Testdaten in das System zu laden. Nun können die Replicas und die Expectes_Nodes in der Controller-Konfiguration auf 4 gesetzt werden, alles andere bleibt wie es ist. Das Update der Controller-Konfiguration erfolgt so:

$ kubectl replace -f crate-controller.yaml --namespace crate
 
statefulset.apps/crate replaced

Kubernetes führt die Änderungen nun Pod für Pod aus. Während sich der Cluster mitten im Roll-out, also in einem inkonsistenten Status, befindet, werden einige Checks scheitern. Standardmäßig sind Replikations-Routinen konfiguriert, so dass CrateDB sich selbst helfen kann, wenn Shards (horizontale Partitionen) neu erstellt werden müssen. Während der Prozess andauert, zeigt das Admin UI einige Warnungen. Ist der Prozess abgeschlossen, sollte alles wieder im Lot und der Scale-In-Vorgang erfolgreich gewesen sein.

CrateDB, Docker und Kubernetes arbeiten gut zusammen und ermöglichen es, einen Cluster schnell aufzusetzen, der flexibel skalierbar bleibt. Mit Testdaten lassen sich so erste Erfahrungen sammeln, um schrittweise in die Technologien hineinzuwachsen.

Geschrieben von
Mika Naylor

Mika Naylor ist Entwicklerin und SysAdmin bei Crate.io.

Kommentare

Hinterlasse einen Kommentar

avatar
4000
  Subscribe  
Benachrichtige mich zu: