Rook-nak vagy nem Bókának – ez a kérdés

Rook-nak vagy nem Bókának – ez a kérdés

E hónap elején, május 3-án jelentették be a „Kubernetes elosztott adattárolási menedzsment rendszerének” jelentős kiadását - 1.0.0-ös bástya. Több mint egy éve mi már közzétett Rook általános áttekintése. Aztán megkértek minket, hogy beszéljünk a tapasztalatairól gyakorlati felhasználása – és most, éppen időben a projekt történetének egy ilyen jelentős mérföldkövéhez, örömmel osztjuk meg felhalmozott benyomásainkat.

Röviden: Rook egy készlet szereplők a Kubernetes számára, amely teljes mértékben átveszi az olyan adattárolási megoldások telepítését, kezelését és automatikus helyreállítását, mint a Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Jelenleg a legfejlettebb (és az egyetlen в stabil szakasz) a megoldás az rook-ceph-operátor.

Megjegyzés: A Rook 1.0.0 Ceph-hez kapcsolódó jelentős változásai között megemlíthetjük a Ceph Nautilus támogatását és az NFS használatának lehetőségét a CephFS vagy RGW gyűjtőkön. Ami többek között kiemelkedik, az az EdgeFS támogatás béta szintre érése.

Tehát ebben a cikkben:

  • Válaszoljunk arra a kérdésre, hogy milyen előnyöket látunk a Rook használatával a Ceph Kubernetes-fürtben való telepítéséhez;
  • Megosztjuk tapasztalatainkat és benyomásainkat a Rook termelésben való használatáról;
  • Mondjuk el, miért mondunk „Igen!” Rook-nak, és a vele kapcsolatos terveinket.

Kezdjük az általános fogalmakkal és elméletekkel.

– Egy bástya előnyöm van! (ismeretlen sakkozó)

Rook-nak vagy nem Bókának – ez a kérdés

A Rook egyik fő előnye, hogy az adattárolókkal való interakciót Kubernetes mechanizmusokon keresztül hajtják végre. Ez azt jelenti, hogy többé nem kell átmásolnia a Ceph konfigurálásához szükséges parancsokat a lapról a konzolra.

— Szeretné telepíteni a CephFS-t egy fürtben? Csak írjon egy YAML fájlt!
- Mit? S3 API-val is szeretne objektumtárolót telepíteni? Csak írjon egy második YAML fájlt!

A bástya egy tipikus operátor összes szabálya szerint jön létre. A vele való interakció segítségével történik CRD (egyéni erőforrás-meghatározások), amelyben leírjuk a szükséges Ceph entitások jellemzőit (mivel ez az egyetlen stabil megvalósítás, alapértelmezés szerint ez a cikk a Ceph-ről fog beszélni, hacsak nincs kifejezetten másképp jelezve). A megadott paraméterek szerint a kezelő automatikusan végrehajtja a konfigurációhoz szükséges parancsokat.

Nézzük meg a részleteket egy objektumtár létrehozásának példáján keresztül, vagy inkább - 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 }}

A listában feltüntetett paraméterek meglehetősen szabványosak, és alig igényelnek megjegyzést, de érdemes különös figyelmet fordítani a sablonváltozókhoz rendelt paraméterekre.

Az általános munkaséma abból adódik, hogy egy YAML fájlon keresztül „rendeljük meg” az erőforrásokat, amihez az operátor végrehajtja a szükséges parancsokat, és visszaad egy „nem túl valós” titkot, amellyel tovább dolgozhatunk. (lásd lejjebb). A fent felsorolt ​​változókból pedig összeáll a parancs és a titkos név.

Milyen csapat ez? Amikor felhasználót hoz létre az objektumtároláshoz, a podban lévő Rook operátor a következőket fogja tenni:

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

A parancs végrehajtásának eredménye egy JSON-struktúra lesz:

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

Keys - milyen jövőbeni alkalmazásoknak kell majd hozzáférniük az objektumtárhoz az S3 API-n keresztül. A Bástya kezelője kedvesen kiválasztja őket, és a névvel ellátott titok formájában elhelyezi a névterében rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

A titkos adatok használatához csak adja hozzá azokat a tárolóhoz környezeti változóként. Példaként adok egy sablont a Jobhoz, amelyben minden felhasználói környezethez automatikusan létrehozunk vödröket:

{{- 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 }}

Az ebben a munkában felsorolt ​​összes művelet a Kubernetes keretein belül történt. A YAML-fájlokban leírt struktúrákat egy Git-tárolóban tárolják, és sokszor használják fel. Ezt óriási előnynek tartjuk a DevOps mérnökei és a CI/CD folyamat egésze számára.

Boldog Rookkal és Radossal

A Ceph + RBD kombináció használata bizonyos korlátozásokat támaszt a kötetek hüvelyekre történő felszerelésére vonatkozóan.

A névtérnek különösen tartalmaznia kell egy titkot a Ceph eléréséhez, hogy az állapottartó alkalmazások működjenek. Rendben van, ha 2-3 környezet van a névterükben: elmehetsz és manuálisan másolhatod a titkot. De mi van akkor, ha minden egyes funkcióhoz külön környezet jön létre saját névtérrel a fejlesztők számára?

Ezt a problémát saját magunk oldottuk meg shell-operátor, amely automatikusan átmásolta a titkokat új névterekbe (egy ilyen horog példáját a következő tartalmazza: ezt a cikket).

#! /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

A Rook használatakor azonban ez a probléma egyszerűen nem létezik. A szerelési folyamat saját illesztőprogramjai alapján történik Flexvolume vagy CSI (még béta stádiumban van), ezért nem igényel titkokat.

A Rook automatikusan megold sok problémát, ami arra ösztönöz bennünket, hogy új projektekben használjuk.

Rook ostroma

Végezzük el a gyakorlati részt Rook és Ceph telepítésével, hogy saját kísérleteinket végezhessük. A bevehetetlen torony lerohanásának megkönnyítése érdekében a fejlesztők Helm csomagot készítettek. Töltsük le:

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

Fájlban rook-ceph/values.yaml sokféle beállítást találhat. A legfontosabb az ügynökök és a keresés toleranciáinak meghatározása. Részletesen leírtuk, hogy a szennyeződések/tűrési mechanizmusok mire használhatók ezt a cikket.

Röviden: nem akarjuk, hogy az ügyfélalkalmazás-podák ugyanazokon a csomópontokon legyenek, mint az adattároló lemezek. Az ok egyszerű: így a Rook ügynökök munkája nem fogja magát az alkalmazást befolyásolni.

Tehát nyissa meg a fájlt rook-ceph/values.yaml kedvenc szerkesztőjével, és a végére adja hozzá a következő blokkot:

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

Minden adattárolásra fenntartott csomóponthoz adja hozzá a megfelelő szennyeződést:

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

Ezután telepítse a Helm diagramot a következő paranccsal:

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

Most létre kell hoznia egy klasztert, és meg kell adnia a helyet 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"

A Ceph állapotának ellenőrzése – várhatóan látni fogja 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

Ugyanakkor ellenőrizzük, hogy az ügyfélalkalmazást tartalmazó podok nem a Ceph számára fenntartott csomópontokra kerülnek:

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

Ezenkívül kívánság szerint további komponensek is konfigurálhatók. További részletek róluk az alábbi helyen találhatók dokumentáció. Az adminisztrációhoz erősen javasoljuk a műszerfal és az eszköztár telepítését.

Bástya és horgok: elég mindenre a bástya?

Mint látható, a Rook fejlesztése javában zajlik. De továbbra is vannak olyan problémák, amelyek nem teszik lehetővé számunkra, hogy teljesen elhagyjuk a Ceph kézi beállítását:

  • Nincs Rook Driver nem tud mérőszámok exportálása a szerelt blokkok használatára vonatkozóan, ami megfoszt bennünket a felügyelettől.
  • Flexvolume és CSI nem tudom hogy változtassa meg a kötetek méretét (ellentétben ugyanazzal az RBD-vel), így Rook megfoszt egy hasznos (és néha kritikusan szükséges!) eszköztől.
  • Rook még mindig nem olyan rugalmas, mint a szokásos Ceph. Ha be akarjuk állítani a készletet a CephFS metaadatok SSD-n való tárolására, magát az adatokat pedig a HDD-n tároljuk, akkor külön-külön eszközcsoportokat kell manuálisan regisztrálnunk a CRUSH térképeken.
  • Annak ellenére, hogy a rook-ceph-operator stabilnak tekinthető, jelenleg néhány probléma merül fel a Ceph 13-ról 14-re történő frissítése során.

Álláspontja

„Jelenleg Rookot gyalogok zárják el a külvilágtól, de hisszük, hogy egy napon döntő szerepet fog játszani a játékban!” (az idézet kifejezetten ehhez a cikkhez lett kitalálva)

A Rook projekt kétségtelenül elnyerte a szívünket – hisszük, hogy [valamennyi előnyével és hátrányával együtt] mindenképpen megérdemli a figyelmet.

Jövőbeli terveink abban merülnek ki, hogy a rook-ceph egy modult készítsünk addon-operátor, ami még egyszerűbbé és kényelmesebbé teszi használatát számos Kubernetes-fürtünkben.

PS

Olvassa el blogunkon is:

Forrás: will.com

Hozzászólás