Rook alebo nerook — to je otázka

Rook alebo nerook — to je otázka

Na začiatku tohto mesiaca, 3. mája, bol oznámený významný release „systému správy pre distribuované úložiská dát v Kubernetes“ — Rook 1.0.0. Viac ako pred rokom sme už publikovali obecný prehľad o Rook. Vtedy nás žiadali, aby sme sa podelili o skúsenosti s jeho používaním v praxi — a práve k takémuto významnému míľniku v histórii projektu sme radi, že sa môžeme podeliť o nahromadené dojmy.

Stručne povedané, Rook predstavuje súbor operátorov pre Kubernetes, ktoré plne preberajú kontrolu nad nasadením, správou a automatickým obnovovaním takých riešení na ukladanie dát, ako sú Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

V súčasnosti je najrozvinutejším (a jediným v stabilným riešením rook-ceph-operator.

Poznámka: medzi významné zmeny v release Rook 1.0.0 týkajúce sa Ceph patrí podpora Ceph Nautilus a možnosť používať NFS pre CephFS alebo RGW-bunky. Z ďalších aspektov sa zvýrazňuje „dozrievanie“ podpory EdgeFS na úroveň beta.

Teda, v tomto článku

  • odpovieme na otázku, aké výhody vidíme v používaní Rook na nasadenie Ceph v klastri Kubernetes;
  • podelíme sa o skúsenosti a dojmy z používania Rook v produkcii;
  • povieme, prečo hovoríme Rooku „Áno!“, a o našich plánoch s ním.

Začnime s všeobecnými konceptmi a teóriou.

„Mám výhodu jedného figúrka!“ (neznámy šachista)

Rook alebo nerook — to je otázka

Jedným z hlavných výhod Rook je, že interakcia s úložiskami dát prebieha prostredníctvom mechanizmov Kubernetes. To znamená, že už nemusíte kopírovať príkazy na nastavenie Ceph zo zoznamu do konzoly.

— Chceš nasadiť CephFS v klastri? Stačí napísať YAML súbor!
­— Čo? Chceš nasadiť aj objektové úložisko s S3 API? Stačí napísať druhý YAML súbor!

Rook bol vytvorený podľa všetkých pravidiel typického operátora. Interakcia s ním prebieha pomocou CRD (Custom Resource Definitions), v ktorých opisujeme požadované vlastnosti entít Ceph (keďže ide o jediné stabilné implementáciu, v článku budeme hovoriť práve o Ceph, pokiaľ nie je výslovne uvedené inak). Podľa zadaných parametrov operátor automaticky vykoná potrebné príkazy na nastavenie.

Konkrétnosť si priblížime na príklade vytvorenia objektového úložiska, a to presnejšie — CephObjectStoreUser.

apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: {{ .Values.s3.crdName }}
  namespace: kube-rook
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPool:
    failureDomain: host
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  gateway:
    type: s3
    sslCertificateRef:
    port: 80
    securePort:
    instances: 1
    allNodes: false
---
apiVersion: ceph.rook.io/v1
kind: CephObjectStoreUser
metadata:
  name: {{ .Values.s3.crdName }}
  namespace: kube-rook
spec:
  store: {{ .Values.s3.crdName }}
  displayName: {{ .Values.s3.username }}

Parametre uvedené v zozname sú dosť štandardné a pravdepodobne si nevyžadujú komentáre, avšak stojí za to osobitne venovať pozornosť tým, ktoré sú zdôraznené v premenných šablón.

Všeobecná schéma fungovania spočíva v tom, že prostredníctvom YAML súboru "objednávame" zdroje, pre ktoré operátor vykonáva potrebné príkazy a vracia nám "nielen pravý" tajný kľúč, s ktorým môžeme ďalej pracovať. (pozri nižšie). A z premenných, ktoré sú uvedené vyššie, bude zostavený príkaz a názov tajného kľúča.

Aký je teda ten príkaz? Pri vytváraní používateľa pre objektové úložisko Rook operátor vo vnútri podu vykoná nasledujúce:

radosgw-admin user create --uid="rook-user" --display-name="{{ .Values.s3.username }}"

Výsledkom vykonania tohto príkazu bude JSON štruktúra:

{
    "user_id": "rook-user",
    "display_name": "{{ .Values.s3.username }}",
    "keys": [
        {
           "user": "rook-user",
           "access_key": "NRWGT19TWMYOB1YDBV1Y",
           "secret_key": "gr1VEGIV7rxcP3xvXDFCo4UDwwl2YoNrmtRlIAty"
        }
    ],
    ...
}

Kľúče — to, čo bude potrebné v budúcnosti aplikáciám na prístup k objektovému úložisku prostredníctvom S3 API. Rook operátor ich láskavo vyberá a ukladá vo svojej namespaces vo forme tajného kľúča s názvom rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Aby ste mohli použiť údaje z tohto tajného kľúča, stačí pridať ich do kontajnera ako premenné prostredia. Ako príklad uvediem šablónu pre Job, v ktorej automaticky vytvárame bucket-y pre každé používateľské prostredie:

{{- range $bucket := $.Values.s3.bucketNames }}
apiVersion: batch/v1
kind: Job
metadata:
  name: create-{{ $bucket }}-bucket-job
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "2"
spec:
  template:
    metadata:
      name: create-{{ $bucket }}-bucket-job
    spec:
      restartPolicy: Never
      initContainers:
      - name: waitdns
        image: alpine:3.6
        command: ["/bin/sh", "-c", "while ! getent ahostsv4 rook-ceph-rgw-{{ $.Values.s3.crdName }}; do sleep 1; done" ]
      - name: config
        image: rook/ceph:v1.0.0
        command: ["/bin/sh", "-c"]
        args: ["s3cmd --configure --access_key=$(ACCESS-KEY) --secret_key=$(SECRET-KEY) -s --no-ssl --dump-config | tee /config/.s3cfg"]
        volumeMounts:
        - name: config
          mountPath: /config
        env:
        - name: ACCESS-KEY
          valueFrom:
            secretKeyRef:
              name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}
              key: AccessKey
        - name: SECRET-KEY
          valueFrom:
            secretKeyRef:
              name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}
              key: SecretKey
      containers:
      - name: create-bucket
        image: rook/ceph:v1.0.0
        command: 
        - "s3cmd"
        - "mb"
        - "--host=rook-ceph-rgw-{{ $.Values.s3.crdName }}"
        - "--host-bucket= "
        - "s3://{{ $bucket }}"
        ports:
        - name: s3-no-sll
          containerPort: 80
        volumeMounts:
        - name: config
          mountPath: /root
      volumes:
      - name: config
        emptyDir: {}
---
{{- end }}

Všetky akcie uvedené v tomto Job-e boli vykonané bez opustenia Kubernetes. Štruktúry popísané v YAML súboroch sú uložené v Git repozitári a opakovane používané. Vnímame v tom veľkú výhodu pre DevOps inžinierov a proces CI/CD ako celok.

S Rookom a Radosom je radosť.

Použitie kombinácie Ceph + RBD kladie určité obmedzenia na pripojenie objemov k podom.

Konkrétne, v namespace musí byť prítomný tajný kľúč na prístup k Ceph, aby mohli stateful aplikácie fungovať. Je normálne, ak máte 2-3 prostredia vo svojich menných priestoroch: môžte ísť a manuálne skopírovať tajný kľúč. Ale čo robiť, ak pre každú funkciu vývojárov vytvárate samostatné prostredie so svojím menným priestorom?

U nás sme tento problém vyriešili pomocou shell-operator, ktorý automaticky kopíroval tajné kľúče do nových menných priestorov (príklad takého hooku je popísaný v tomto článku).

#! /bin/bash

if [[ $1 == “--config” ]]; then
   cat <<EOF
{"onKubernetesEvent":[
 {"name": "OnNewNamespace",
  "kind": "namespace",
  "event": ["add"]
  }
]}
EOF
else
    NAMESPACE=$(kubectl get namespace -o json | jq '.items | max_by( .metadata.creationTimestamp ) | .metadata.name')
    kubectl -n ${CEPH_SECRET_NAMESPACE} get secret ${CEPH_SECRET_NAME} -o json | jq ".metadata.namespace="${NAMESPACE}"" | kubectl apply -f -
fi

Avšak pri použití Rooku tento problém jednoducho neexistuje. Proces pripojenia prebieha pomocou vlastných ovládačov na báze Flexvolume alebo CSI (momentálne v beta verzii) a preto nevyžaduje tajné kľúče.

Rook automaticky rieši mnohé problémy, čo nás podnecuje používať ho v nových projektoch.

Obranná línia Rook

Dokončíme praktickou část nasazením Rook a Ceph pro možnost provádění vlastních experimentů. Abychom se k této nedobytné věži dostali lépe, vývojáři připravili Helm balíček. Pojďme si ho stáhnout:

$ helm fetch rook-master/rook-ceph --untar --version 1.0.0

V súbore rook-ceph/values.yaml nalezneme množství různých nastavení. Nejpodstatnější je uvést tolerace pro agenty a vyhledávání. O mechanismu taints/tolerations jsme podrobně hovořili v tomto článku.

Stručně řečeno, nechceme, aby se pod' s klientskou aplikací nacházely na stejných uzlech, kde jsou disky pro ukládání dat. Důvod je prostý: tak nebude práce agentů Rook ovlivňovat samotnou aplikaci.

Takže otevřeme soubor rook-ceph/values.yaml v oblíbeném editoru a na konec přidáme následující blok:

discover:
  toleration: NoExecute
  tolerationKey: node-role/storage
agent:
  toleration: NoExecute
  tolerationKey: node-role/storage
  mountSecurityMode: Any

Na každý uzel, který je vyhrazen pro ukládání dat, přidáme příslušný taint:

$ kubectl taint node ${NODE_NAME} node-role/storage="":NoExecute

Po čemž nainstalujeme Helm chart pomocí příkazu:

$ helm install --namespace ${ROOK_NAMESPACE} ./rook-ceph

Nyní je třeba vytvořit cluster a určit umístění OSD:

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  clusterName: "ceph"
  finalizers:
  - cephcluster.ceph.rook.io
  generation: 1
  name: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v13
  dashboard:
    enabled: true
  dataDirHostPath: /var/lib/rook/osd
  mon:
    allowMultiplePerNode: false
    count: 3
  network:
    hostNetwork: true
  rbdMirroring:
    workers: 1
  placement:
    all:
      tolerations:
      - key: node-role/storage
        operator: Exists
  storage:
    useAllNodes: false
    useAllDevices: false
    config:
      osdsPerDevice: "1"
      storeType: filestore
    resources:
      limits:
        memory: "1024Mi"
      requests:
        memory: "1024Mi"
    nodes:
    - name: host-1
      directories:
      - path: "/mnt/osd"
    - name: host-2
      directories:
      - path: "/mnt/osd"
    - name: host-3
      directories:
      - path: "/mnt/osd"

Kontrolujeme stav Ceph – očekáváme, že uvidíme HEALTH_OK:

$ kubectl -n ${ROOK_NAMESPACE} exec $(kubectl -n ${ROOK_NAMESPACE} get pod -l app=rook-ceph-operator -o name -o jsonpath='{.items[0].metadata.name}') -- ceph -s

Také zkontrolujeme, že pod' s klientskou aplikací nepadají na uzly vyhrazené pro Ceph:

$ kubectl -n ${APPLICATION_NAMESPACE} get pods -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName

Dále si podle potřeby nastavíme další komponenty. Podrobnosti o nich jsou uvedeny v dokumenácie. Pro administraci důrazně doporučujeme nainstalovat dashboard a toolbox.

Rookovy háčky: Je na vše dost Rook?

Ako môžete vidieť, vývoj Rook pokračuje naplno. No stále pretrvávajú problémy, ktoré nám nedovoľujú úplne sa vzdať manuálneho nastavenia Ceph:

  • Žiadny ovládač Rook nevie exportovať metriky využívania pripojených blokov, čo nás oberá o monitorovanie.
  • Flexvolume a CSI nevedia meniť veľkosť objemov (na rozdiel od RBD), takže Rook prichádza o užitočný (a niekedy aj kriticky potrebný!) nástroj.
  • Rook stále nie je tak flexibilný ako bežný Ceph. Ak by sme chceli nastaviť, aby sa pool pre metadáta CephFS ukladali na SSD, a samotné dáta — na HDD, musíme ručne zapisovať samostatné skupiny zariadení do CRUSH máp.
  • Napriek tomu, že rook-ceph-operator sa považuje za stabilný, momentálne existujú isté problémy pri aktualizácii Ceph z verzie 13 na 14.

Zhrnutie

„Momentálne je Rook uzavretý pred vonkajším svetom pešiakmi, ale veríme, že raz zohrá rozhodujúcu úlohu v partii!“ (citát vymyslený špeciálne pre tento článok)

Projekt Rook určite získal naše srdcia — považujeme ho za [so všetkými jeho plusmi a mínusmi] a určite si zaslúži vašu pozornosť.

Naše ďalšie plány sa týkajú toho, aby sme urobili rook-ceph modulom pre addon-operator, čo jeho použitie v našich početných Kubernetes klastroch ešte viac uľahčí a spríjemní.

P.S.

Prečítajte si tiež na našom blogu:

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster