Veža alebo nie veža - to je otázka

Veža alebo nie veža - to je otázka

Začiatkom tohto mesiaca, 3. mája, bolo oznámené veľké vydanie „systému správy pre distribuované ukladanie údajov v Kubernetes“ - Veža 1.0.0. Už pred viac ako rokom publikovaný všeobecný prehľad Rook. Potom sme boli požiadaní, aby sme hovorili o jeho skúsenostiach použitie v praxi — a teraz, práve v čase takéhoto významného míľnika v histórii projektu, sa radi podelíme o naše nahromadené dojmy.

Rook je skrátka súprava operátorov pre Kubernetes, ktoré preberajú plnú kontrolu nad nasadením, správou, automatickou obnovou riešení na ukladanie dát, ako sú Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

V súčasnosti najrozvinutejšie (a jediný в stabilný etapa) riešením je veža-ceph-operátor.

Poznámka: Medzi významné zmeny vo vydaní Rook 1.0.0 týkajúce sa Ceph môžeme zaznamenať podporu pre Ceph Nautilus a možnosť používať NFS pre vedrá CephFS alebo RGW. Čo vyniká medzi ostatnými, je dozrievanie podpory EdgeFS na úroveň beta.

Takže v tomto článku:

  • Odpovedzme si na otázku, aké výhody vidíme v používaní Rooka na nasadenie Ceph v klastri Kubernetes;
  • Podelíme sa o naše skúsenosti a dojmy z používania Rook vo výrobe;
  • Povedzme vám, prečo hovoríme „Áno!“ Rookovi a o našich plánoch s ním.

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

"Mám výhodu jedného veža!" (neznámy šachista)

Veža alebo nie veža - to je otázka

Jednou z hlavných výhod Rooku je, že interakcia s dátovými skladmi sa uskutočňuje prostredníctvom mechanizmov Kubernetes. To znamená, že už nemusíte kopírovať príkazy na konfiguráciu Ceph z listu do konzoly.

— Chcete nasadiť CephFS v klastri? Stačí napísať súbor YAML!
- Čo? Chcete tiež nasadiť objektový obchod s S3 API? Stačí napísať druhý súbor YAML!

Veža je vytvorená podľa všetkých pravidiel typického operátora. K interakcii s ním dochádza pomocou CRD (vlastné definície zdrojov), v ktorej popisujeme charakteristiky entít Ceph, ktoré potrebujeme (keďže ide o jedinú stabilnú implementáciu, tento článok bude štandardne hovoriť o Ceph, pokiaľ nie je výslovne uvedené inak). Podľa zadaných parametrov operátor automaticky vykoná príkazy potrebné na konfiguráciu.

Pozrime sa na špecifiká pomocou príkladu vytvorenia Object Store, alebo skôr - 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ú celkom štandardné a takmer nepotrebujú komentár, ale stojí za to venovať osobitnú pozornosť tým, ktoré sú priradené premenným šablóny.

Všeobecná schéma práce spočíva v tom, že zdroje „objednáme“ prostredníctvom súboru YAML, pre ktorý operátor vykoná potrebné príkazy a vráti nám „nie tak skutočné“ tajomstvo, s ktorým môžeme ďalej pracovať. (Pozri nižšie). A z vyššie uvedených premenných sa zostaví príkaz a tajný názov.

Čo je to za tím? Pri vytváraní používateľa na ukladanie objektov operátor Veža vo vnútri modulu urobí nasledovné:

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

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

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

Keys - aké budúce aplikácie budú potrebovať na prístup k ukladaniu objektov cez S3 API. Operátor veže ich láskavo vyberie a vloží do svojho menného priestoru vo forme tajničky s menom rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Ak chcete použiť údaje z tohto tajomstva, jednoducho ich pridajte do kontajnera ako premenné prostredia. Ako príklad uvediem šablónu pre Job, v ktorej automaticky vytvárame buckety 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 tejto úlohe boli vykonané v rámci Kubernetes. Štruktúry opísané v súboroch YAML sú uložené v úložisku Git a mnohokrát opakovane použité. Vnímame to ako obrovské plus pre inžinierov DevOps a proces CI/CD ako celok.

Šťastný s Rookom a Radošom

Použitie kombinácie Ceph + RBD ukladá určité obmedzenia týkajúce sa montáže objemov do strukov.

Najmä menný priestor musí obsahovať tajomstvo pre prístup k Ceph, aby mohli stavové aplikácie fungovať. Je to v poriadku, ak máte 2-3 prostredia v ich menných priestoroch: môžete ísť a skopírovať tajomstvo ručne. Čo ak sa však pre každú funkciu vytvorí samostatné prostredie s vlastným menným priestorom pre vývojárov?

Tento problém sme vyriešili sami pomocou shell-operátor, ktorý automaticky skopíroval tajomstvá do nových menných priestorov (príklad takéhoto háku je opísaný v 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

Pri používaní Rook však tento problém jednoducho neexistuje. Proces montáže prebieha pomocou vlastných ovládačov na základe Flexvolume alebo CSI (stále v beta štádiu), a preto nevyžaduje tajomstvá.

Rook automaticky rieši veľa problémov, čo nás povzbudzuje k tomu, aby sme ho používali v nových projektoch.

Obliehanie veže

Dokončite praktickú časť nasadením Rooka a Cepha, aby sme mohli vykonávať vlastné experimenty. Aby bolo ľahšie zaútočiť na túto nedobytnú vežu, vývojári pripravili balíček Helm. Poďme si to stiahnuť:

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

V súbore rook-ceph/values.yaml môžete nájsť veľa rôznych nastavení. Najdôležitejšie je špecifikovať tolerancie pre agentov a vyhľadávanie. Podrobne sme popísali, na čo sa dá použiť mechanizmus kazov/tolerancií v tomto článku.

Stručne povedané, nechceme, aby boli moduly klientskych aplikácií umiestnené na rovnakých uzloch ako disky na ukladanie údajov. Dôvod je jednoduchý: týmto spôsobom práca agentov Rook neovplyvní samotnú aplikáciu.

Takže otvorte súbor rook-ceph/values.yaml pomocou svojho obľúbeného editora a na koniec pridajte nasledujúci blok:

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

Pre každý uzol vyhradený na ukladanie údajov pridajte zodpovedajúcu škvrnu:

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

Potom nainštalujte tabuľku Helm pomocou príkazu:

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

Teraz musíte vytvoriť klaster a určiť umiestnenie 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"

Kontrola stavu Ceph – očakávajte, že uvidíte 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

Zároveň skontrolujme, či pody s klientskou aplikáciou neskončia na uzloch rezervovaných pre Ceph:

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

Ďalej je možné podľa potreby konfigurovať ďalšie komponenty. Ďalšie podrobnosti o nich sú uvedené v dokumentáciu. Pre správu dôrazne odporúčame nainštalovať dashboard a toolbox.

Veža a háky: stačí veža na všetko?

Ako môžete vidieť, vývoj Rooka je v plnom prúde. Stále však existujú problémy, ktoré nám neumožňujú úplne opustiť manuálnu konfiguráciu Ceph:

  • Žiadny vodič Rook nemôže exportné metriky o použití namontovaných blokov, čo nás pripravuje o monitorovanie.
  • Flexvolume a CSI neviem ako zmeniť veľkosť zväzkov (na rozdiel od rovnakého RBD), takže Rook príde o užitočný (a niekedy kriticky potrebný!) nástroj.
  • Rook stále nie je taký flexibilný ako bežný Ceph. Ak chceme nakonfigurovať fond pre ukladanie metadát CephFS na SSD a samotných údajov na HDD, budeme musieť manuálne zaregistrovať samostatné skupiny zariadení v mapách CRUSH.
  • Napriek tomu, že rook-ceph-operator je považovaný za stabilný, pri aktualizácii Ceph z verzie 13 na 14 sa v súčasnosti vyskytujú určité problémy.

Závery

"Práve teraz je Rook uzavretá pred vonkajším svetom pešiakmi, ale veríme, že jedného dňa bude hrať rozhodujúcu úlohu v hre!" (citát vymyslený špeciálne pre tento článok)

Projekt Rook si nepochybne získal naše srdcia – veríme, že [so všetkými jeho kladmi a zápormi] si určite zaslúži vašu pozornosť.

Naše budúce plány sa scvrkli na to, aby sme urobili z rook-ceph modul operátor doplnku, vďaka čomu bude jeho používanie v našich početných klastroch Kubernetes ešte jednoduchšie a pohodlnejšie.

PS

Prečítajte si aj na našom blogu:

Zdroj: hab.com

Pridať komentár