Klauke Enterprises Blog

Level Up: Rancher und Kubernetes mit CEPH Storage via RBD

Geschrieben von Felix Klauke | 01.07.2020

Persistenter Storage ist eine Herausforderung, ohne Frage. Besonders wenn du auf mehrere Server skalierst, verlangt diese Herausforderung dringlich nach Lösungen, die ich dir sehr gerne liefere. CEPH hat sich als zuverlässiges Storage System herausgestellt, das du ganz einfach an dein Kubernetes Cluster anbinden kannst, um dynamisch Storage zu provisionieren. 

 

Persistenter Storage

Du unterscheidest in der Regel zwischen persistentem und flüchtigem Speicher. Der flüchtige Speicher wird nach der Verwendung verworfen und ist nicht weiter relevant. Der persistente Speicher enthält in der Regel die Nutzdaten, die du auch behalten möchtest. Das können zum Beispiel Datenbanken mit Benutzeraccounts oder Messdaten sein. Wenn du dein Programm beim nächsten Mal startest, sollen sie unbedingt wieder da sein und müssen daher persistent (lat. persistere = fortdauern) gespeichert werden. 

Persistenter Speicher bedarf jedoch genaueren Managements. Die Daten dürfen nicht einfach auf einen "Nicht-Vergessen"-Haufen geworfen werden, sondern sollen fein säuberlich getrennt abgelegt werden. Doch wie stellst du den Speicher dafür bereit?

 

Ceph

Speicher auf einem Server bereitzustellen ist kein Kunststück: Du schiebst einfach eine Festplatte rein, fertig! Um Storage auch auf verschiedenen Servern und über die Grenzen von einzelnen Maschinen hinweg anbieten zu können braucht es aber ein verteiltes Storage-System. Alle Server sollen schnell und zuverlässig auf alle Daten zugreifen können, damit Daten niemals an einen Server gebunden sind. Dieser kann nämlich ausfallen, der Speicher und die Anwendung sollen aber weiterlaufen.

An dieser Stelle kommt CEPH ins Spiel, welches sich selbst als hochperformantes, verlässliches und skalierbares Storage-System beschreibt. In Lösungen wie Proxmox ist es ratz fatz eingerichtet und liefert beeindruckende Ergebnisse, die es absolut als Storage-System für dein Cluster qualifizieren. 

 

Kubernetes & Rancher

Kubernetes Cluster zu managen ist absolut nicht trivial und es gibt auf dem Markt nur eine handvoll von Tools, die dir deine Arbeit auch wirklich erleichtern. Ein sehr etabliertes und von mir hoch geschätztes Tool dafür ist Rancher. Das einfache Setup und die übersichtliche Administration, Provisionierung und Wartung von Kubernetes Clusters macht damit tatsächlich Spaß.

Du brauchst Hilfe bei der Einrichtung oder Administration deines Clusters? Dann halte an dieser Stelle inne und vereinbare einen Termin, damit wir die folgenden Schritte zusammen durchgehen können:

 

 

Kubernetes CEPH storage class

Damit du Speicher dynamisch zur Verfügung stellen kannst arbeitet Kubernetes mit Storage Classes. Du brauchst also eine einfache storage class, die auf dein CEPH Cluster zugreift. Du brauchst dafür:

  • Ein laufendes CEPH Cluster mit ausreichend Speicher 
  • Zugangsdaten für dein CEPH Cluster
  • Die IPs deiner CEPH Monitors (Ich verwende hier exemplarisch 10.0.10.1, 10.0.10.2 und 10.0.10.3)
  • Einen CEPH pool, den du als Speicher benutzen möchtest (Ich habe meinen kube genannt)
  • Einen fetzigen Namen für deine Storage Class, ich nenne meine hier ceph-fra-01 (Weil es sich um das CEPH Cluster #1 in Frankfurt handelt)
 
Zugangsdaten über Kubernetes Secrets

Die Zugangsdaten für CEPH legen wir auf einem der CEPH Monitors an (Vorausgesetzt, dass der Pool kube heißt):

ceph auth get-or-create client.kube mon 'allow r' osd 'allow rw pool=kube'

 

Die Zugangsdaten müssen danach ausgelesen werden:

ceph auth get-key client.admin | base64
ceph auth get-key client.kube | base64

 

Nun kümmern wir uns um entsprechende Zugangsdaten in Kubernetes, die wir in Form von Secrets anlegen:

 

apiVersion: v1
kind: Secret
metadata:
  name: ceph-admin-secret
  namespace: kube-system
type: "kubernetes.io/rbd"
data:
  key: --Dein Admin Key--

---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
  namespace: kube-system
type: "kubernetes.io/rbd"
data:
  key: --Dein user key--

Die Storage class anlegen

Daraufhin kannst du ein entsprechendes Storage Class Objekt anlegen:

 

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-fra-01
  annotations:
     storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.0.100.1:6789,10.0.100.2:6789,10.0.100.3:6789
  adminId: admin
  adminSecretName: ceph-admin-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret
  userSecretNamespace: kube-system

 

Hinweis: Beachte, dass die entsprechenden Keyrings von ceph (z.B. /etc/ceph/xxx.keyring) auf den K8s Nodes liegen müssen und das ceph-common Paket installiert sein muss, damit deine Nodes Zugriff auf CEPH bekommen. 

 

Das sollten wir einmal detailliert durchgehen. Durch eine Annotation haben wir die neue Storage Class zur Standard-Class gemacht. Dass heißt, dass alle Persistent Volume Claims bei uns anklopfen und nach Speicher fragen, wenn wir es ihnen nicht explizit anders befohlen haben sollten. Außerdem werden alle Monitors angegeben, um eine gewissen Ausfallsicherheit zu gewährleisten. Von hier aus werden nur noch der zu verwendende Pool und die entsprechenden Zugangsdaten angegeben.

Wenn du dich weniger mit den Kubernetes Ressourcen beschäftigen möchtest, so kannst du hier die Brücke zurück zu Rancher schlagen, das die Verwaltung von Storage Classes und Secrets über die Web UI ermöglicht:

  • Für die Secrets navigierst du zu deinem Cluster und dem System Projekt. Unter Ressources kannst du die Secrets anlegen. Achte hier jedoch darauf, dass das Secrets den kubernetes.io/rbd type braucht! (Ich empfehle in diesem Fall, die Secrets per kubectl anzulegen)
  • Für die Storage Classes navigierst du zu deinem Cluster und kannst dann unter Storage deine Classes verwalten. Doch Achtung: Damit du das mit CEPH arbeiten kannst musst du Global > Settings > Feature Flags die unsupported-storage-drivers einschalten.
 
Test-Volume Claim

Um die Storage Class zu testen, provisionieren wir zum Testen einfach ein Volume:

 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  storageClassName: ceph-fra-01
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

 

Sollte ein Volume gebunden werden, haben wir von nun an einen dynamisch provisionierten CEPH Storage in unserem Kubernetes 🎉

 

Fazit

Das Setup ist nicht immer einfach und birgt einige Fallen, in vielen Fällen wird es Probleme geben, aber das Endergebnis ist es auf jeden Fall wert. Einfacher, skalierbarer, hyperkonvergenter Speicher ist nun einmal nicht umsonst. Wenn du Probleme mit dem Setup hast, darfst du mich gerne kontaktieren und wir setzen zusammen deinen CEPH Storage auf: