Al Rook aŭ ne al Rook - jen la demando

Al Rook aŭ ne al Rook - jen la demando

Komence de ĉi tiu monato, la 3-an de majo, estis anoncita grava eldono de "administra sistemo por distribuita datumstokado en Kubernetes" - Roko 1.0.0. Antaŭ pli ol unu jaro ni jam eldonita ĝenerala superrigardo de Rook. Tiam oni petis nin paroli pri lia sperto uzi en la praktiko — kaj nun, ĝustatempe por tiel signifa mejloŝtono en la historio de la projekto, ni feliĉas kundividi niajn amasigitajn impresojn.

Mallonge, Rook estas aro telefonistoj por Kubernetes, kiuj prenas plenan kontrolon de la deplojo, administrado, aŭtomata reakiro de datumstokaj solvoj kiel Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Nuntempe la plej evoluinta (kaj la sola в stabila etapo) la solvo estas rook-ceph-operator.

Примечание: Inter la signifaj ŝanĝoj en la eldono de Rook 1.0.0 rilate al Ceph, ni povas noti subtenon por Ceph Nautilus kaj la kapablon uzi NFS por CephFS aŭ RGW-siteloj. Kio elstaras inter aliaj estas la maturiĝo de EdgeFS-subteno al la beta-nivelo.

Do, en ĉi tiu artikolo ni:

  • Ni respondu la demandon pri kiaj avantaĝoj ni vidas uzi Rook por deploji Ceph en Kubernetes-areo;
  • Ni dividos nian sperton kaj impresojn pri uzado de Rook en produktado;
  • Ni diru al vi kial ni diras “Jes!” al Rook, kaj pri niaj planoj por li.

Ni komencu per ĝeneralaj konceptoj kaj teorio.

"Mi havas avantaĝon de unu Roko!" (nekonata ŝakludanto)

Al Rook aŭ ne al Rook - jen la demando

Unu el la ĉefaj avantaĝoj de Rook estas, ke interago kun datumbutikoj estas efektivigita per Kubernetes-mekanismoj. Ĉi tio signifas, ke vi ne plu bezonas kopii la komandojn por agordi Ceph de la folio en la konzolon.

— Ĉu vi volas deploji CephFS en areto? Nur skribu YAML-dosieron!
- Kio? Ĉu vi ankaŭ volas deploji objektobutikon kun S3 API? Nur skribu duan YAML-dosieron!

Rook estas kreita laŭ ĉiuj reguloj de tipa funkciigisto. Interago kun li okazas uzante CRD (Personadaj Rimedaj Difinoj), en kiu ni priskribas la karakterizaĵojn de Ceph-entaĵoj, kiujn ni bezonas (Ĉar tio estas la nura stabila efektivigo, defaŭlte ĉi tiu artikolo parolos pri Ceph, krom se eksplicite dirite alie). Laŭ la specifitaj parametroj, la operatoro aŭtomate plenumos la komandojn necesajn por agordo.

Ni rigardu la specifaĵojn uzante la ekzemplon krei Objektan Vendejon, aŭ pli ĝuste - 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 }}

La parametroj indikitaj en la listo estas sufiĉe normaj kaj apenaŭ bezonas komentojn, sed indas atenti speciale tiujn asignitajn al ŝablonaj variabloj.

La ĝenerala skemo de laboro venas al tio, ke ni "ordigas" rimedojn per YAML-dosiero, por kiu la operatoro plenumas la necesajn komandojn kaj resendas al ni "ne tiom realan" sekreton per kiu ni povas plu labori. (Vidu suben). Kaj el la variabloj listigitaj supre, la komando kaj sekreta nomo estos kompilitaj.

Kia teamo estas ĉi tiu? Kreante uzanton por objektostokado, la Rook-funkciigisto ene de la pod faros la jenon:

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

La rezulto de ekzekuto de ĉi tiu komando estos JSON-strukturo:

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

Keys - kiaj estontaj aplikoj bezonos por aliri objektostokadon per la S3 API. La Rook-funkciigisto afable elektas ilin kaj metas ilin en sian nomspacon en la formo de sekreto kun la nomo rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Por uzi la datumojn de ĉi tiu sekreto, simple aldonu ĝin al la ujo kiel mediovariabloj. Kiel ekzemplo, mi donos ŝablonon por Job, en kiu ni aŭtomate kreas sitelojn por ĉiu uzantmedio:

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

Ĉiuj agoj listigitaj en ĉi tiu Laboro estis faritaj en la kadro de Kubernetes. La strukturoj priskribitaj en YAML-dosieroj estas konservitaj en Git-deponejo kaj multfoje reuzitaj. Ni vidas ĉi tion kiel grandega pluso por DevOps-inĝenieroj kaj la CI/KD-procezo entute.

