Rook apo jo Rook — kjo është çështja

Rook apo jo Rook — kjo është çështja

Në fillim të këtij muaji, më 3 maj, u njoftua një lansim i madh i 'sistemit të menaxhimit për depozitat e shpërndara të dhënash në Kubernetes' — Rook 1.0.0. Më shumë se një vit më parë ne tashmë publikuam një përmbledhje të përgjithshme të Rook. Në atë kohë na u kërkua të flisnim për përvojën e tij në praktikë — dhe ja, pikërisht për një përmendje të tillë të rëndësishme në historinë e projektit, jemi të lumtur të ndajmë përshtypjet e grumbulluara.

Nëse e përmbledhim, Rook është një grup Të dhënat dhe puna me to — janë baza për Kubernetes, i cili merr plotësisht nën kontroll vendosjen, menaxhimin, rikuperimin automatik të zgjidhjeve për ruajtjen e dhënave, si Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Derisa, zgjidhja më e zhvilluar (dhe e vetmja në stabilitetit në fazë) është rook-ceph-operator.

Shënim: ndër ndryshimet e rëndësishme në lansimin e Rook 1.0.0, të lidhura me Ceph, mund të përmendim mbështetje për Ceph Nautilus dhe mundësinë për të përdorur NFS për CephFS- ose RGW-bakete. Nga të tjerat, veçohet 'pjekja' e mbështetjes së EdgeFS në nivelin beta.

Pra, në këtë artikull ne:

  • do të përgjigjemi në pyetjen se cilat janë përfitimet që shohim në përdorimin e Rook për vendosjen e Ceph në klasterin Kubernetes;
  • do të ndajmë përvojën dhe përshtypjet nga përdorimi i Rook në prodhim;
  • do të tregojmë pse i themi Rook’ut 'Po!', dhe për planet tona mbi të.

Të fillojmë me konceptet dhe teorinë e përgjithshme.

"Kam një avantaj thjesht një Rook!" (një nënshkrues i panjohur)

Rook apo jo Rook — kjo është çështja

Një nga përfitimet kryesore të Rook është se ndërveprimi me depozitat e dhënash bëhet përmes mekanizmave të Kubernetes. Kjo do të thotë se nuk keni më nevojë të kopjoni komandat për të konfiguruar Ceph nga një letër në konsol.

— A do të dëshironit të vendosni CephFS në klaster? Thjesht shkruani një skedar YAML!
— Çfarë? A do të dëshironit të vendosni gjithashtu një object store me API S3? Thjesht shkruani një skedar të dytë YAML!

Rook është krijuar sipas rregullave tipike të një operatori. Ndërveprimi me të ndodh përmes CRD (Mënyrat e Burimit të Personalizuar), në të cilat ne përshkruajmë karakteristikat që na nevojiten për entitetet Ceph (pasi kjo është zgjidhja e vetme e qëndrueshme, në mënyrë që në këtë artikull do të flitet për Ceph, përveç nëse është shprehur ndryshe). Sipas parametrave të caktuar, operatori do të kryejë automatikisht komandat e nevojshme për konfigurim.

Të shohim konkretësi në shembullin e krijimit të Object Store, më saktësisht — 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 }}

Parametrat e listuara janë mjaft standarde dhe me siguri nuk kanë nevojë për komentime, megjithatë është e rëndësishme të vëmë re ato që janë theksuar si variabla të modeleve.

Schema e përgjithshme e funksionimit është e tillë që përmes një skedari YAML ne «porositim» burimet, për këtë arsye operatori ekzekuton komandat e nevojshme dhe na kthen një «sekret jo shumë të vërtetë» me të cilin mund të punojmë më tej. (shih më poshtë). Nga variablat e lartë përmendur, do të formohet komanda dhe emri i sekretes.

Cila është këto komandë? Kur krijojmë një përdorues për objektin e ruajtjes, operatori Rook brenda pod-it do të ekzekutojë si më poshtë:

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

Rezultati i ekzekutimit të kësaj komande do të jetë një strukturë JSON:

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

Çelësat — ato që do të nevojiten në të ardhmen nga aplikacionet për të aksesuar objektin e ruajtjes përmes S3 API. Operator Rook me mirësjellje i zgjedh ato dhe i ruan në namespace-t e tij si një sekret me emrin rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Për të përdorur të dhënat nga ky sekret, mjafton t'i shtoni ato në kontejner si variabla ambienti. Si një shembull, unë do të jem një model për Job, ku ne automatikisht krijojmë bucket-a për çdo mjedis përdoruesi:

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

Të gjitha veprimet e përmendura në këtë Punë u kryen brenda kufijve të Kubernetes. Strukturat e përshkruara në skedarët YAML janë të organizuara në një depo Git dhe janë ripërdorur shumë herë. Këtu shohim një avantazh të madh për inxhinierët DevOps dhe procesin CI/CD në tërësi.

Me Rook dhe Rados është kënaqësi.

