In diesem Beitrag unserer DevOps-Beratungsserie folgen wir unserer früheren vergleichenden Analyse von CEPH oder NFS als alternative Kubernetes-Datenspeicherlösungen mit einer Anleitung zu Ceph-Ansible. Wir werden untersuchen, wie Ceph-Ansible für eine schnelle, fehlerfreie Bereitstellung von Ceph-Storage-Clustern innerhalb einer DevOps-Architektur verwendet werden kann. Wir gehen auch auf spezielle Anwendungsfälle, die Stärken und Nachteile dieser Tools im Vergleich zu Alternativen ein und schließen mit einer detaillierten Schritt-für-Schritt-Anleitung zur Installation von Ceph-Clustern mit Ceph-Ansible für eine Kubernetes-Umgebung.
Was ist Ceph-Datenspeicherung (Data Storage) und wie und wann wird sie eingesetzt?
Das exponentielle Wachstum des Datenspeicherbedarfs moderner Unternehmen hat zu einem Bedarf an effektiven Big-Data-Speicherlösungen geführt. Das Speicher-Tool Ceph hat sich dieser Herausforderung gestellt.
Ceph ist ein von Red Hat initiiertes Open-Source-Softwareprojekt. Es wird verwendet, um skalierbare objekt-, block- und dateibasierte Speicherung unter einem einzigen System zu ermöglichen. Ceph-Storage-Cluster werden mit dem CRUSH-Algorithmus (Controlled Replication Under Scalable Hashing) gepaart, um Commodity-Hardware zu betreiben. CRUSH verwaltet die optimale Verteilung von Daten über einen Ceph-Cluster und ermöglicht gleichzeitig den freien Abruf von Daten.
Ceph-Storage-Cluster enthalten eine große Menge an Daten. Durch die Verwendung von Subclustern unterhalb eines Clusters werden diese Daten in überschaubare und relevante Teile aufgeteilt. Damit die Daten gemäß der entsprechenden Abstammung organisiert werden können, müssen die Subcluster als Teil eines „übergeordneten“ Clusters ordnungsgemäß konfiguriert werden. CRUSH ist ein skalierbarer Hashing-Algorithmus, der einen großen Datensatz in die entsprechenden Cluster und Subcluster aufteilt und so eine optimierte Suche ermöglicht. Die Rolle von Ceph bei der Big-Data-Speicherung ist also eine, die sowohl die Speicheroptimierung als auch den einfachen Datenzugriff und -abruf kombiniert.
Ein Fall von Ceph-Ansible – hybride Cloud-Infrastruktur mit Kubernetes
Moderne hybride Softwarearchitekturen, die Bare-Metal- mit Cloud-Lösungen (z. B. AWS, Google Cloud) kombinieren und ein Containerisierungstool wie Docker und Orchestratoren wie Docker Swarm, Kubernetes und Rancher verwenden, stoßen häufig auf ein Problem:
Wie und wo können Datenanwendungen so gespeichert werden, dass sie von überall in der Infrastruktur zugänglich sind, unabhängig vom Standort des Docker-Containers mit der Anwendung?
Ceph hilft, dieses Problem durch ein verteiltes Speichersystem mit hoher Verfügbarkeit und Skalierbarkeit zu lösen. In Kubernetes-basierten Architekturen verfügt Ceph zum Beispiel über einen Provisioner für K8s PersistentVolume- CephFS und K8s PersistentVolumeClaims – RBD (Ceph Block Device). Ceph wird auch häufig in Big-Data-Verarbeitungs- und -Speicherlösungen eingesetzt, da es sich durch eine besonders hohe horizontale Skalierbarkeit auszeichnet.
Ceph-Ansible, eine Automatisierungs-Engine für die Bereitstellung und das Konfigurationsmanagement, stammt ebenfalls von Red Hat. Es gilt weithin als die flexibelste Methode zur Installation und Verwaltung eines großen Ceph-Storage-Clusters. Einige Ingenieure scheuen vor Ceph-Ansible zurück, da es nicht unbedingt die einfachste Lösung für die Installation und Verwaltung von Ceph-Speicher ist. Aber mit dem richtigen Know-how ist es auch nicht übermäßig schwierig. Und die daraus resultierenden produktionsreifen Cluster bedeuten, dass sich der zusätzliche Aufwand oft mehr als lohnt.
Schwachstellen von Ceph-Storage
Der Nachteil von Architekturlösungen auf Basis von Ceph ist, dass sie zu relativ hohen Redundanzraten für Server und/oder virtuelle Maschinen führen. Es handelt sich also um eine effektive, aber nicht billige Speicherlösung für Big Data und Kubernetes.
Ceph-Storage-Cluster sollten auch nicht für kritische Daten verwendet werden, da sie kein hohes Maß an Sicherheit bieten.
Bereitstellen von Ceph in Kubernetes mit Ceph-Ansible
Sehen wir uns an, wie man Ceph mit Ceph-Ansible für die zukünftige Verwendung in Kubernetes als block devices (PersistentVolumeClaims – RBD) bereitstellt.
Für unseren Prüfstand werden wir verwenden:
1x virtual server with ansible | |
192.168.1.2 | for external traffic |
10.0.1.4 | for internal traffic |
3x servers for ceph + on each server 3 free HDDs for OSD | |
192.168.2.1 192.168.2.2 192.168.2.3 | for external traffic |
10.0.1.1 10.0.1.2 10.0.1.3 | for internal traffic |
Grafana und Ceph Dashboard zur Visualisierung des Ceph Storage Clusters werden ebenfalls auf einem der Server installiert.
Für unsere 4 Server ist das interne Netzwerk 10.0.1.0/24 konfiguriert, das wir für den internen Ceph-Verkehr nutzen werden
Schritt-für-Schritt-Anleitung zur Vorbereitung eines Servers mit Ansible
Es ist notwendig, ssh-Keys zu generieren und sie auf allen Servern zu verteilen.
Laden Sie das Repository herunter:
git clone https://github.com/ceph/ceph-ansible
Wechseln Sie nun zu der Version, die wir gemäß der folgenden Struktur benötigen. Es ist auch erwähnenswert, dass es für verschiedene Versionen verschiedene Anforderungen an die Ansible-Version gibt.
Die Stable- * Brunches wurden von QE geprüft und erhalten während ihres Lebenszyklus nur selten Korrekturen:
Brunch | Version |
stable-3.0 | support for Ceph versions of jewel and luminous. Ansible version 2.4 is required |
stable-3.1 | support for Ceph versions of luminous and mimic. Ansible version 2.4 is required |
stable-3.2 | support for Ceph versions of luminous and mimic. Ansible version 2.6 is required |
stable-4.0 | support for Ceph version of nautilus. Ansible version 2.8 is required |
In diesem Beispiel wird die Nautilus-Version verwendet
git checkout stable-4.0
Installieren Sie alle erforderlichen dependencies
pip install -r requirements.txt
Beispiel config files umbenennen:
cp site.yml.sample site.yml cp group_vars/all.yml.sample group_vars/all.yml cp group_vars/mons.yml.sample group_vars/mons.yml cp group_vars/osds.yml.sample group_vars/osds.yml
Erstellen eines inventory file mit einer Beschreibung aller unserer Server
[mons] 192.168.2.1 192.168.2.2 192.168.2.3 [osds] 192.168.2.1 192.168.2.2 192.168.2.3 [mgrs] 192.168.2.1 [grafana-server] 192.168.2.1
Wir bringen das main file site.yml in die folgende Form:
--- # Defines deployment design and assigns role to server groups - hosts: - mons - osds gather_facts: false any_errors_fatal: true become: true tags: always vars: delegate_facts_host: True pre_tasks: # If we can't get python2 installed before any module is used we will fail # so just try what we can to get it installed - import_tasks: raw_install_python.yml - name: gather facts setup: when: not delegate_facts_host | bool - name: gather and delegate facts setup: delegate_to: "{{ item }}" delegate_facts: True with_items: "{{ groups['all'] }}" run_once: true when: delegate_facts_host | bool - name: install required packages for fedora > 23 raw: sudo dnf -y install python2-dnf libselinux-python ntp register: result when: - ansible_distribution == 'Fedora' - ansible_distribution_major_version|int >= 23 until: result is succeeded - name: check if it is atomic host stat: path: /run/ostree-booted register: stat_ostree tags: always - name: set_fact is_atomic set_fact: is_atomic: '{{ stat_ostree.stat.exists }}' tags: always tasks: - import_role: name: ceph-defaults - import_role: name: ceph-facts - import_role: name: ceph-validate - import_role: name: ceph-infra - hosts: mons gather_facts: false become: True any_errors_fatal: true pre_tasks: - name: set ceph monitor install 'In Progress' run_once: true set_stats: data: installer_phase_ceph_mon: status: "In Progress" start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" tasks: - import_role: name: ceph-defaults tags: ['ceph_update_config'] - import_role: name: ceph-facts tags: ['ceph_update_config'] - import_role: name: ceph-handler - import_role: name: ceph-common - import_role: name: ceph-config tags: ['ceph_update_config'] - import_role: name: ceph-mon - import_role: name: ceph-mgr when: groups.get(mgr_group_name, []) | length == 0 post_tasks: - name: set ceph monitor install 'Complete' run_once: true set_stats: data: installer_phase_ceph_mon: status: "Complete" end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" - hosts: mgrs gather_facts: false become: True any_errors_fatal: true pre_tasks: - name: set ceph manager install 'In Progress' run_once: true set_stats: data: installer_phase_ceph_mgr: status: "In Progress" start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" tasks: - import_role: name: ceph-defaults tags: ['ceph_update_config'] - import_role: name: ceph-facts tags: ['ceph_update_config'] - import_role: name: ceph-handler - import_role: name: ceph-common - import_role: name: ceph-config tags: ['ceph_update_config'] - import_role: name: ceph-mgr post_tasks: - name: set ceph manager install 'Complete' run_once: true set_stats: data: installer_phase_ceph_mgr: status: "Complete" end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" - hosts: osds gather_facts: false become: True any_errors_fatal: true pre_tasks: - name: set ceph osd install 'In Progress' run_once: true set_stats: data: installer_phase_ceph_osd: status: "In Progress" start: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" tasks: - import_role: name: ceph-defaults tags: ['ceph_update_config'] - import_role: name: ceph-facts tags: ['ceph_update_config'] - import_role: name: ceph-handler - import_role: name: ceph-common - import_role: name: ceph-config tags: ['ceph_update_config'] - import_role: name: ceph-osd post_tasks: - name: set ceph osd install 'Complete' run_once: true set_stats: data: installer_phase_ceph_osd: status: "Complete" end: "{{ lookup('pipe', 'date +%Y%m%d%H%M%SZ') }}" - hosts: mons gather_facts: false become: True any_errors_fatal: true tasks: - import_role: name: ceph-defaults - name: get ceph status from the first monitor command: ceph --cluster {{ cluster }} -s register: ceph_status changed_when: false delegate_to: "{{ groups[mon_group_name][0] }}" run_once: true - name: "show ceph status for cluster {{ cluster }}" debug: msg: "{{ ceph_status.stdout_lines }}" delegate_to: "{{ groups[mon_group_name][0] }}" run_once: true when: not ceph_status.failed - import_playbook: infrastructure-playbooks/dashboard.yml when: - dashboard_enabled | bool - groups.get(grafana_server_group_name, []) | length > 0 - ansible_os_family in ['RedHat', 'Suse']
Wir bearbeiten die Datei group_vars/all.yml, in der wir wichtige Parameter wie die Version des zukünftigen Clusters, das interne Subnetz, die Schnittstellen, die Loggröße und vieles mehr festlegen. Für unser Beispiel wird die Konfiguration der Variablen wie folgt aussehen:
ceph_origin: repository ceph_repository: community ceph_stable_release: nautilus monitor_interface: eth0 journal_size: 5120 #public_network: 0.0.0.0/0 - leave commented cluster_network: 10.0.1.0/24 #specify the network for internal traffic
Bearbeiten Sie nun die Datei mit den Variablen, die für die Konfiguration von OSD group_vars/osds.yml zuständig sind.
Sie können eine automatisierte Suche und Installation von OSD auf dem Server durchführen, indem Sie eine Variable angeben:
osd_auto_discovery: true
Wir geben jedoch ausdrücklich die Laufwerke unserer Server an:
devices: - /dev/sdb - /dev/sdc - /dev/sdd
Die Vorbereitungen sind abgeschlossen und Sie sind nun bereit, ansible-playbook auszuführen
ansible-playbook site.yml-i inventory_hosts
Die ungefähre deployment-Zeit beträgt 10 Minuten. Das Ergebnis der erfolgreichen Ausführung in der Konsole ist die folgende Ausgabe:
INSTALLER STATUS **************************************************************** Install Ceph Monitor : Complete (0:02:48) Install Ceph Manager : Complete (0:01:14) Install Ceph OSD : Complete (0:01:29) Install Ceph Dashboard : Complete (0:00:38) Install Ceph Grafana : Complete (0:01:08) Install Ceph Node Exporter : Complete (0:01:31) Thursday 22 August 2019 10:20:20 +0200 (0:00:00.064) 0:09:50.539 ********* ================================================================================= ceph-common : install redhat ceph packages ------------------------------- 79.72s ceph-container-engine : install container package ------------------------ 37.51s ceph-mgr : install ceph-mgr packages on RedHat or SUSE ------------------- 35.18s ceph-osd : use ceph-volume lvm batch to create bluestore osds ------------ 29.40s ceph-grafana : wait for grafana to start --------------------------------- 19.38s ceph-config : generate ceph configuration file: ceph.conf ---------------- 12.03s ceph-grafana : install ceph-grafana-dashboards package on RedHat or SUSE -- 9.11s ceph-common : install centos dependencies --------------------------------- 8.23s ceph-validate : validate provided configuration --------------------------- 7.23s ceph-mgr : wait for all mgr to be up -------------------------------------- 6.72s ceph-mon : fetch ceph initial keys ---------------------------------------- 5.33s ceph-dashboard : set or update dashboard admin username and password ------ 5.25s ceph-facts : set_fact fsid from ceph_current_status ----------------------- 4.30s check for python ---------------------------------------------------------- 4.02s ceph-mon : waiting for the monitor(s) to form the quorum... --------------- 3.94s ceph-facts : create a local fetch directory if it does not exist ---------- 3.75s ceph-facts : set_fact devices generate device list when osd_auto_discovery- 3.41s gather and delegate facts ------------------------------------------------- 3.37s ceph-osd : apply operating system tuning ---------------------------------- 2.91s ceph-container-engine : start container service --------------------------- 2.89s
Wir haben folgende Komponenten erfolgreich installiert:
Install CephMonitor Install CephManager Install CephOSD Install CephDashboard Install Ceph Grafana Install CephNode Exporter
Um auf das Dashboard zuzugreifen, verwenden Sie den Link:
Dashboard web UI
http://192.168.2.1:8443/
Default login und password – admin / admin
Wir haben die grundlegende Einrichtung eines verteilten Ceph-Speichersystems erfolgreich abgeschlossen. Wenn der Speichercluster später erweitert werden muss, fügen Sie einfach einen neuen Server zum Inventar hinzu und schon kann es losgehen!