2.2. Format d'emballage du cadre de l'opérateur


Ce guide décrit le format d'emballage pour les opérateurs pris en charge par Operator Lifecycle Manager (OLM) dans OpenShift Container Platform.

2.2.1. Format de l'offre groupée

Le bundle format pour les opérateurs est un format d'empaquetage introduit par le cadre des opérateurs. Pour améliorer l'évolutivité et permettre aux utilisateurs en amont d'héberger leurs propres catalogues, la spécification du format bundle simplifie la distribution des métadonnées des opérateurs.

Un Operator bundle représente une version unique d'un Operator. Les bundle manifests sur disque sont conteneurisés et expédiés en tant que bundle image, qui est une image de conteneur non rinçable qui stocke les manifestes Kubernetes et les métadonnées de l'opérateur. Le stockage et la distribution de l'image de bundle sont ensuite gérés à l'aide d'outils de conteneur existants tels que podman et docker et de registres de conteneurs tels que Quay.

Les métadonnées de l'opérateur peuvent inclure

  • Informations qui identifient l'opérateur, par exemple son nom et sa version.
  • Informations supplémentaires qui pilotent l'interface utilisateur, par exemple son icône et quelques exemples de ressources personnalisées (CR).
  • API requises et fournies.
  • Images liées.

Lors du chargement des manifestes dans la base de données du registre des opérateurs, les exigences suivantes sont validées :

  • La liasse doit avoir au moins un canal défini dans les annotations.
  • Chaque bundle a exactement une version de service de cluster (CSV).
  • Si un CSV possède une définition de ressource personnalisée (CRD), cette CRD doit exister dans l'ensemble.

2.2.1.1. Manifestes

Les manifestes de paquets font référence à un ensemble de manifestes Kubernetes qui définissent le déploiement et le modèle RBAC de l'opérateur.

Un bundle comprend un CSV par répertoire et généralement les CRD qui définissent les API propres au CSV dans son répertoire /manifests.

Exemple de présentation du format de la liasse

etcd
├── manifests
│   ├── etcdcluster.crd.yaml
│   └── etcdoperator.clusterserviceversion.yaml
│   └── secret.yaml
│   └── configmap.yaml
└── metadata
    └── annotations.yaml
    └── dependencies.yaml

Autres objets pris en charge

Les types d'objets suivants peuvent également être inclus de manière facultative dans le répertoire /manifests d'une liasse :

Types d'objets optionnels pris en charge

  • ClusterRole
  • ClusterRoleBinding
  • ConfigMap
  • ConsoleCLIDownload
  • ConsoleLink
  • ConsoleQuickStart
  • ConsoleYamlSample
  • PodDisruptionBudget
  • PriorityClass
  • PrometheusRule
  • Role
  • RoleBinding
  • Secret
  • Service
  • ServiceAccount
  • ServiceMonitor
  • VerticalPodAutoscaler

Lorsque ces objets facultatifs sont inclus dans une liasse, Operator Lifecycle Manager (OLM) peut les créer à partir de la liasse et gérer leur cycle de vie en même temps que le CSV :

Cycle de vie des objets optionnels

  • Lorsque le CSV est supprimé, OLM supprime l'objet facultatif.
  • Lorsque le CSV est mis à jour :

    • Si le nom de l'objet facultatif est le même, OLM le met à jour à sa place.
    • Si le nom de l'objet facultatif a changé entre les versions, OLM le supprime et le recrée.

2.2.1.2. Annotations

Une liasse comprend également un fichier annotations.yaml dans son répertoire /metadata. Ce fichier définit des données agrégées de plus haut niveau qui aident à décrire le format et les informations sur la manière dont l'offre groupée doit être ajoutée à un index d'offres groupées :

Exemple annotations.yaml

annotations:
  operators.operatorframework.io.bundle.mediatype.v1: "registry+v1" 1
  operators.operatorframework.io.bundle.manifests.v1: "manifests/" 2
  operators.operatorframework.io.bundle.metadata.v1: "metadata/" 3
  operators.operatorframework.io.bundle.package.v1: "test-operator" 4
  operators.operatorframework.io.bundle.channels.v1: "beta,stable" 5
  operators.operatorframework.io.bundle.channel.default.v1: "stable" 6

1
Le type de média ou le format du bundle de l'opérateur. Le format registry v1 signifie qu'il contient un CSV et les objets Kubernetes associés.
2
Le chemin dans l'image vers le répertoire qui contient les manifestes de l'opérateur. Cette étiquette est réservée pour une utilisation future et a pour valeur par défaut manifests/. La valeur manifests.v1 implique que la liasse contient des manifestes d'opérateurs.
3
Le chemin dans l'image vers le répertoire qui contient les fichiers de métadonnées sur la liasse. Cette étiquette est réservée pour une utilisation future et a actuellement pour valeur par défaut metadata/. La valeur metadata.v1 implique que cette liasse a des métadonnées d'opérateur.
4
Le nom du paquet de la liasse.
5
La liste des chaînes auxquelles l'offre groupée est abonnée lorsqu'elle est ajoutée à un registre d'opérateur.
6
Le canal par défaut auquel un opérateur doit être abonné lorsqu'il est installé à partir d'un registre.
Note

En cas de non-concordance, c'est le fichier annotations.yaml qui fait foi, car le registre des opérateurs sur le cluster qui s'appuie sur ces annotations n'a accès qu'à ce fichier.

2.2.1.3. Dépendances

Les dépendances d'un Opérateur sont listées dans un fichier dependencies.yaml dans le dossier metadata/ d'un bundle. Ce fichier est facultatif et n'est actuellement utilisé que pour spécifier les dépendances explicites de la version de l'opérateur.

La liste des dépendances contient un champ type pour chaque élément afin de spécifier de quel type de dépendance il s'agit. Les types de dépendances de l'opérateur suivants sont pris en charge :

olm.package
Ce type indique une dépendance pour une version spécifique de l'opérateur. Les informations sur la dépendance doivent inclure le nom du paquet et la version du paquet au format semver. Par exemple, vous pouvez spécifier une version exacte telle que 0.5.2 ou une plage de versions telle que >0.5.1.
olm.gvk
Avec ce type, l'auteur peut spécifier une dépendance avec des informations sur le groupe, la version et le type (GVK), de manière similaire à l'utilisation existante des CRD et des API dans un CSV. Il s'agit d'un chemin permettant aux auteurs d'opérateurs de consolider toutes les dépendances, API ou versions explicites, au même endroit.
olm.constraint
Ce type déclare des contraintes génériques sur des propriétés arbitraires de l'opérateur.

Dans l'exemple suivant, des dépendances sont spécifiées pour un opérateur Prometheus et des CRD etcd :

Exemple de fichier dependencies.yaml

dependencies:
  - type: olm.package
    value:
      packageName: prometheus
      version: ">0.27.0"
  - type: olm.gvk
    value:
      group: etcd.database.coreos.com
      kind: EtcdCluster
      version: v1beta2

2.2.1.4. À propos de l'interface de programmation opm

L'outil CLI opm est fourni par Operator Framework pour être utilisé avec le format Operator bundle. Cet outil vous permet de créer et de maintenir des catalogues d'opérateurs à partir d'une liste de bundles d'opérateurs qui sont similaires à des dépôts de logiciels. Le résultat est une image de conteneur qui peut être stockée dans un registre de conteneurs et ensuite installée sur un cluster.

Un catalogue contient une base de données de pointeurs vers le contenu du manifeste de l'opérateur qui peut être interrogé par le biais d'une API incluse qui est servie lorsque l'image du conteneur est exécutée. Sur OpenShift Container Platform, Operator Lifecycle Manager (OLM) peut référencer l'image dans une source de catalogue, définie par un objet CatalogSource, qui interroge l'image à intervalles réguliers pour permettre des mises à jour fréquentes des opérateurs installés sur le cluster.

  • Voir Outils CLI pour les étapes d'installation du CLI opm.

2.2.2. Catalogues basés sur des fichiers

File-based catalogs sont la dernière itération du format de catalogue dans Operator Lifecycle Manager (OLM). Il s'agit d'une évolution du format de base de données SQLite, basée sur du texte brut (JSON ou YAML) et une configuration déclarative, et il est entièrement rétrocompatible. L'objectif de ce format est de permettre l'édition, la composabilité et l'extensibilité du catalogue de l'opérateur.

Édition

Avec les catalogues basés sur des fichiers, les utilisateurs qui interagissent avec le contenu d'un catalogue sont en mesure d'apporter des modifications directes au format et de vérifier que ces modifications sont valides. Comme ce format est du JSON ou du YAML en texte brut, les responsables de catalogues peuvent facilement manipuler les métadonnées des catalogues à la main ou à l'aide d'outils JSON ou YAML largement connus et pris en charge, tels que l'interface de programmation (CLI) jq.

Cette possibilité de modification permet d'utiliser les fonctions suivantes et les extensions définies par l'utilisateur :

  • Promouvoir une offre existante auprès d'un nouveau canal
  • Changer le canal par défaut d'un paquet
  • Algorithmes personnalisés pour l'ajout, la mise à jour et la suppression des bords de mise à niveau
Composabilité

Les catalogues basés sur des fichiers sont stockés dans une hiérarchie de répertoires arbitraire, ce qui permet de composer des catalogues. Par exemple, considérons deux répertoires distincts de catalogues basés sur des fichiers : catalogA et catalogB. Un responsable de catalogue peut créer un nouveau catalogue combiné en créant un nouveau répertoire catalogC et en y copiant catalogA et catalogB.

Cette composabilité permet de créer des catalogues décentralisés. Le format permet aux auteurs d'opérateurs de maintenir des catalogues spécifiques aux opérateurs et aux mainteneurs de construire de manière triviale un catalogue composé de catalogues d'opérateurs individuels. Les catalogues basés sur des fichiers peuvent être composés en combinant plusieurs autres catalogues, en extrayant des sous-ensembles d'un catalogue ou en combinant ces deux méthodes.

Note

Les paquets en double et les paquets en double à l'intérieur d'un paquet ne sont pas autorisés. La commande opm validate renvoie une erreur si des doublons sont trouvés.

Étant donné que les auteurs d'opérateurs connaissent le mieux leur opérateur, ses dépendances et sa compatibilité avec les mises à jour, ils sont en mesure de maintenir leur propre catalogue spécifique à l'opérateur et de contrôler directement son contenu. Avec les catalogues basés sur des fichiers, les auteurs d'opérateurs sont responsables de la construction et de la maintenance de leurs paquets dans un catalogue. Les responsables des catalogues composites, cependant, ne sont responsables que de la conservation des paquets dans leur catalogue et de la publication du catalogue pour les utilisateurs.

Extensibilité

La spécification de catalogue basée sur les fichiers est une représentation de bas niveau d'un catalogue. Bien qu'il puisse être maintenu directement dans sa forme de bas niveau, les responsables de catalogues peuvent construire des extensions intéressantes qui peuvent être utilisées par leurs propres outils personnalisés pour effectuer n'importe quel nombre de mutations.

Par exemple, un outil pourrait traduire une API de haut niveau, telle que (mode=semver), en un format de catalogue de bas niveau, basé sur des fichiers, pour les bords de mise à niveau. Ou encore, un responsable de catalogue pourrait avoir besoin de personnaliser toutes les métadonnées des lots en ajoutant une nouvelle propriété aux lots qui répondent à certains critères.

Bien que cette extensibilité permette de développer des outils officiels supplémentaires au-dessus des API de bas niveau pour les futures versions d'OpenShift Container Platform, le principal avantage est que les mainteneurs de catalogues disposent également de cette capacité.

Important

À partir d'OpenShift Container Platform 4.11, le catalogue Operator fourni par Red Hat par défaut est publié dans le format de catalogue basé sur des fichiers. Les catalogues Operator fournis par Red Hat par défaut pour OpenShift Container Platform 4.6 à 4.10 sont publiés dans le format de base de données SQLite déprécié.

Les sous-commandes, drapeaux et fonctionnalités de opm liés au format de base de données SQLite sont également obsolètes et seront supprimés dans une prochaine version. Ces fonctionnalités sont toujours prises en charge et doivent être utilisées pour les catalogues qui utilisent le format de base de données SQLite obsolète.

La plupart des sous-commandes et des drapeaux de opm pour travailler avec le format de base de données SQLite, tels que opm index prune, ne fonctionnent pas avec le format de catalogue basé sur des fichiers. Pour plus d'informations sur l'utilisation des catalogues basés sur des fichiers, voir Gestion des catalogues personnalisés et Mise en miroir des images pour une installation déconnectée à l'aide du plugin oc-mirror.

2.2.2.1. Structure du répertoire

Les catalogues basés sur des fichiers peuvent être stockés et chargés à partir de systèmes de fichiers basés sur des répertoires. Le CLI de opm charge le catalogue en parcourant le répertoire racine et en revenant sur les sous-répertoires. Il tente de charger tous les fichiers qu'il trouve et échoue en cas d'erreur.

Les fichiers hors catalogue peuvent être ignorés à l'aide des fichiers .indexignore, qui obéissent aux mêmes règles que les fichiers .gitignore en ce qui concerne les motifs et la priorité.

Exemple de fichier .indexignore

# Ignore everything except non-object .json and .yaml files
**/*
!*.json
!*.yaml
**/objects/*.json
**/objects/*.yaml

Les responsables des catalogues ont la possibilité de choisir la disposition qu'ils souhaitent, mais il est recommandé de stocker les blobs de catalogue basés sur les fichiers de chaque paquet dans des sous-répertoires distincts. Chaque fichier individuel peut être au format JSON ou YAML ; il n'est pas nécessaire que tous les fichiers d'un catalogue utilisent le même format.

Structure de base recommandée

catalog
├── packageA
│   └── index.yaml
├── packageB
│   ├── .indexignore
│   ├── index.yaml
│   └── objects
│       └── packageB.v0.1.0.clusterserviceversion.yaml
└── packageC
    └── index.json

Cette structure recommandée a la propriété que chaque sous-répertoire de la hiérarchie des répertoires est un catalogue autonome, ce qui rend la composition, la découverte et la navigation dans le catalogue des opérations triviales du système de fichiers. Le catalogue peut également être inclus dans un catalogue parent en le copiant dans le répertoire racine du catalogue parent.

2.2.2.2. Schémas

Les catalogues basés sur des fichiers utilisent un format, basé sur la spécification du langage CUE, qui peut être étendu avec des schémas arbitraires. Le schéma CUE suivant ( _Meta ) définit le format auquel tous les blobs de catalogues basés sur des fichiers doivent adhérer :

_Meta schéma

_Meta: {
  // schema is required and must be a non-empty string
  schema: string & !=""

  // package is optional, but if it's defined, it must be a non-empty string
  package?: string & !=""

  // properties is optional, but if it's defined, it must be a list of 0 or more properties
  properties?: [... #Property]
}

#Property: {
  // type is required
  type: string & !=""

  // value is required, and it must not be null
  value: !=null
}

Note

Aucun des schémas CUE énumérés dans la présente spécification ne doit être considéré comme exhaustif. La commande opm validate comporte des validations supplémentaires qu'il est difficile, voire impossible, d'exprimer de manière concise dans le langage CUE.

Un catalogue Operator Lifecycle Manager (OLM) utilise actuellement trois schémas (olm.package, olm.channel, et olm.bundle), qui correspondent aux concepts existants de paquet et de liasse d'OLM.

Chaque paquet d'opérateurs d'un catalogue nécessite exactement un blob olm.package, au moins un blob olm.channel et un ou plusieurs blobs olm.bundle.

Note

Tous les schémas olm.* sont réservés aux schémas définis par OLM. Les schémas personnalisés doivent utiliser un préfixe unique, tel qu'un domaine dont vous êtes propriétaire.

2.2.2.2.1. schéma de l'olm.package

Le schéma olm.package définit les métadonnées d'un opérateur au niveau du paquet. Il s'agit de son nom, de sa description, de son canal par défaut et de son icône.

Exemple 2.1. olm.package schéma

#Package: {
  schema: "olm.package"

  // Package name
  name: string & !=""

  // A description of the package
  description?: string

  // The package's default channel
  defaultChannel: string & !=""

  // An optional icon
  icon?: {
    base64data: string
    mediatype:  string
  }
}
2.2.2.2.2. schéma olm.channel

Le schéma olm.channel définit un canal à l'intérieur d'un paquet, les entrées de paquet qui sont membres du canal et les bords de mise à niveau pour ces paquets.

Une liasse peut être incluse en tant qu'entrée dans plusieurs blobs olm.channel, mais elle ne peut avoir qu'une seule entrée par canal.

Il est possible que la valeur de remplacement d'une entrée fasse référence à un autre nom de paquet qui ne peut être trouvé dans ce catalogue ou dans un autre catalogue. Cependant, tous les autres invariants du canal doivent rester vrais, comme le fait qu'un canal n'ait pas plusieurs têtes.

Exemple 2.2. olm.channel schéma

#Channel: {
  schema: "olm.channel"
  package: string & !=""
  name: string & !=""
  entries: [...#ChannelEntry]
}

#ChannelEntry: {
  // name is required. It is the name of an `olm.bundle` that
  // is present in the channel.
  name: string & !=""

  // replaces is optional. It is the name of bundle that is replaced
  // by this entry. It does not have to be present in the entry list.
  replaces?: string & !=""

  // skips is optional. It is a list of bundle names that are skipped by
  // this entry. The skipped bundles do not have to be present in the
  // entry list.
  skips?: [...string & !=""]

  // skipRange is optional. It is the semver range of bundle versions
  // that are skipped by this entry.
  skipRange?: string & !=""
}
2.2.2.2.3. schéma olm.bundle

Exemple 2.3. olm.bundle schéma

#Bundle: {
  schema: "olm.bundle"
  package: string & !=""
  name: string & !=""
  image: string & !=""
  properties: [...#Property]
  relatedImages?: [...#RelatedImage]
}

#Property: {
  // type is required
  type: string & !=""

  // value is required, and it must not be null
  value: !=null
}

#RelatedImage: {
  // image is the image reference
  image: string & !=""

  // name is an optional descriptive name for an image that
  // helps identify its purpose in the context of the bundle
  name?: string & !=""
}

2.2.2.3. Propriétés

Les propriétés sont des éléments arbitraires de métadonnées qui peuvent être attachés à des schémas de catalogues basés sur des fichiers. Le champ type est une chaîne qui spécifie effectivement la signification sémantique et syntaxique du champ value. La valeur peut être n'importe quel JSON ou YAML arbitraire.

OLM définit une poignée de types de propriétés, en utilisant à nouveau le préfixe réservé olm.*.

2.2.2.3.1. propriété olm.package

La propriété olm.package définit le nom et la version du paquet. Il s'agit d'une propriété obligatoire pour les bundles, et il doit y avoir exactement une de ces propriétés. Le champ packageName doit correspondre au champ de première classe package de la liasse et le champ version doit être une version sémantique valide.

Exemple 2.4. olm.package propriété

#PropertyPackage: {
  type: "olm.package"
  value: {
    packageName: string & !=""
    version: string & !=""
  }
}
2.2.2.3.2. propriété olm.gvk

La propriété olm.gvk définit le groupe/la version/le type (GVK) d'une API Kubernetes fournie par ce bundle. Cette propriété est utilisée par OLM pour résoudre un bundle avec cette propriété en tant que dépendance pour d'autres bundles qui listent le même GVK comme API requise. Le GVK doit respecter les validations GVK de Kubernetes.

Exemple 2.5. olm.gvk propriété

#PropertyGVK: {
  type: "olm.gvk"
  value: {
    group: string & !=""
    version: string & !=""
    kind: string & !=""
  }
}
2.2.2.3.3. olm.package.required

La propriété olm.package.required définit le nom du package et la plage de versions d'un autre package requis par cette offre groupée. Pour chaque propriété de paquetage requise qu'une offre énumère, OLM s'assure qu'un opérateur est installé sur le cluster pour le paquetage répertorié et dans la plage de versions requise. Le champ versionRange doit être une plage de versions sémantiques (semver) valide.

Exemple 2.6. olm.package.required propriété

#PropertyPackageRequired: {
  type: "olm.package.required"
  value: {
    packageName: string & !=""
    versionRange: string & !=""
  }
}
2.2.2.3.4. olm.gvk.requis

La propriété olm.gvk.required définit le groupe/la version/le type (GVK) d'une API Kubernetes dont ce bundle a besoin. Pour chaque propriété GVK requise, OLM s'assure qu'il existe un opérateur installé sur le cluster qui la fournit. Le GVK doit respecter les validations GVK de Kubernetes.

Exemple 2.7. olm.gvk.required propriété

#PropertyGVKRequired: {
  type: "olm.gvk.required"
  value: {
    group: string & !=""
    version: string & !=""
    kind: string & !=""
  }
}

2.2.2.4. Exemple de catalogue

Avec les catalogues basés sur des fichiers, les responsables des catalogues peuvent se concentrer sur la curation et la compatibilité des opérateurs. Comme les auteurs d'opérateurs ont déjà produit des catalogues spécifiques pour leurs opérateurs, les responsables de catalogues peuvent construire leur catalogue en rendant chaque catalogue d'opérateur dans un sous-répertoire du répertoire racine du catalogue.

Il existe de nombreuses façons de créer un catalogue basé sur des fichiers ; les étapes suivantes décrivent une approche simple :

  1. Maintenir un seul fichier de configuration pour le catalogue, contenant des références d'images pour chaque opérateur du catalogue :

    Exemple de fichier de configuration de catalogue

    name: community-operators
    repo: quay.io/community-operators/catalog
    tag: latest
    references:
    - name: etcd-operator
      image: quay.io/etcd-operator/index@sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
    - name: prometheus-operator
      image: quay.io/prometheus-operator/index@sha256:e258d248fda94c63753607f7c4494ee0fcbe92f1a76bfdac795c9d84101eb317

  2. Exécuter un script qui analyse le fichier de configuration et crée un nouveau catalogue à partir de ses références :

    Exemple de script

    name=$(yq eval '.name' catalog.yaml)
    mkdir "$name"
    yq eval '.name + "/" + .references[].name' catalog.yaml | xargs mkdir
    for l in $(yq e '.name as $catalog | .references[] | .image + "|" + $catalog + "/" + .name + "/index.yaml"' catalog.yaml); do
      image=$(echo $l | cut -d'|' -f1)
      file=$(echo $l | cut -d'|' -f2)
      opm render "$image" > "$file"
    done
    opm alpha generate dockerfile "$name"
    indexImage=$(yq eval '.repo + ":" + .tag' catalog.yaml)
    docker build -t "$indexImage" -f "$name.Dockerfile" .
    docker push "$indexImage"

2.2.2.5. Lignes directrices

Les lignes directrices suivantes doivent être prises en compte lors de la gestion de catalogues basés sur des fichiers.

2.2.2.5.1. Paquets immuables

En ce qui concerne le gestionnaire du cycle de vie des opérateurs (OLM), il est généralement conseillé de considérer les images des liasses et leurs métadonnées comme immuables.

Si un bundle cassé a été poussé vers un catalogue, vous devez supposer qu'au moins un de vos utilisateurs a effectué une mise à niveau vers ce bundle. Sur la base de cette hypothèse, vous devez publier une autre liasse avec un bord de mise à niveau à partir de la liasse cassée pour vous assurer que les utilisateurs ayant installé la liasse cassée reçoivent une mise à niveau. OLM ne réinstallera pas une liasse installée si le contenu de cette liasse est mis à jour dans le catalogue.

Toutefois, dans certains cas, il est préférable de modifier les métadonnées du catalogue :

  • Promotion des canaux : Si vous avez déjà publié une offre groupée et que vous décidez par la suite de l'ajouter à un autre canal, vous pouvez ajouter une entrée pour votre offre groupée dans un autre blob olm.channel.
  • Nouveaux bords de mise à niveau : Si vous publiez une nouvelle version de l'offre groupée 1.2.z, par exemple 1.2.4, mais que 1.3.0 est déjà disponible, vous pouvez mettre à jour les métadonnées du catalogue pour 1.3.0 afin d'ignorer 1.2.4.
2.2.2.5.2. Contrôle des sources

Les métadonnées du catalogue doivent être stockées dans le contrôle de la source et considérées comme la source de vérité. Les mises à jour des images du catalogue doivent comprendre les étapes suivantes :

  1. Mettre à jour le répertoire du catalogue contrôlé par la source avec un nouveau commit.
  2. Construire et pousser l'image du catalogue. Utilisez une taxonomie d'étiquetage cohérente, telle que :latest ou :<target_cluster_version>, afin que les utilisateurs puissent recevoir les mises à jour d'un catalogue au fur et à mesure qu'elles sont disponibles.

2.2.2.6. Utilisation du CLI

Pour obtenir des instructions sur la création de catalogues basés sur des fichiers à l'aide de l'interface CLI de opm, reportez-vous à la section Gestion des catalogues personnalisés.

Pour obtenir une documentation de référence sur les commandes CLI de opm relatives à la gestion des catalogues basés sur des fichiers, voir Outils CLI.

2.2.2.7. Automatisation

Les auteurs d'opérateurs et les responsables de catalogues sont encouragés à automatiser la maintenance de leurs catalogues avec des flux de travail CI/CD. Les mainteneurs de catalogues peuvent encore améliorer cela en construisant une automatisation GitOps pour accomplir les tâches suivantes :

  • Vérifier que les auteurs de demandes d'extraction (PR) sont autorisés à effectuer les modifications demandées, par exemple en mettant à jour la référence de l'image de leur paquet.
  • Vérifiez que les mises à jour du catalogue passent la commande opm validate.
  • Vérifiez que les références du bundle ou de l'image de catalogue mis à jour existent, que les images de catalogue s'exécutent correctement dans un cluster et que les opérateurs de ce package peuvent être installés avec succès.
  • Fusionner automatiquement les RP qui ont passé les contrôles précédents.
  • Reconstruire et republier automatiquement l'image du catalogue.

2.2.3. RukPak (aperçu technologique)

Important

RukPak est une fonctionnalité d'aperçu technologique uniquement. Les fonctionnalités de l'aperçu technologique ne sont pas prises en charge par les accords de niveau de service (SLA) de production de Red Hat et peuvent ne pas être complètes sur le plan fonctionnel. Red Hat ne recommande pas de les utiliser en production. Ces fonctionnalités offrent un accès anticipé aux fonctionnalités des produits à venir, ce qui permet aux clients de tester les fonctionnalités et de fournir un retour d'information pendant le processus de développement.

Pour plus d'informations sur la portée de l'assistance des fonctionnalités de l'aperçu technologique de Red Hat, voir Portée de l'assistance des fonctionnalités de l'aperçu technologique.

OpenShift Container Platform 4.12 introduit le type platform Operator en tant que fonctionnalité d'aperçu technologique. Le mécanisme de la plateforme Operator s'appuie sur le composant RukPak, également introduit dans OpenShift Container Platform 4.12, et ses ressources pour gérer le contenu.

RukPak se compose d'une série de contrôleurs, appelés provisioners, qui installent et gèrent le contenu sur un cluster Kubernetes. RukPak fournit également deux API principales : Bundle et BundleDeployment. Ces composants travaillent ensemble pour apporter du contenu sur le cluster et l'installer, en générant des ressources au sein du cluster.

Un provisionneur place une surveillance sur les ressources Bundle et BundleDeployment qui font explicitement référence au provisionneur. Pour un ensemble donné, le provisionneur décompresse le contenu de la ressource Bundle sur le cluster. Ensuite, lorsqu'une ressource BundleDeployment fait référence à cet ensemble, le provisionneur installe le contenu de l'ensemble et est responsable de la gestion du cycle de vie de ces ressources.

Deux provisionneurs sont actuellement mis en œuvre et fournis avec RukPak : le plain provisioner qui source et décompresse les paquets plain v0, et le registry provisioner qui source et décompresse les paquets Operator Lifecycle Manager (OLM) registry v1.

2.2.3.1. L'offre groupée

Un objet RukPak Bundle représente un contenu à mettre à la disposition d'autres consommateurs dans le cluster. Tout comme le contenu d'une image de conteneur doit être extrait et décompressé pour que le pod puisse commencer à l'utiliser, les objets Bundle sont utilisés pour référencer le contenu qui pourrait avoir besoin d'être extrait et décompressé. En ce sens, un bundle est une généralisation du concept d'image et peut être utilisé pour représenter n'importe quel type de contenu.

Les paquets ne peuvent rien faire par eux-mêmes ; ils ont besoin d'un provisionneur pour décompresser et rendre leur contenu disponible dans le cluster. Ils peuvent être décompressés sur n'importe quel support de stockage arbitraire, tel qu'un fichier tar.gz dans un répertoire monté dans les pods du provisionneur. Chaque objet Bundle est associé à un champ spec.provisionerClassName qui indique l'objet Provisioner qui surveille et décompresse ce type de paquet particulier.

Exemple Bundle objet configuré pour fonctionner avec le provisionneur ordinaire

apiVersion: core.rukpak.io/v1alpha1
kind: Bundle
metadata:
  name: my-bundle
spec:
  source:
    type: image
    image:
      ref: my-bundle@sha256:xyz123
  provisionerClassName: core-rukpak-io-plain

Note

Les paquets sont considérés comme immuables après leur création.

2.2.3.1.1. Immutabilité de l'offre groupée

Une fois qu'un objet Bundle est accepté par le serveur API, l'ensemble est considéré comme un artefact immuable par le reste du système RukPak. Ce comportement renforce la notion qu'un bundle représente un élément de contenu unique et statique à introduire dans le cluster. Un utilisateur peut être certain qu'un bundle particulier pointe vers un ensemble spécifique de manifestes et qu'il ne peut être mis à jour sans créer un nouveau bundle. Cette propriété s'applique aussi bien aux bundles autonomes qu'aux bundles dynamiques créés par un objet BundleTemplate intégré.

L'immuabilité de l'ensemble est assurée par le webhook principal de RukPak. Ce webhook surveille les événements de l'objet Bundle et, pour toute mise à jour d'une liasse, vérifie si le champ spec de la liasse existante est sémantiquement égal à celui de la liasse mise à jour proposée. Si ce n'est pas le cas, la mise à jour est rejetée par le webhook. D'autres champs de l'objet Bundle, tels que metadata ou status, sont mis à jour au cours du cycle de vie de l'offre groupée ; seul le champ spec est considéré comme immuable.

L'application d'un objet Bundle et la tentative de mise à jour de sa spécification devraient échouer. Par exemple, l'exemple suivant crée un bundle :

$ oc apply -f -<<EOF
apiVersion: core.rukpak.io/v1alpha1
kind: Bundle
metadata:
  name: combo-tag-ref
spec:
  source:
    type: git
    git:
      ref:
        tag: v0.0.2
      repository: https://github.com/operator-framework/combo
  provisionerClassName: core-rukpak-io-plain
EOF

Exemple de sortie

bundle.core.rukpak.io/combo-tag-ref created

Ensuite, l'application d'un correctif à la liasse pour qu'elle pointe vers une balise plus récente renvoie une erreur :

$ oc patch bundle combo-tag-ref --type='merge' -p '{"spec":{"source":{"git":{"ref":{"tag":"v0.0.3"}}}}}'

Exemple de sortie

Error from server (bundle.spec is immutable): admission webhook "vbundles.core.rukpak.io" denied the request: bundle.spec is immutable

Le webhook d'admission du noyau RukPak a rejeté le correctif parce que la spécification de l'ensemble est immuable. La méthode recommandée pour modifier le contenu d'une liasse consiste à créer un nouvel objet Bundle au lieu de le mettre à jour sur place.

Autres considérations sur l'immutabilité

Bien que le champ spec de l'objet Bundle soit immuable, il est toujours possible pour un objet BundleDeployment de pivoter vers une version plus récente du contenu de la liasse sans modifier le champ spec sous-jacent. Ce pivotement involontaire pourrait se produire dans le scénario suivant :

  1. Un utilisateur définit une étiquette d'image, une branche Git ou une étiquette Git dans le champ spec.source de l'objet Bundle.
  2. La balise image est déplacée vers un nouveau résumé, un utilisateur apporte des modifications à une branche Git, ou un utilisateur supprime et repousse une balise Git sur un commit différent.
  3. Un utilisateur fait quelque chose qui entraîne la recréation du pod d'unpackage du bundle, comme la suppression du pod d'unpackage.

Si ce scénario se produit, le nouveau contenu de l'étape 2 est décompressé à la suite de l'étape 3. Le déploiement de l'offre groupée détecte les modifications et passe à la version la plus récente du contenu.

Ceci est similaire au comportement d'un pod, où l'une des images de conteneur du pod utilise une balise, la balise est déplacée vers un digest différent, puis à un moment donné dans le futur, le pod existant est reprogrammé sur un nœud différent. À ce moment-là, le nœud extrait la nouvelle image du nouveau résumé et exécute quelque chose de différent sans que l'utilisateur ne le demande explicitement.

Pour être sûr que le contenu sous-jacent de la spécification Bundle ne change pas, utilisez une image basée sur un condensé ou une référence à un commit Git lors de la création de l'offre groupée.

2.2.3.1.2. Paquet simple spec

Un bundle simple dans RukPak est une collection de manifestes YAML Kubernetes statiques et arbitraires dans un répertoire donné.

Le format de liasse simple actuellement mis en œuvre est le format plain v0. Le nom du format de liasse, plain v0, combine le type de liasse (plain) et la version actuelle du schéma (v0).

Note

Le format de la liasse plain v0 est à la version de schéma v0, ce qui signifie qu'il s'agit d'un format expérimental susceptible d'être modifié.

Par exemple, l'illustration suivante montre l'arborescence des fichiers d'un bundle plain v0. Il doit comporter un répertoire manifests/ contenant les ressources Kubernetes nécessaires au déploiement d'une application.

Exemple plain v0 Arborescence des fichiers de la liasse

manifests
├── namespace.yaml
├── cluster_role.yaml
├── role.yaml
├── serviceaccount.yaml
├── cluster_role_binding.yaml
├── role_binding.yaml
└── deployment.yaml

Les manifestes statiques doivent se trouver dans le répertoire manifests/ et contenir au moins une ressource pour que le bundle soit un bundle plain v0 valide que le provisionneur peut décompresser. Le répertoire manifests/ doit également être plat ; tous les manifestes doivent se trouver au niveau supérieur, sans sous-répertoire.

Important

N'incluez pas de contenu dans le répertoire manifests/ d'un paquet ordinaire qui ne soit pas un manifeste statique. Sinon, un échec se produira lors de la création de contenu sur le cluster à partir de ce bundle. Tout fichier qui ne s'appliquerait pas avec succès avec la commande oc apply entraînera une erreur. Les fichiers YAML ou JSON multi-objets sont également valides.

2.2.3.1.3. Spécification de la liasse de registres

Un bundle de registre, ou registry v1 bundle, contient un ensemble de manifestes YAML Kubernetes statiques organisés dans l'ancien format de bundle Operator Lifecycle Manager (OLM).

Ressources supplémentaires

2.2.3.2. Déploiement groupé

Avertissement

Un objet BundleDeployment modifie l'état d'un cluster Kubernetes en installant et en supprimant des objets. Il est important de vérifier et de faire confiance au contenu qui est installé et de limiter l'accès à l'API BundleDeployment, à l'aide d'un système RBAC, aux seules personnes qui ont besoin de ces autorisations.

L'API RukPak BundleDeployment pointe vers un objet Bundle et indique qu'il doit être actif. Cela permet notamment de pivoter à partir d'anciennes versions d'un ensemble actif. Un objet BundleDeployment peut également inclure une spécification intégrée pour un ensemble souhaité.

Tout comme les pods génèrent des instances d'images de conteneurs, un déploiement de bundle génère une version déployée d'un bundle. Le déploiement d'un bundle peut être considéré comme une généralisation du concept de pod.

Les spécificités de la manière dont un déploiement de bundle apporte des modifications à un cluster basé sur un bundle référencé sont définies par le provisionneur qui est configuré pour surveiller ce déploiement de bundle.

Exemple BundleDeployment objet configuré pour fonctionner avec le provisionneur ordinaire

apiVersion: core.rukpak.io/v1alpha1
kind: BundleDeployment
metadata:
  name: my-bundle-deployment
spec:
  provisionerClassName: core-rukpak-io-plain
  template:
    metadata:
      labels:
        app: my-bundle
    spec:
      source:
        type: image
        image:
          ref: my-bundle@sha256:xyz123
      provisionerClassName: core-rukpak-io-plain

2.2.3.3. Provisionneur

Un provisionneur RukPak est un contrôleur qui comprend les API BundleDeployment et Bundle et peut prendre des mesures. Chaque provisionneur se voit attribuer un identifiant unique et est chargé de rapprocher les objets Bundle et BundleDeployment avec un champ spec.provisionerClassName correspondant à cet identifiant particulier.

Par exemple, le "plain provisioner" est capable de décompresser un paquet plain v0 donné sur un cluster et de l'instancier, rendant ainsi le contenu du paquet disponible dans le cluster.

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.