Topu ali ne Rooku - to je vprašanje

Topu ali ne Rooku - to je vprašanje

V začetku tega meseca, 3. maja, je bila objavljena velika izdaja "sistema upravljanja za porazdeljeno shranjevanje podatkov v Kubernetesu" - Rook 1.0.0. Že pred več kot enim letom objavljeno splošni pregled Rooka. Potem so nas prosili, da spregovorimo o njegovi izkušnji uporabo v praksi — in zdaj, ravno v času za tako pomemben mejnik v zgodovini projekta, z veseljem delimo naše zbrane vtise.

Skratka, Rook je komplet izvajalci za Kubernetes, ki prevzamejo popoln nadzor nad uvajanjem, upravljanjem in samodejnim obnavljanjem rešitev za shranjevanje podatkov, kot so Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Trenutno najbolj razvit (in edini в stabilno faza) rešitev je rook-ceph-operator.

Obvestilo: Med pomembnimi spremembami v izdaji Rook 1.0.0, povezanimi s Cephom, lahko omenimo podporo za Ceph Nautilus in možnost uporabe NFS za vedra CephFS ali RGW. Kar med drugim izstopa, je dozorevanje podpore za EdgeFS na raven beta.

Torej, v tem članku:

  • Odgovorimo na vprašanje, kakšne prednosti vidimo pri uporabi Rooka za namestitev Ceph v gručo Kubernetes;
  • Delili bomo svoje izkušnje in vtise o uporabi Rook v proizvodnji;
  • Naj vam povemo, zakaj Rooku rečemo "Da!" in o naših načrtih z njim.

Začnimo s splošnimi koncepti in teorijo.

"Imam prednost enega topa!" (neznani šahist)

Topu ali ne Rooku - to je vprašanje

Ena od glavnih prednosti Rooka je, da interakcija s shrambami podatkov poteka prek mehanizmov Kubernetes. To pomeni, da vam ni več treba kopirati ukazov za konfiguracijo Ceph iz lista v konzolo.

— Ali želite uvesti CephFS v gruči? Samo napišite datoteko YAML!
- Kaj? Ali želite uvesti tudi shrambo objektov z API-jem S3? Samo napišite drugo datoteko YAML!

Rook je ustvarjen po vseh pravilih tipičnega operaterja. Interakcija z njim poteka z uporabo CRD (definicije virov po meri), v katerem opisujemo značilnosti Ceph entitet, ki jih potrebujemo (ker je to edina stabilna izvedba, bo ta članek privzeto govoril o Cephu, razen če je izrecno navedeno drugače). V skladu z navedenimi parametri bo operater samodejno izvedel ukaze, potrebne za konfiguracijo.

Oglejmo si posebnosti na primeru ustvarjanja Object Store, ali bolje rečeno - 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 }}

Parametri, navedeni v seznamu, so precej standardni in komaj potrebujejo komentarje, vendar je vredno posvetiti posebno pozornost tistim, ki so dodeljeni spremenljivkam predloge.

Splošna shema dela se zmanjša na dejstvo, da "naročimo" vire prek datoteke YAML, za katero operater izvede potrebne ukaze in nam vrne "ne tako resnično" skrivnost, s katero lahko delamo naprej (glej spodaj). Iz zgoraj navedenih spremenljivk bosta sestavljena ukaz in skrivno ime.

Kakšna ekipa je to? Pri ustvarjanju uporabnika za shranjevanje objektov bo operater Rook znotraj sklopa naredil naslednje:

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

Rezultat izvajanja tega ukaza bo struktura JSON:

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

Keys - katere prihodnje aplikacije bodo morale dostopati do shranjevanja objektov prek API-ja S3. Operater Rook jih prijazno izbere in v obliki skrivnosti z imenom postavi v svoj imenski prostor rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Če želite uporabiti podatke iz te skrivnosti, jih preprosto dodajte v vsebnik kot spremenljivke okolja. Kot primer bom dal predlogo za Job, v kateri samodejno ustvarimo vedra za vsako uporabniško okolje:

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

Vsa dejanja, navedena v tem opravilu, so bila izvedena v okviru Kubernetesa. Strukture, opisane v datotekah YAML, so shranjene v repozitoriju Git in večkrat ponovno uporabljene. To vidimo kot velik plus za inženirje DevOps in proces CI/CD kot celoto.

Zadovoljna z Rookom in Radosom

Uporaba kombinacije Ceph + RBD nalaga določene omejitve pri namestitvi prostornine na pode.

Zlasti mora imenski prostor vsebovati skrivnost za dostop do Ceph, da lahko aplikacije s stanjem delujejo. V redu je, če imate 2-3 okolja v njihovih imenskih prostorih: skrivnost lahko kopirate ročno. Toda kaj, če je za vsako funkcijo ustvarjeno ločeno okolje z lastnim imenskim prostorom za razvijalce?

To težavo smo rešili sami z uporabo lupina-operater, ki je samodejno kopiral skrivnosti v nove imenske prostore (primer takega kljuka je opisan v ta članek).

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

Vendar pri uporabi Rook ta problem preprosto ne obstaja. Postopek namestitve poteka z lastnimi gonilniki, ki temeljijo na Flexvolume ali CSI (še vedno v beta fazi) in zato ne zahteva skrivnosti.

Rook samodejno reši veliko težav, kar nas spodbuja k uporabi v novih projektih.

Obleganje Rooka

Dokončajmo praktični del z uvedbo Rook in Ceph, da bomo lahko izvajali lastne poskuse. Za lažji napad na ta neosvojljiv stolp so razvijalci pripravili paket Helm. Prenesimo ga:

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

V datoteki rook-ceph/values.yaml najdete lahko veliko različnih nastavitev. Najpomembnejša stvar je določitev toleranc za agente in iskanje. Podrobno smo opisali, za kaj se lahko uporablja mehanizem za omamljanje/tolerance ta članek.

Skratka, ne želimo, da so sklopi odjemalskih aplikacij nameščeni na istih vozliščih kot diski za shranjevanje podatkov. Razlog je preprost: tako delo agentov Rook ne bo vplivalo na samo aplikacijo.

Torej, odprite datoteko rook-ceph/values.yaml s svojim najljubšim urejevalnikom in na koncu dodajte naslednji blok:

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

Za vsako vozlišče, rezervirano za shranjevanje podatkov, dodajte ustrezen madež:

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

Nato namestite Helm chart z ukazom:

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

Zdaj morate ustvariti gručo in določiti lokacijo 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"

Preverjanje statusa Ceph - pričakujte, da boste videli 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

Hkrati preverimo, da podi z odjemalsko aplikacijo ne končajo na vozliščih, rezerviranih za Ceph:

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

Poleg tega je mogoče po želji konfigurirati dodatne komponente. Več podrobnosti o njih je navedenih v dokumentacijo. Za administracijo močno priporočamo namestitev armaturne plošče in orodjarne.

Top in trnki: je Top dovolj za vse?

Kot lahko vidite, je razvoj Rooka v polnem teku. Vendar še vedno obstajajo težave, ki nam ne dovoljujejo, da popolnoma opustimo ročno konfiguracijo Ceph:

  • Ni Rook Driverja ne morem izvoz metrike o uporabi montiranih blokov, kar nas prikrajša za spremljanje.
  • Flexvolume in CSI ne vem kako spremenite velikost nosilcev (v nasprotju z istim RBD), tako da je Rook prikrajšan za uporabno (in včasih kritično potrebno!) orodje.
  • Rook še vedno ni tako prilagodljiv kot običajni Ceph. Če želimo konfigurirati skupino za shranjevanje metapodatkov CephFS na SSD, same podatke pa za shranjevanje na trdi disk, bomo morali ročno registrirati ločene skupine naprav v zemljevidih ​​CRUSH.
  • Kljub dejstvu, da se rook-ceph-operator šteje za stabilnega, je trenutno nekaj težav pri nadgradnji Cepha iz različice 13 na 14.

Ugotovitve

"Trenutno je Rook s kmeti zaprt pred zunanjim svetom, vendar verjamemo, da bo nekega dne igral odločilno vlogo v igri!" (citat izmišljen posebej za ta članek)

Projekt Rook je nedvomno osvojil naša srca – verjamemo, da si [z vsemi svojimi prednostmi in slabostmi] vsekakor zasluži vašo pozornost.

Naši načrti za prihodnost se spuščajo v to, da naredimo rook-ceph modul za addon-operator, zaradi česar bo njegova uporaba v naših številnih gručah Kubernetes še preprostejša in priročnejša.

PS

Preberite tudi na našem blogu:

Vir: www.habr.com

Dodaj komentar