Përdorimi i kombinimit Ceph + RBD përjashton disa kufizime në montimin e volumeve në pod.

Në veçanti, në namespace duhet të ekzistojë një sekret për qasje në Ceph, në mënyrë që aplikacionet me gjendje të funksionojnë. Është normale të keni 2-3 ambientet në hapësirat tuaja emërtuese: mund të shkoni dhe të kopjoni sekretin manualisht. Por çfarë të bëni nëse për çdo karakteristikë për zhvilluesit krijohet një ambient i veçantë me kushte të veta emërtuese?

Ne zgjidhëm këtë problem me shell-operator, i cili kopjon automatikisht sekretet në hapësira të reja emërtuese (një shembull i një ngjitjeje të tillë përshkruhet në këto artikuj).

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

Megjithatë, me përdorimin e Rook, kjo problematikë thjesht nuk ekziston. Procesi i montimit ndodh nëpërmjet shoferëve të vetë Rook bazuar në Flexvolume ose CSI (ndërkohë në fazë beta) dhe prandaj nuk kërkon sekrete.

Rook zgjidh automatikisht shumë probleme, çka na motivon të përdorim atë në projektet e reja.

Rrethimi i Rook

Përfundimi i pjesës praktike është zhvillimi i Rook dhe Ceph për të mundësuar eksperimente të veta. Për ta bërë më të lehtë marrjen me assalt këtë kështjellë të pakapshme, zhvilluesit kanë përgatitur një paketë Helm. Le të shkarkojmë atë:

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

Në skedar rook-ceph/values.yaml mund të gjenden shumë parametra të ndryshëm. Më e rëndësishmja është të tregohet tolerimet për agentët dhe kërkimin. Për çfarë mund të përdoret mekanizmi i taints/tolerations, e kemi përshkruar në detaje në këto artikuj.

Nëse në shkurt, ne nuk duam që pod’ët me aplikacionin klient të ndodhen në të njëjtët node ku ndodhen disqet për ruajtjen e të dhënave. Arsyeja është e thjeshtë: kështu funksionimi i agjentëve Rook nuk do të ndikojë në vetë aplikacionin.

Pra, hapim skedarin rook-ceph/values.yaml me redaktorin tonë të preferuar dhe shtojmë bllokun e mëposhtëm në fund:

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

Çdo node që është rezervuar për ruajtjen e të dhënave, duhet të ketë taintin përkatës:

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

Pas kësaj, instalojmë Helm-chart me komandën:

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

Tani është e nevojshme të krijohet një klaster dhe të tregojmë vendndodhjen e 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"

Kontrollojmë statusin e Ceph — presim të shohim 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

Po ashtu do të kontrollojmë se pod’ët me aplikacionin klient nuk ndodhen në node të rezervuara për Ceph:

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

Më pas, sipas dëshirës, konfigurohen komponentë të tjerë. Më shumë informacion mbi ta gjendet në dokumentacionin. Për administrim rekomandojmë fuqimisht të instalohet dashboard dhe toolbox.

Dërguesit e Rook: a ka mjaftueshëm Rook për çdo gjë?

Siç duket, zhvillimi i Rook po vazhdon me ritëm të shpejtë. Megjithatë, ende ekzistojnë probleme që nuk na lejojnë të heqim dorë plotësisht nga konfigurimi manual i Ceph:

  • Asnjë drejtues Rook nuk di të eksportojë metrika mbi përdorimin e blokëve të montuar, çka na privon nga monitorimi.
  • Flexvolume dhe CSI nuk dinë të ndryshojnë madhësitë e volumeve (ndryshe nga RBD), prandaj Rook humbet një mjet të dobishëm (ndonjëherë edhe kritik!).
  • Rook ende nuk është aq i fleksibël sa Ceph i zakonshëm. Nëse dëshirojmë të konfigurojmë që grupi për metadatat CephFS të ruhet në SSD, ndërsa të dhënat vetë në HDD, do të duhet të shkruajmë manualisht grupe të veçanta pajisjesh në hartat CRUSH.
  • Megjithatë, edhe pse rook-ceph-operator konsiderohet i qëndrueshëm, aktualisht ekzistojnë disa probleme gjatë përditësimit të Ceph nga versioni 13 në 14.

Përfundimet

«Tani Rook është i mbyllur nga bota e jashtme me pawns, por ne besojmë se një ditë do të luajë një rol vendimtar në lojë!» (cita është shpikur posaçërisht për këtë artikull)

Projekti Rook pa dyshim ka fituar zemrat tona - ne besojmë se [me të gjitha avantazhet dhe disavantazhet e tij] ai me siguri meritojnë edhe vëmendjen tuaj.

Planifikimet tona të ardhshme përfshijnë që të bëjmë rook-ceph një modul për addon-operator, çka do ta bëjë përdorimin e tij në shumë Kubernetes-klastra tona edhe më të thjeshtë dhe të rehatshëm.

P.S.

Lexoni gjithashtu në blogun tonë:

Burimi: habr.com

Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS 🔥 Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS | ProHoster