Tour ou pas Tour - c'est la question



Plus tÎt ce mois-ci, le 3 mai, une version majeure du «systÚme de gestion des entrepÎts de données distribués à Kubernetes» a été annoncée - Rook 1.0.0 . Il y a plus d'un an, nous avons déjà publié un aperçu général de Rook. Ensuite, on nous a demandé de parler de l'expérience de son utilisation dans la pratique - et maintenant, à temps pour une étape aussi importante dans l'histoire du projet, nous sommes heureux de partager nos impressions accumulées.

En bref, Rook est un ensemble d' opérateurs pour Kubernetes qui prennent le contrÎle complet du déploiement, de la gestion et de la récupération automatique de solutions de stockage telles que Ceph, EdgeFS, Minio, Cassandra, CockroachDB.

À l'heure actuelle, la solution la plus dĂ©veloppĂ©e (et uniquement Ă  un stade stable ) est l' opĂ©rateur tour-ceph .

Remarque : Parmi les changements importants dans la version de Rook 1.0.0 liĂ©s Ă  Ceph, la prise en charge de Ceph Nautilus et la possibilitĂ© d'utiliser NFS pour CephFS ou le compartiment RGW peuvent ĂȘtre notĂ©s. Entre autres, la "maturation" du support EdgeFS au niveau bĂȘta se distingue.

Ainsi, dans cet article, nous:

  • rĂ©pondre Ă  la question des avantages que nous voyons Ă  utiliser Rook pour dĂ©ployer Ceph dans le cluster Kubernetes;
  • partager l'expĂ©rience et les impressions de l'utilisation de Rook en production;
  • Nous vous expliquerons pourquoi nous disons «Oui!» À Rook et nos plans pour lui.

Commençons par les concepts généraux et la théorie.

"J'ai un avantage dans une tour!" (joueur d'échecs inconnu)




L'un des principaux avantages de Rook est que l'interaction avec les entrepÎts de données s'effectue via les mécanismes Kubernetes. Cela signifie que vous n'avez plus besoin de copier les commandes pour configurer Ceph de la brochure sur la console.

- Vous souhaitez dĂ©ployer dans un cluster CephFS? Écrivez simplement un fichier yaml!
- Quoi? Vous souhaitez déployer un magasin d'objets avec l'API S3? Il suffit d'écrire un deuxiÚme fichier yaml!

La tour est créée par toutes les rÚgles d'un opérateur typique. L'interaction avec celle-ci se produit à l'aide de CRD (Custom Resource Definitions) , dans lequel nous décrivons les caractéristiques des entités Ceph dont nous avons besoin (car il s'agit de la seule implémentation stable, par défaut, l'article parlera de Ceph, sauf indication contraire explicite) . Selon les paramÚtres spécifiés, l'opérateur exécutera automatiquement les commandes nécessaires à la configuration.

Examinons les détails en utilisant l'exemple de la création d'un magasin d'objets, ou plutÎt 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 }} 

Les paramÚtres indiqués dans la liste sont assez standard et ne nécessiteront probablement pas de commentaires, mais vous devez porter une attention particuliÚre à ceux qui sont mis en évidence dans les variables du modÚle.

Le schéma général de travail se résume au fait qu'à travers le fichier YAML nous «commandons» des ressources, pour lesquelles l'opérateur exécute les commandes nécessaires et nous renvoie le secret «non réel», avec lequel nous pouvons continuer à travailler (voir ci-dessous) . Et à partir des variables indiquées ci-dessus, la commande et le nom du secret seront composés.

De quel genre d'équipe s'agit-il? Lors de la création d'un utilisateur pour le stockage d'objets, l'instruction Rook à l'intérieur du pod fera ce qui suit:

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

Le résultat de cette commande sera une structure JSON:

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

Keys sont ce dont les futures applications auront besoin pour accéder au stockage d'objets via l'API S3. L'opérateur Rook les sélectionne et les place dans son espace de noms en secret sous le nom rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }} .

Pour utiliser les donnĂ©es de ce secret, il suffit de les ajouter au conteneur en tant que variables d'environnement. À titre d'exemple, je vais donner un modĂšle pour Job, dans lequel nous crĂ©ons automatiquement des compartiments pour chaque environnement utilisateur:

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

Toutes les activités énumérées dans ce travail ont été effectuées sans aller au-delà de Kubernetes. Les structures décrites dans les fichiers YAML sont repliées dans le référentiel Git et réutilisées à plusieurs reprises. En cela, nous voyons un énorme avantage pour les ingénieurs DevOps et le processus CI / CD dans son ensemble.

Avec Rook et Rados Ă  Joy


L'utilisation d'un groupe de Ceph + RBD impose certaines restrictions sur le montage de volumes sur des pods.

En particulier, l'espace de noms doit avoir un secret pour accéder à Ceph afin que les applications avec état puissent fonctionner. C'est ok si vous avez 2-3 environnements dans vos espaces de noms: vous pouvez aller copier le secret manuellement. Mais que se passe-t-il si chaque fonctionnalité développeur crée un environnement distinct avec son propre espace de noms?

Nous avons résolu ce problÚme à l'aide d'un opérateur shell , qui copiait automatiquement les secrets dans le nouvel espace de noms (un exemple d'un tel crochet est décrit dans cet article ).

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

Cependant, lors de l'utilisation de Rook, ce problĂšme n'existe tout simplement pas. Le processus de montage se dĂ©roule Ă  l'aide de vos propres pilotes basĂ©s sur Flexvolume ou CSI (toujours en version bĂȘta) et ne nĂ©cessite donc pas de secrets.

Rook résout automatiquement de nombreux problÚmes, ce qui nous encourage à l'utiliser dans de nouveaux projets.

SiĂšge de la tour


Nous complétons la partie pratique avec le déploiement de Rook et Ceph pour la possibilité de mener nos propres expériences. Afin de prendre d'assaut cette tour imprenable, c'était plus facile, les développeurs ont préparé un package Helm. Téléchargez-le:

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

rook-ceph/values.yaml pouvez trouver de nombreux paramÚtres différents dans le fichier rook-ceph/values.yaml . Plus important encore, spécifiez les tolérances pour les agents et la recherche. Pourquoi vous pouvez utiliser le mécanisme de souillures / tolérances, nous l'avons décrit en détail dans cet article .

En bref, nous ne voulons pas que les pods avec l'application client soient situĂ©s sur les mĂȘmes nƓuds oĂč se trouvent les disques de stockage de donnĂ©es. La raison est simple: de cette façon, le travail des agents Rook n'affectera pas l'application elle-mĂȘme.

Alors, ouvrez le fichier rook-ceph/values.yaml éditeur préféré et ajoutez le bloc suivant à la fin:

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

Pour chaque noeud réservé au stockage de données, ajoutez la souillure correspondante:

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

Installez ensuite le Helm-chart avec la commande:

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

Vous devez maintenant créer un cluster et indiquer l'emplacement de l' 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" 

Vérifiez le statut Ceph - attendez-vous à voir 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 

Dans le mĂȘme temps, vĂ©rifiez que les pods avec l'application cliente n'atteignent pas les nƓuds rĂ©servĂ©s Ă  Ceph:

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

D'autres composants optionnels sont configurés. Plus d'informations à leur sujet sont indiquées dans la documentation . Pour l'administration, nous recommandons fortement d'installer le tableau de bord et la boßte à outils.

Tour et crochets: la tour est-elle suffisante pour tout?


Comme vous pouvez le voir, le développement de Rook bat son plein. Mais il y a toujours des problÚmes qui ne nous permettent pas d'abandonner complÚtement la configuration manuelle de Ceph:

  • Aucun pilote Rook ne peut exporter des mĂ©triques sur l'utilisation de blocs montĂ©s, ce qui nous prive de surveillance.
  • Flexvolume et CSI ne savent pas comment redimensionner les volumes (contrairement au mĂȘme RBD), donc Rook perd un outil utile (et parfois indispensable!).
  • Rook n'est toujours pas aussi flexible que Ceph ordinaire. Si nous voulons configurer le pool pour les mĂ©tadonnĂ©es CephFS Ă  stocker sur le SSD et les donnĂ©es elles-mĂȘmes sur le disque dur, nous devrons enregistrer manuellement les groupes de pĂ©riphĂ©riques individuels dans les cartes CRUSH.
  • MalgrĂ© le fait que rook-ceph-operator est considĂ©rĂ© comme stable, il existe actuellement certains problĂšmes lors de la mise Ă  jour de Ceph de la version 13 Ă  14.

Conclusions


"Maintenant Rook est fermĂ©e du monde extĂ©rieur par des pions, mais nous pensons qu'un jour elle jouera un rĂŽle dĂ©cisif dans la fĂȘte!" (une citation a Ă©tĂ© inventĂ©e spĂ©cifiquement pour cet article)

Le projet Rook a sans aucun doute gagnĂ© nos cƓurs - nous pensons que [avec tous ses avantages et ses inconvĂ©nients] il mĂ©rite vraiment votre attention.

Nos projets ultérieurs consistent à faire de rook-ceph un module pour l' opérateur d' addons , ce qui rendra son utilisation dans nos nombreux clusters Kubernetes encore plus simple et plus pratique.

PS


Lisez aussi dans notre blog:

Source: https://habr.com/ru/post/fr451818/


All Articles