Rookille vai ei Rookille - se on kysymys

Rookille vai ei Rookille - se on kysymys

Tämän kuun alussa, 3. toukokuuta, julkistettiin "Kubernetesin hajautetun tiedontallennusjärjestelmän hallintajärjestelmä" - Torni 1.0.0. Olemme jo yli vuosi sitten julkaistu yleiskatsaus Rookista. Sitten meitä pyydettiin keskustelemaan hänen kokemuksestaan käyttää käytännössä – ja nyt, juuri niin merkittävän virstanpylvään aikaan projektin historiassa, jaamme mielellämme kertyneet vaikutelmamme.

Lyhyesti sanottuna Rook on sarja toimijoiden Kubernetesille, joka ottaa täyden hallinnan tietotallennusratkaisujen, kuten Ceph, EdgeFS, Mini, Cassandra, CockroachDB, käyttöönotosta, hallinnasta ja automaattisesta palautuksesta.

Tällä hetkellä kehittynein (ja ainoa в vakaa vaiheessa) ratkaisu on rook-ceph-operaattori.

Huomata: Cephiin liittyvän Rook 1.0.0 -julkaisun merkittävistä muutoksista voimme mainita Ceph Nautiluksen tuen ja mahdollisuuden käyttää NFS:ää CephFS- tai RGW-ämpäriin. Muiden joukossa erottuu EdgeFS-tuen kypsyminen beta-tasolle.

Joten tässä artikkelissa me:

  • Vastataan kysymykseen siitä, mitä etuja näemme Rookin käyttämisessä Cephin käyttöönotossa Kubernetes-klusterissa;
  • Jaamme kokemuksemme ja vaikutelmamme Rookin käytöstä tuotannossa;
  • Kerrotaan miksi sanomme "Kyllä!" Rookille ja suunnitelmistamme häntä kohtaan.

Aloitetaan yleisistä käsitteistä ja teoriasta.

"Minulla on yksi torni etu!" (Tuntematon shakinpelaaja)

Rookille vai ei Rookille - se on kysymys

Yksi Rookin tärkeimmistä eduista on se, että vuorovaikutus tietovarastojen kanssa tapahtuu Kubernetes-mekanismien kautta. Tämä tarkoittaa, että sinun ei enää tarvitse kopioida komentoja Cephin määrittämiseksi taulukosta konsoliin.

— Haluatko ottaa CephFS:n käyttöön klusterissa? Kirjoita vain YAML-tiedosto!
- Mitä? Haluatko myös ottaa käyttöön S3 API:n kanssa objektikaupan? Kirjoita vain toinen YAML-tiedosto!

Torni on luotu kaikkien tyypillisen operaattorin sääntöjen mukaan. Vuorovaikutus hänen kanssaan tapahtuu käyttämällä CRD (muokatut resurssien määritelmät), jossa kuvaamme tarvitsemiemme Ceph-entiteettien ominaisuuksia (koska tämä on ainoa vakaa toteutus, oletusarvoisesti tässä artikkelissa puhutaan Cephistä, ellei nimenomaisesti toisin mainita). Määritettyjen parametrien mukaan käyttäjä suorittaa automaattisesti konfigurointiin tarvittavat komennot.

Tarkastellaan yksityiskohtia käyttämällä esimerkkiä esinekaupan luomisesta, tai pikemminkin - 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 }}

Listauksessa ilmoitetut parametrit ovat varsin vakiomuotoisia eivätkä kaipaa kommentteja, mutta mallimuuttujille varattuihin parametreihin kannattaa kiinnittää erityistä huomiota.

Yleinen työsuunnitelma tiivistyy siihen, että "tilaamme" resursseja YAML-tiedoston kautta, jolle operaattori suorittaa tarvittavat komennot ja palauttaa meille "ei niin todellisen" salaisuuden, jonka kanssa voimme työskennellä edelleen (Katso alempaa). Ja yllä luetelluista muuttujista käännetään komento ja salainen nimi.

Millainen joukkue tämä on? Kun luot käyttäjän objektien tallennusta varten, podin sisällä oleva Rook-operaattori tekee seuraavaa:

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

Tämän komennon suorittamisen tulos on JSON-rakenne:

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

Keys - mitä tulevat sovellukset tarvitsevat päästäkseen objektitallennustilaan S3 API:n kautta. Rook-operaattori valitsee ne ystävällisesti ja laittaa ne omaan nimiavaruuteensa salaisuuden muodossa nimen kanssa rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

Jos haluat käyttää tämän salaisuuden tietoja, lisää ne säilöön ympäristömuuttujiksi. Esimerkkinä annan mallin Jobille, jossa luomme automaattisesti ämpärit kullekin käyttäjäympäristölle:

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

Kaikki tässä tehtävässä luetellut toimet suoritettiin Kubernetesin puitteissa. YAML-tiedostoissa kuvatut rakenteet tallennetaan Git-arkistoon ja niitä käytetään useita kertoja. Näemme tämän valtavana lisänä DevOps-insinööreille ja CI/CD-prosessille kokonaisuudessaan.

