На Рук или не на Рук - тоа е прашањето

На Рук или не на Рук - тоа е прашањето

На почетокот на овој месец, на 3 мај, беше објавено големо издание на „систем за управување за дистрибуирано складирање податоци во Кубернетес“ - Рок 1.0.0. Пред повеќе од една година ние веќе објавено општ преглед на Рук. Потоа од нас беше побарано да зборуваме за неговото искуство употреба во пракса - и сега, точно на време за една ваква значајна пресвртница во историјата на проектот, со задоволство ги споделуваме нашите акумулирани впечатоци.

Накратко, Rook е сет оператори за Kubernetes, кои преземаат целосна контрола врз распоредувањето, управувањето, автоматското враќање на решенијата за складирање податоци како што се Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

Во моментов најразвиените (и единственото в стабилно фаза) решението е рок-цеф-оператор.

Имајте на ум: Меѓу значајните промени во изданието на Rook 1.0.0 поврзани со Ceph, можеме да ја забележиме поддршката за Ceph Nautilus и способноста да се користи NFS за CephFS или RGW кофи. Она што се издвојува меѓу другото е созревањето на поддршката на EdgeFS до бета ниво.

Значи, во оваа статија ние:

  • Ајде да одговориме на прашањето какви предности гледаме во користењето на Rook за распоредување на Ceph во кластерот Kubernetes;
  • Ќе го споделиме нашето искуство и впечатоци од користењето на Rook во производството;
  • Ајде да ви кажеме зошто му велиме „Да!“ на Рук и за нашите планови за него.

Да почнеме со општи концепти и теорија.

„Имам предност од еден Рок! (непознат шахист)

На Рук или не на Рук - тоа е прашањето

Една од главните предности на Rook е тоа што интеракцијата со складиштата на податоци се врши преку механизмите на Kubernetes. Ова значи дека повеќе не треба да ги копирате командите за конфигурирање на Ceph од листот во конзолата.

— Дали сакате да го распоредите CephFS во кластер? Само напишете датотека YAML!
- Што? Дали сакате да распоредите продавница за објекти со S3 API? Само напишете втора датотека YAML!

Rook е создаден според сите правила на типичен оператор. Интеракцијата со него се јавува со користење CRD (Дефиниции за прилагодени ресурси), во кој ги опишуваме карактеристиките на ентитетите на Кеф што ни се потребни (бидејќи ова е единствената стабилна имплементација, стандардно овој напис ќе зборува за Ceph, освен ако не е експлицитно наведено поинаку). Според наведените параметри, операторот автоматски ќе ги изврши командите потребни за конфигурација.

Ајде да ги погледнеме спецификите користејќи го примерот за создавање продавница за објекти, или подобро кажано - 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 }}

Параметрите наведени во списокот се сосема стандардни и едвај имаат потреба од коментари, но вреди да се обрне посебно внимание на оние што се распределени на променливите на шаблоните.

Општата шема на работа се сведува на фактот дека ние „нарачуваме“ ресурси преку датотека YAML, за која операторот ги извршува потребните команди и ни враќа „не толку реална“ тајна со која можеме понатаму да работиме (Види подолу). И од променливите наведени погоре, командата и тајното име ќе бидат компајлирани.

Каков тим е ова? Кога креирате корисник за складирање на објекти, операторот Rook во подлогата ќе го направи следново:

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

Резултатот од извршувањето на оваа команда ќе биде структура JSON:

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

Keys - што ќе им треба на идните апликации за пристап до складирање на објекти преку S3 API. Операторот Rook љубезно ги избира и ги става во неговиот именски простор во форма на тајна со името rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

За да ги користите податоците од оваа тајна, само додадете ги во контејнерот како променливи на околината. Како пример, ќе дадам образец за Job, во кој автоматски креираме кофи за секоја корисничка околина:

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

Сите дејства наведени во оваа Работа беа извршени во рамките на Kubernetes. Структурите опишани во YAML-датотеките се чуваат во складиштето на Git и повторно се користат многу пати. Го гледаме ова како огромен плус за инженерите на DevOps и процесот на CI/CD како целина.

Среќен со Рук и Радош

Користењето на комбинацијата Ceph + RBD наметнува одредени ограничувања за монтажата на волумените на мешунките.

Конкретно, именскиот простор мора да содржи тајна за пристап до Ceph за да функционираат државните апликации. Во ред е ако имате 2-3 околини во нивните именски простори: можете да отидете и рачно да ја копирате тајната. Но, што ако за секоја карактеристика се создаде посебна средина со сопствен именски простор за програмерите?

Сами го решивме овој проблем користејќи школка-оператор, кој автоматски ги копирал тајните во нови именски простори (пример за таква кука е опишан во овој напис).

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

Меѓутоа, кога се користи Rook, овој проблем едноставно не постои. Процесот на монтирање се случува со користење на сопствени драјвери врз основа на Flexvolume или CSI (сè уште во бета фаза) и затоа не бара тајни.

Rook автоматски решава многу проблеми, што нè поттикнува да го користиме во нови проекти.

Опсада на Рук

Ајде да го завршиме практичниот дел со распоредување на Rook и Ceph за да можеме да ги спроведеме нашите сопствени експерименти. За полесно да се нападне оваа непробојна кула, програмерите подготвија пакет Helm. Ајде да го преземеме:

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

Во датотека rook-ceph/values.yaml можете да најдете многу различни поставки. Најважно е да се специфицираат толеранциите за агентите и пребарувањето. Детално опишавме за што може да се користи механизмот за дамки/толеранции овој напис.

Накратко, не сакаме местата за апликации на клиентот да се наоѓаат на истите јазли како и дисковите за складирање податоци. Причината е едноставна: на овој начин работата на агентите на Rook нема да влијае на самата апликација.

Значи, отворете ја датотеката rook-ceph/values.yaml со вашиот омилен уредник и додадете го следниот блок на крајот:

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

За секој јазол резервиран за складирање податоци, додадете ја соодветната дамка:

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

Потоа инсталирајте ја табелата на Helm со командата:

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

Сега треба да креирате кластер и да ја наведете локацијата 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 - очекувајте да видите 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

Во исто време, да провериме дали подлогите со клиентската апликација не завршуваат на јазли резервирани за Ceph:

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

Понатаму, дополнителните компоненти може да се конфигурираат по желба. Повеќе детали за нив се наведени во документација. За администрација, силно препорачуваме да ги инсталирате контролната табла и алатникот.

Рок и куки: дали е Рук доволно за се?

Како што можете да видите, развојот на Rook е во полн замав. Но, сè уште има проблеми што не ни дозволуваат целосно да ја напуштиме рачната конфигурација на Ceph:

  • Нема возач на Rook не може извозни метрики за употреба на монтирани блокови, што нè лишува од следење.
  • Flexvolume и CSI не знам како променете ја големината на волумените (за разлика од истиот RBD), така што Rook е лишен од корисна (а понекогаш и критично потребна!) алатка.
  • Рук сè уште не е толку флексибилен како обичниот Цеф. Ако сакаме да го конфигурираме базенот за метаподатоците на CephFS да се складираат на SSD, а самите податоци да се складираат на HDD, ќе треба рачно да регистрираме одделни групи уреди во мапите CRUSH.
  • И покрај фактот дека rook-ceph-операторот се смета за стабилен, во моментов има некои проблеми при надградбата на Ceph од верзијата 13 на 14.

Наоди

„Во моментов Рук е затворена од надворешниот свет со пиони, но веруваме дека еден ден таа ќе игра одлучувачка улога во играта!“ (цитат измислен специјално за овој напис)

Проектот Rook несомнено ги освои нашите срца - веруваме дека [со сите свои добрите и лошите страни] дефинитивно го заслужува вашето внимание.

Нашите идни планови се сведуваат на тоа да направиме rook-ceph модул за кој додаток-оператор, што ќе ја направи неговата употреба во нашите бројни Kubernetes кластери уште поедноставна и поудобна.

PS

Прочитајте и на нашиот блог:

Извор: www.habr.com

Додадете коментар