Ceph-Ansible für eine schnelle und fehlerfreie Installation von Ceph Storage Clusters

Ceph-Ansible – Use Cases And Technical Guide To Deploying Ceph In Kubernetes

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.2for external traffic
10.0.1.4for 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:

BrunchVersion
stable-3.0support for Ceph versions of jewel and luminous. Ansible version 2.4 is required
stable-3.1support for Ceph versions of luminous and mimic. Ansible version 2.4 is required
stable-3.2support for Ceph versions of luminous and mimic. Ansible version 2.6 is required
stable-4.0support 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!

Ausgewählte Blogbeiträge