
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 ).
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: