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 valeurmanifests.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 valeurmetadata.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.
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
Ressources supplémentaires
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
etcatalogB
. Un responsable de catalogue peut créer un nouveau catalogue combiné en créant un nouveau répertoirecatalogC
et en y copiantcatalogA
etcatalogB
.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.
NoteLes 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é.
À 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 }
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
.
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 :
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
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 exemple1.2.4
, mais que1.3.0
est déjà disponible, vous pouvez mettre à jour les métadonnées du catalogue pour1.3.0
afin d'ignorer1.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 :
- Mettre à jour le répertoire du catalogue contrôlé par la source avec un nouveau commit.
-
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)
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
.
Ressources supplémentaires
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
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 :
-
Un utilisateur définit une étiquette d'image, une branche Git ou une étiquette Git dans le champ
spec.source
de l'objetBundle
. - 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.
- 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
).
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.
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é
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.