Feliĉa kun Rook kaj Rados

Uzado de la kombinaĵo Ceph + RBD trudas iujn limigojn pri muntado de volumoj al podoj.

Aparte, la nomspaco devas enhavi sekreton por aliri Ceph por ke ŝtataj aplikoj funkciu. Estas bone se vi havas 2-3 mediojn en iliaj nomspacoj: vi povas iri kopii la sekreton permane. Sed kio se por ĉiu funkcio estas kreita aparta medio kun sia propra nomspaco por programistoj?

Ni mem solvis ĉi tiun problemon uzante ŝelo-funkciigisto, kiu aŭtomate kopiis sekretojn al novaj nomspacoj (ekzemplo de tia hoko estas priskribita en ĉi tiu artikolo).

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

Tamen, kiam vi uzas Rook, ĉi tiu problemo simple ne ekzistas. La munta procezo okazas uzante siajn proprajn ŝoforojn bazitajn sur FleksvolumoCSI (ankoraŭ en beta stadio) kaj tial ne postulas sekretojn.

Rook aŭtomate solvas multajn problemojn, kio instigas nin uzi ĝin en novaj projektoj.

Sieĝo de Rook

Ni kompletigu la praktikan parton deplojante Rook kaj Ceph por ke ni povu fari niajn proprajn eksperimentojn. Por faciligi sturmi ĉi tiun nepenetreblan turon, la programistoj preparis Helm-pakaĵon. Ni elŝutu ĝin:

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

En dosiero rook-ceph/values.yaml vi povas trovi multajn malsamajn agordojn. La plej grava afero estas specifi tolerojn por agentoj kaj serĉo. Ni priskribis detale por kio la makuloj/tolerema mekanismo povas esti uzata ĉi tiu artikolo.

Resume, ni ne volas, ke la klientaj aplikaĵaj podoj situu sur la samaj nodoj kiel la datumaj diskoj. La kialo estas simpla: tiamaniere la laboro de Rook-agentoj ne influos la aplikaĵon mem.

Do, malfermu la dosieron rook-ceph/values.yaml kun via plej ŝatata redaktilo kaj aldonu la sekvan blokon ĉe la fino:

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

Por ĉiu nodo rezervita por datumstokado, aldonu la respondan makulon:

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

Poste instalu la Helm-diagramon kun la komando:

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

Nun vi devas krei areton kaj specifi la lokon 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"

Kontrolante Ceph-statuson - atendu vidi 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

Samtempe, ni kontrolu, ke la podoj kun la klienta aplikaĵo ne finiĝas sur nodoj rezervitaj por Ceph:

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

Plue, kromaj komponantoj povas esti agorditaj laŭdezire. Pliaj detaloj pri ili estas indikitaj en dokumentado. Por administrado, ni forte rekomendas instali la instrumentpanelon kaj ilarkeston.

Rook kaj hokoj: ĉu Rook sufiĉas por ĉio?

Kiel vi povas vidi, la evoluo de Rook estas en plena svingo. Sed ankoraŭ ekzistas problemoj, kiuj ne permesas al ni tute forlasi manan agordon de Ceph:

  • Neniu Rook Driver ne povas eksporti metrikojn pri la uzo de muntitaj blokoj, kiu senigas nin de monitorado.
  • Flexvolume kaj CSI ne scias kiel ŝanĝi la grandecon de volumoj (kontraste al la sama RBD), do Rook estas senigita de utila (kaj foje kritike bezonata!) ilo.
  • Rook ankoraŭ ne estas same fleksebla kiel regula Ceph. Se ni volas agordi la naĝejon por ke CephFS-metadatumoj estu stokitaj sur SSD, kaj la datumoj mem por esti stokitaj sur HDD, ni devos registri apartajn grupojn de aparatoj en CRUSH-mapoj permane.
  • Malgraŭ la fakto, ke rook-ceph-operator estas konsiderata stabila, nuntempe ekzistas iuj problemoj dum ĝisdatigado de Ceph de versio 13 al 14.

trovoj

"Ĝuste nun Rook estas fermita de la ekstera mondo per peonoj, sed ni kredas, ke iam ŝi ludos decidan rolon en la ludo!" (citaĵo elpensita specife por ĉi tiu artikolo)

La projekto Rook sendube gajnis niajn korojn - ni kredas, ke [kun ĉiuj siaj avantaĝoj kaj malavantaĝoj] ĝi certe meritas vian atenton.

Niaj estontaj planoj resumiĝas al igi rook-ceph modulo por aldon-funkciigisto, kiu faros ĝian uzon en niaj multaj Kubernetes-aretoj eĉ pli simpla kaj pli oportuna.

PS

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton