Topu ili ne Topu - to je pitanje

Topu ili ne Topu - to je pitanje

Početkom ovog mjeseca, 3. maja, najavljeno je veliko izdanje „sistema za upravljanje distribuiranim skladištenjem podataka u Kubernetesu“ - Top 1.0.0. Već prije više od godinu dana objavljeno opšti pregled topa. Zatim su nas zamolili da pričamo o njegovom iskustvu koristiti u praksi — i sada, baš na vrijeme za tako značajnu prekretnicu u historiji projekta, sa zadovoljstvom dijelimo naše nagomilane utiske.

Ukratko, Rook je set operateri za Kubernetes, koji preuzimaju potpunu kontrolu nad implementacijom, upravljanjem, automatskim oporavkom rješenja za pohranu podataka kao što su Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Trenutno najrazvijeniji (i jedini в stabilan faza) rešenje je rook-ceph-operator.

primjedba: Među značajnim promjenama u izdanju Rook 1.0.0 koje se odnose na Ceph, možemo primijetiti podršku za Ceph Nautilus i mogućnost korištenja NFS-a za CephFS ili RGW bucket. Ono što se ističe među ostalima je sazrevanje EdgeFS podrške do beta nivoa.

Dakle, u ovom članku mi:

  • Hajde da odgovorimo na pitanje koje prednosti vidimo u korištenju Rooka za implementaciju Ceph-a u Kubernetes klasteru;
  • Podijelit ćemo svoje iskustvo i utiske o korištenju Rooka u proizvodnji;
  • Hajde da vam kažemo zašto kažemo „Da!“ Rooku i o našim planovima za njega.

Počnimo s općim konceptima i teorijom.

"Imam prednost jednog topa!" (nepoznati šahista)

Topu ili ne Topu - to je pitanje

Jedna od glavnih prednosti Rooka je ta što se interakcija sa skladištima podataka odvija kroz Kubernetes mehanizme. To znači da više ne morate kopirati komande za konfiguraciju Ceph-a sa lista u konzolu.

— Da li želite da primenite CephFS u klasteru? Samo napišite YAML datoteku!
- Šta? Želite li također implementirati skladište objekata sa S3 API-jem? Samo napišite drugi YAML fajl!

Top je kreiran prema svim pravilima tipičnog operatera. Interakcija s njim nastaje korištenjem CRD (prilagođene definicije resursa), u kojem opisujemo karakteristike Ceph entiteta koji su nam potrebni (Budući da je ovo jedina stabilna implementacija, ovaj članak će po defaultu govoriti o Ceph-u, osim ako nije izričito drugačije navedeno). Prema navedenim parametrima, operater će automatski izvršiti naredbe potrebne za konfiguraciju.

Pogledajmo pojedinosti koristeći primjer kreiranja trgovine objekata, odnosno - 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 u listi su prilično standardni i jedva da ih treba komentarisati, ali vrijedi obratiti posebnu pažnju na one koji su dodijeljeni varijablama šablona.

Opća shema rada se svodi na to da resurse „naručujemo“ preko YAML datoteke, za koju operater izvršava potrebne naredbe i vraća nam „ne baš stvarnu“ tajnu s kojom možemo dalje raditi (vidi dolje). A iz gore navedenih varijabli, komanda i tajno ime će se kompajlirati.

Kakav je ovo tim? Prilikom kreiranja korisnika za pohranu objekata, Rook operator unutar modula će učiniti sljedeće:

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

Rezultat izvršavanja ove naredbe će biti JSON struktura:

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

Keys - koje buduće aplikacije će trebati za pristup skladištu objekata putem S3 API-ja. Operator Rook ih ljubazno bira i stavlja u svoj imenski prostor u obliku tajne sa imenom rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Da biste koristili podatke iz ove tajne, samo ih dodajte u kontejner kao varijable okruženja. Kao primjer, dat ću predložak za posao, u kojem automatski kreiramo bucket za svako korisničko okruženje:

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

Sve radnje navedene u ovom Zadatku izvedene su u okviru Kubernetesa. Strukture opisane u YAML datotekama se pohranjuju u Git spremište i više puta se koriste. Ovo vidimo kao veliki plus za DevOps inženjere i CI/CD proces u cjelini.

Zadovoljan sa Rookom i Radosom

Korištenje kombinacije Ceph + RBD nameće određena ograničenja za montažu volumena na podove.

Konkretno, imenski prostor mora sadržavati tajnu za pristup Ceph-u kako bi aplikacije koje sadrže stanje funkcionirale. U redu je ako imate 2-3 okruženja u njihovim imenskim prostorima: možete otići i kopirati tajnu ručno. Ali šta ako se za svaku karakteristiku kreira zasebno okruženje sa sopstvenim prostorom imena za programere?

Ovaj problem smo sami riješili koristeći shell-operator, koji je automatski kopirao tajne u nove prostore imena (primjer takve kuke je opisan u ovaj članak).

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

Međutim, kada koristite Rook, ovaj problem jednostavno ne postoji. Proces montaže se odvija korišćenjem sopstvenih drajvera na osnovu Flexvolume ili CSI (još u beta fazi) i stoga ne zahtijeva tajne.

Rook automatski rješava mnoge probleme, što nas potiče da ga koristimo u novim projektima.

Opsada topa

Završimo praktični dio postavljanjem Rooka i Cepha kako bismo mogli provoditi vlastite eksperimente. Kako bi olakšali juriš na ovu neosvojivu kulu, programeri su pripremili Helm paket. Preuzmimo ga:

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

U fajlu rook-ceph/values.yaml možete pronaći mnogo različitih postavki. Najvažnije je specificirati tolerancije za agente i pretragu. Detaljno smo opisali u čemu se može koristiti mehanizam mrlja/tolerancije ovaj članak.

Ukratko, ne želimo da se podovi klijentske aplikacije nalaze na istim čvorovima kao i diskovi za pohranu podataka. Razlog je jednostavan: na ovaj način rad Rook agenata neće utjecati na samu aplikaciju.

Dakle, otvorite datoteku rook-ceph/values.yaml sa vašim omiljenim editorom i dodajte sljedeći blok na kraju:

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

Za svaki čvor rezerviran za pohranu podataka dodajte odgovarajuću mrlju:

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

Zatim instalirajte Helm chart naredbom:

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

Sada morate kreirati klaster i odrediti lokaciju 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"

Provjera Ceph statusa - očekujte da vidite 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

U isto vrijeme, provjerimo da podovi s klijentskom aplikacijom ne završe na čvorovima rezerviranim za Ceph:

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

Nadalje, dodatne komponente se mogu konfigurirati po želji. Više detalja o njima navedeno je u dokumentaciju. Za administraciju, toplo preporučujemo instaliranje kontrolne ploče i alata.

Top i udice: da li je top dovoljan za sve?

Kao što vidite, razvoj Rooka je u punom jeku. Ali još uvijek postoje problemi koji nam ne dozvoljavaju da potpuno napustimo ručnu konfiguraciju Ceph-a:

  • No Rook Driver ne mogu izvoz metrike o korištenju montiranih blokova, što nas lišava nadzora.
  • Flexvolume i CSI ne znam kako promijenite veličinu volumena (za razliku od istog RBD-a), tako da je Rook lišen korisnog (i ponekad kritično potrebnog!) alata.
  • Rook još uvijek nije tako fleksibilan kao obični Ceph. Ako želimo da konfigurišemo spremište za CephFS metapodatke da se pohranjuju na SSD, a sami podaci da se pohranjuju na HDD, moraćemo ručno da registrujemo odvojene grupe uređaja u CRUSH mapama.
  • Uprkos činjenici da se rook-ceph-operator smatra stabilnim, trenutno postoje problemi prilikom nadogradnje Ceph-a sa verzije 13 na 14.

nalazi

“Trenutno je top zatvorena od vanjskog svijeta pijunima, ali vjerujemo da će jednog dana igrati odlučujuću ulogu u igri!” (citat izmišljen posebno za ovaj članak)

Projekt Rook je nesumnjivo osvojio naša srca - vjerujemo da [sa svim svojim prednostima i nedostacima] definitivno zaslužuje vašu pažnju.

Naši budući planovi se svode na to da rook-ceph bude modul za addon-operator, što će učiniti njegovu upotrebu u našim brojnim Kubernetes klasterima još jednostavnijom i praktičnijom.

PS

Pročitajte i na našem blogu:

izvor: www.habr.com

Dodajte komentar