Tyytyväinen Rookin ja Radosin kanssa

Ceph + RBD -yhdistelmän käyttö asettaa tiettyjä rajoituksia tilavuuksien kiinnittämiselle koteloihin.

Erityisesti nimiavaruudessa on oltava salaisuus Ceph-käyttöä varten, jotta tilalliset sovellukset toimivat. On ok, jos sinulla on 2-3 ympäristöä niiden nimiavaruuksissa: voit kopioida salaisuuden manuaalisesti. Mutta entä jos jokaiselle ominaisuudelle luodaan kehittäjille erillinen ympäristö omalla nimiavaruudellaan?

Ratkaisimme tämän ongelman itse käyttämällä kuorioperaattori, joka kopioi salaisuudet automaattisesti uusiin nimiavaroihin (esimerkki tällaisesta koukusta on kuvattu kohdassa tässä artikkelissa).

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

Kuitenkin, kun käytät Rookia, tätä ongelmaa ei yksinkertaisesti ole. Asennusprosessi tapahtuu käyttämällä sen omia ohjaimia Flexvolume tai CSI (vielä beta-vaiheessa) eikä siksi vaadi salaisuuksia.

Rook ratkaisee automaattisesti monia ongelmia, mikä rohkaisee meitä käyttämään sitä uusissa projekteissa.

Rookin piiritys

Suoritetaan käytännön osa ottamalla käyttöön Rook ja Ceph, jotta voimme suorittaa omia kokeilujamme. Tämän vallitsemattoman tornin myrskyn helpottamiseksi kehittäjät ovat laatineet Helm-paketin. Ladataan se:

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

Tiedostossa rook-ceph/values.yaml löydät monia erilaisia ​​asetuksia. Tärkeintä on määrittää toleranssit agenteille ja haulle. Kuvasimme yksityiskohtaisesti, mihin tahra-/sietomekanismia voidaan käyttää tässä artikkelissa.

Lyhyesti sanottuna emme halua, että asiakassovellusyksiköt sijaitsevat samoissa solmuissa kuin tiedontallennuslevyt. Syy on yksinkertainen: näin Rook-agenttien työ ei vaikuta itse sovellukseen.

Joten, avaa tiedosto rook-ceph/values.yaml suosikkieditorillasi ja lisää seuraava lohko loppuun:

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

Lisää jokaiselle datan tallennusta varten varatulle solmulle vastaava tahra:

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

Asenna sitten ruorikaavio komennolla:

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

Nyt sinun on luotava klusteri ja määritettävä sijainti 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"

Ceph-tilan tarkistaminen - odota nähdä 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

Samalla tarkistetaan, että asiakassovelluksen podit eivät päädy Cephille varattuihin solmuihin:

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

Lisäksi lisäkomponentteja voidaan konfiguroida tarpeen mukaan. Tarkempia tietoja niistä on ilmoitettu kohdassa dokumentointi. Hallintoa varten suosittelemme kojelaudan ja työkalulaatikon asentamista.

Torni ja koukut: riittääkö torni kaikkeen?

Kuten näette, Rookin kehitys on täydessä vauhdissa. Mutta silti on ongelmia, jotka eivät anna meidän luopua kokonaan Cephin manuaalisesta määrityksestä:

  • Ei Rook-kuljettajaa ei voi viedä mittareita asennettujen lohkojen käytöstä, mikä estää meiltä valvonnan.
  • Flexvolume ja CSI en tiedä miten muuttaa volyymien kokoa (toisin kuin sama RBD), joten Rook menettää hyödyllisen (ja joskus erittäin tarpeellisen!) työkalun.
  • Rook ei ole vieläkään yhtä joustava kuin tavallinen Ceph. Jos haluamme määrittää poolin CephFS-metadatalle tallennettavaksi SSD:lle ja itse datan tallennettavaksi kiintolevylle, meidän on rekisteröitävä erilliset laiteryhmät CRUSH-karttoihin manuaalisesti.
  • Huolimatta siitä, että rook-ceph-operaattoria pidetään vakaana, Cephin päivityksessä versiosta 13 versioon 14 on tällä hetkellä joitain ongelmia.

Tulokset

"Tällä hetkellä Rook on eristetty ulkomaailmasta pelinappuloilla, mutta uskomme, että jonain päivänä hänellä on ratkaiseva rooli pelissä!" (Lainaus keksitty nimenomaan tätä artikkelia varten)

Rook-projekti on epäilemättä voittanut sydämemme - uskomme, että se [kaikkien etujensa ja haittojensa kanssa] ansaitsee ehdottomasti huomiosi.

Tulevaisuuden suunnitelmamme tiivistyvät siihen, että teemme rook-cephistä moduulin addon-operaattori, mikä tekee sen käytöstä lukuisissa Kubernetes-klustereissamme entistä yksinkertaisempaa ja kätevämpää.

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti