Rechercher

6.8. Lier les charges de travail à l'aide de l'opérateur de liaison de services

download PDF

Les développeurs d'applications doivent lier une charge de travail à un ou plusieurs services d'appui en utilisant un secret de liaison. Ce secret est généré dans le but de stocker des informations qui seront consommées par la charge de travail.

Prenons l'exemple d'un service auquel vous souhaitez vous connecter et qui expose déjà les données de liaison. Dans ce cas, vous aurez également besoin d'une charge de travail à utiliser avec la ressource personnalisée (CR) ServiceBinding. En utilisant cette CR ServiceBinding, la charge de travail envoie une demande de liaison avec les détails des services à lier.

Exemple de ServiceBinding CR

apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
    name: spring-petclinic-pgcluster
    namespace: my-petclinic
spec:
    services: 1
    - group: postgres-operator.crunchydata.com
      version: v1beta1
      kind: PostgresCluster
      name: hippo
    application: 2
      name: spring-petclinic
      group: apps
      version: v1
      resource: deployments

1
Spécifie une liste de ressources de service.
2
L'exemple d'application qui pointe vers un déploiement ou toute autre ressource similaire avec une PodSpec intégrée.

Comme le montre l'exemple précédent, vous pouvez également utiliser directement un site ConfigMap ou un site Secret en tant que ressource de service à utiliser comme source de données de liaison.

6.8.1. Stratégies de dénomination

Les stratégies de dénomination ne sont disponibles que pour le groupe binding.operators.coreos.com API.

Les stratégies de nommage utilisent les modèles Go pour vous aider à définir des noms de liaison personnalisés par le biais de la demande de liaison de service. Les stratégies de dénomination s'appliquent à tous les attributs, y compris les correspondances dans la ressource personnalisée (CR) ServiceBinding.

Un service d'appui projette les noms de liaison sous forme de fichiers ou de variables d'environnement dans la charge de travail. Si une charge de travail attend les noms de liaison projetés dans un format particulier, mais que les noms de liaison à projeter à partir du service d'appui ne sont pas disponibles dans ce format, vous pouvez modifier les noms de liaison à l'aide de stratégies d'attribution de noms.

Fonctions de post-traitement prédéfinies

Lors de l'utilisation des stratégies de dénomination, en fonction des attentes ou des exigences de votre charge de travail, vous pouvez utiliser les fonctions de post-traitement prédéfinies suivantes, dans n'importe quelle combinaison, pour convertir les chaînes de caractères :

  • upper: Convertit les chaînes de caractères en lettres capitales ou majuscules.
  • lower: Convertit les chaînes de caractères en lettres minuscules.
  • title: Convertit les chaînes de caractères où la première lettre de chaque mot est en majuscule, à l'exception de certains mots mineurs.

Stratégies de dénomination prédéfinies

Les noms de liens déclarés par le biais d'annotations sont traités pour leur changement de nom avant leur projection dans la charge de travail selon les stratégies de dénomination prédéfinies suivantes :

  • none: Lorsqu'il est appliqué, il n'y a pas de changement dans les noms des liaisons.

    Exemple

    Après la compilation du modèle, les noms de la liaison prennent la forme {{ .name }}.

    host: hippo-pgbouncer
    port: 5432
  • upper: Appliqué lorsqu'aucun namingStrategy n'est défini. Lorsqu'il est appliqué, il convertit toutes les chaînes de caractères de la clé du nom de la liaison en lettres capitales ou majuscules.

    Exemple

    Après la compilation du modèle, les noms des liens prennent la forme {{ .service.kind | upper}}_{{ .name | upper }}.

    DATABASE_HOST: hippo-pgbouncer
    DATABASE_PORT: 5432

    Si votre charge de travail nécessite un format différent, vous pouvez définir une stratégie de dénomination personnalisée et modifier le nom de la liaison à l'aide d'un préfixe et d'un séparateur, par exemple PORT_DATABASE.

Note
  • Lorsque les noms des liens sont projetés sous forme de fichiers, la stratégie de dénomination prédéfinie none est appliquée par défaut et les noms des liens ne changent pas.
  • Lorsque les noms des liens sont projetés en tant que variables d'environnement et qu'aucun namingStrategy n'est défini, la stratégie de dénomination prédéfinie uppercase est appliquée par défaut.
  • Vous pouvez remplacer les stratégies de dénomination prédéfinies en définissant des stratégies de dénomination personnalisées utilisant différentes combinaisons de noms de liaison personnalisés et de fonctions de post-traitement prédéfinies.

6.8.2. Options de reliure avancées

Vous pouvez définir la ressource personnalisée (CR) ServiceBinding pour qu'elle utilise les options de liaison avancées suivantes :

  • Modifier les noms des liens : Cette option n'est disponible que pour le groupe binding.operators.coreos.com API.
  • Composer des données de liaison personnalisées : Cette option n'est disponible que pour le groupe binding.operators.coreos.com API.
  • Lier les charges de travail à l'aide de sélecteurs d'étiquettes : Cette option est disponible pour les groupes d'API binding.operators.coreos.com et servicebinding.io.

6.8.2.1. Modifier les noms des liaisons avant de les projeter dans la charge de travail

Vous pouvez spécifier les règles de modification des noms de liaison dans l'attribut .spec.namingStrategy du CR ServiceBinding. Par exemple, considérons un exemple d'application Spring PetClinic qui se connecte à la base de données PostgreSQL. Dans ce cas, le service de base de données PostgreSQL expose les champs host et port de la base de données à utiliser pour la liaison. L'exemple d'application Spring PetClinic peut accéder à ces données de liaison exposées par le biais des noms de liaison.

Exemple : Exemple d'application Spring PetClinic sur le site ServiceBinding CR

...
    application:
      name: spring-petclinic
      group: apps
      version: v1
      resource: deployments
...

Exemple : Service de base de données PostgreSQL dans le CR ServiceBinding

...
    services:
    - group: postgres-operator.crunchydata.com
      version: v1beta1
      kind: PostgresCluster
      name: hippo
...

Si namingStrategy n'est pas défini et que les noms des liens sont projetés en tant que variables d'environnement, la valeur host: hippo-pgbouncer dans le service d'appui et la variable d'environnement projetée apparaîtront comme indiqué dans l'exemple suivant :

Exemple

DATABASE_HOST: hippo-pgbouncer

où :

DATABASE

Spécifie le service backend kind.

HOST

Spécifie le nom de la liaison.

Après avoir appliqué la stratégie de nommage POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV, la liste des noms de liaison personnalisés préparée par la demande de liaison de service apparaît comme le montre l'exemple suivant :

Exemple

POSTGRESQL_DATABASE_HOST_ENV: hippo-pgbouncer
POSTGRESQL_DATABASE_PORT_ENV: 5432

Les éléments suivants décrivent les expressions définies dans la stratégie de dénomination POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV:

  • .name: Fait référence au nom de la liaison exposée par le service d'appui. Dans l'exemple précédent, les noms de liaison sont HOST et PORT.
  • .service.kind: Désigne le type de ressource de service dont les noms de liaison sont modifiés par la stratégie de dénomination.
  • upper: Fonction de chaîne utilisée pour post-traiter la chaîne de caractères lors de la compilation de la chaîne du modèle Go.
  • POSTGRESQL: Préfixe du nom de la liaison personnalisée.
  • ENV: Suffixe du nom de la liaison personnalisée.

Comme dans l'exemple précédent, vous pouvez définir les modèles de chaînes dans namingStrategy pour définir comment chaque clé des noms de liaison doit être préparée par la demande de liaison de service.

6.8.2.2. Composer des données de liaison personnalisées

En tant que développeur d'applications, vous pouvez composer des données de liaison personnalisées dans les circonstances suivantes :

  • Le service de soutien n'expose pas les données de liaison.
  • Les valeurs exposées ne sont pas disponibles dans le format requis par la charge de travail.

Par exemple, considérons un cas où le service de soutien CR expose l'hôte, le port et l'utilisateur de la base de données en tant que données de liaison, mais la charge de travail exige que les données de liaison soient consommées en tant que chaîne de connexion. Vous pouvez composer des données de liaison personnalisées à l'aide d'attributs dans la ressource Kubernetes représentant le service d'appui.

Exemple

apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
    name: spring-petclinic-pgcluster
    namespace: my-petclinic
spec:
    services:
    - group: postgres-operator.crunchydata.com
      version: v1beta1
      kind: PostgresCluster
      name: hippo 1
      id: postgresDB 2
    - group: ""
      version: v1
      kind: Secret
      name: hippo-pguser-hippo
      id: postgresSecret
    application:
      name: spring-petclinic
      group: apps
      version: v1
      resource: deployments
    mappings:
      ## From the database service
      - name: JDBC_URL
        value: 'jdbc:postgresql://{{ .postgresDB.metadata.annotations.proxy }}:{{ .postgresDB.spec.port }}/{{ .postgresDB.metadata.name }}'
      ## From both the services!
      - name: CREDENTIALS
        value: '{{ .postgresDB.metadata.name }}{{ translationService.postgresSecret.data.password }}'
      ## Generate JSON
      - name: DB_JSON 3
        value: {{ json .postgresDB.status }} 4

1
Nom de la ressource du service de soutien.
2
Identifiant facultatif.
3
Nom JSON généré par le Service Binding Operator. Le Service Binding Operator projette ce nom JSON comme le nom d'un fichier ou d'une variable d'environnement.
4
Valeur JSON générée par l'opérateur de liaison de services. Le Service Binding Operator projette cette valeur JSON dans un fichier ou une variable d'environnement. La valeur JSON contient les attributs du champ spécifié de la ressource personnalisée du service d'appui.

6.8.2.3. Lier les charges de travail à l'aide d'un sélecteur d'étiquettes

Vous pouvez utiliser un sélecteur d'étiquettes pour spécifier la charge de travail à lier. Si vous déclarez une liaison de service en utilisant les sélecteurs d'étiquettes pour récupérer des charges de travail, l'opérateur de liaison de service tente périodiquement de trouver et de lier de nouvelles charges de travail qui correspondent au sélecteur d'étiquettes donné.

Par exemple, en tant qu'administrateur de cluster, vous pouvez lier un service à chaque Deployment dans un espace de noms avec l'étiquette environment: production en définissant un champ labelSelector approprié dans le CR ServiceBinding. Cela permet à l'opérateur de liaison de services de lier chacune de ces charges de travail à un CR ServiceBinding.

Exemple ServiceBinding CR dans l'API binding.operators.coreos.com/v1alpha1

apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
  name: multi-application-binding
  namespace: service-binding-demo
spec:
  application:
    labelSelector: 1
      matchLabels:
        environment: production
    group: apps
    version: v1
    resource: deployments
  services:
    group: ""
    version: v1
    kind: Secret
    name: super-secret-data

1
Spécifie la charge de travail qui est liée.

Exemple ServiceBinding CR dans l'API servicebinding.io

apiVersion: servicebindings.io/v1beta1
kind: ServiceBinding
metadata:
  name: multi-application-binding
  namespace: service-binding-demo
spec:
  workload:
    selector: 1
      matchLabels:
        environment: production
    apiVersion: app/v1
    kind: Deployment
  service:
    apiVersion: v1
    kind: Secret
    name: super-secret-data

1
Spécifie la charge de travail qui est liée.
Important

Si vous définissez les paires de champs suivantes, Service Binding Operator refuse l'opération de liaison et génère une erreur :

  • Les champs name et labelSelector dans l'API binding.operators.coreos.com/v1alpha1.
  • Les champs name et selector dans l'API servicebinding.io (Spec API).

Comprendre le comportement du rebinding

Prenons le cas où, après une liaison réussie, vous utilisez le champ name pour identifier une charge de travail. Si vous supprimez et recréez cette charge de travail, l'outil de réconciliation ServiceBinding ne lie pas à nouveau la charge de travail et l'opérateur ne peut pas projeter les données de liaison sur la charge de travail. Toutefois, si vous utilisez le champ labelSelector pour identifier une charge de travail, le programme de rapprochement ServiceBinding lie à nouveau la charge de travail et l'opérateur projette les données de liaison.

6.8.3. Lier des charges de travail secondaires qui ne sont pas conformes à PodSpec

Un scénario typique de liaison de service implique la configuration du service de soutien, de la charge de travail (déploiement) et de l'opérateur de liaison de service. Considérons un scénario impliquant une charge de travail secondaire (qui peut également être un opérateur d'application) qui n'est pas conforme à PodSpec et qui se trouve entre la charge de travail principale (déploiement) et l'opérateur de liaison de service.

Pour ces ressources de charge de travail secondaire, l'emplacement du chemin d'accès au conteneur est arbitraire. Pour la liaison de service, si la charge de travail secondaire d'une CR n'est pas conforme à la PodSpec, vous devez spécifier l'emplacement du chemin du conteneur. Cela permet de projeter les données de liaison dans le chemin du conteneur spécifié dans la charge de travail secondaire de la ressource personnalisée (CR) ServiceBinding, par exemple lorsque vous ne voulez pas que les données de liaison se trouvent dans un pod.

Dans Service Binding Operator, vous pouvez configurer le chemin d'accès des conteneurs ou des secrets au sein d'une charge de travail et lier ces chemins d'accès à un emplacement personnalisé.

6.8.3.1. Configuration de l'emplacement personnalisé du chemin d'accès au conteneur

Cet emplacement personnalisé est disponible pour le groupe API binding.operators.coreos.com lorsque Service Binding Operator projette les données de liaison en tant que variables d'environnement.

Considérons une charge de travail secondaire CR, qui n'est pas conforme à la PodSpec et dont les conteneurs sont situés sur le chemin spec.containers:

Exemple : Charge de travail secondaire CR

apiVersion: "operator.sbo.com/v1"
kind: SecondaryWorkload
metadata:
    name: secondary-workload
spec:
    containers:
    - name: hello-world
      image: quay.io/baijum/secondary-workload:latest
      ports:
      - containerPort: 8080

Procédure

  • Configurez le chemin d'accès spec.containers en spécifiant une valeur dans le CR ServiceBinding et liez ce chemin d'accès à un emplacement personnalisé spec.application.bindingPath.containersPath:

    Exemple : ServiceBinding CR avec le chemin d'accès spec.containers dans un emplacement personnalisé

    apiVersion: binding.operators.coreos.com/v1alpha1
    kind: ServiceBinding
    metadata:
        name: spring-petclinic-pgcluster
    spec:
        services:
        - group: postgres-operator.crunchydata.com
          version: v1beta1
          kind: PostgresCluster
          name: hippo
          id: postgresDB
        - group: ""
          version: v1
          kind: Secret
          name: hippo-pguser-hippo
          id: postgresSecret
        application: 1
          name: spring-petclinic
          group: apps
          version: v1
          resource: deployments
        application: 2
          name: secondary-workload
          group: operator.sbo.com
          version: v1
          resource: secondaryworkloads
          bindingPath:
            containersPath: spec.containers 3

    1
    L'exemple d'application qui pointe vers un déploiement ou toute autre ressource similaire avec une PodSpec intégrée.
    2
    La charge de travail secondaire, qui n'est pas conforme à la PodSpec.
    3
    L'emplacement personnalisé du chemin d'accès au conteneur.

Après avoir spécifié l'emplacement du chemin du conteneur, Service Binding Operator génère les données de liaison, qui deviennent disponibles dans le chemin du conteneur spécifié dans la charge de travail secondaire de la CR ServiceBinding.

L'exemple suivant montre le chemin spec.containers avec les champs envFrom et secretRef:

Exemple : Charge de travail secondaire CR avec les champs envFrom et secretRef

apiVersion: "operator.sbo.com/v1"
kind: SecondaryWorkload
metadata:
    name: secondary-workload
spec:
    containers:
    - env: 1
      - name: ServiceBindingOperatorChangeTriggerEnvVar
        value: "31793"
      envFrom:
      - secretRef:
          name: secret-resource-name 2
      image: quay.io/baijum/secondary-workload:latest
      name: hello-world
      ports:
      - containerPort: 8080
      resources: {}

1
Tableau unique de conteneurs avec des valeurs générées par l'opérateur de liaison de service. Ces valeurs sont basées sur le service d'appui CR.
2
Nom de la ressource Secret générée par l'opérateur de liaison de services.

6.8.3.2. Configuration de l'emplacement personnalisé du chemin d'accès secret

Cet emplacement personnalisé est disponible pour le groupe API binding.operators.coreos.com lorsque Service Binding Operator projette les données de liaison en tant que variables d'environnement.

Considérons une charge de travail secondaire CR, qui n'est pas conforme à la PodSpec, avec seulement le secret sur le chemin spec.secret:

Exemple : Charge de travail secondaire CR

apiVersion: "operator.sbo.com/v1"
kind: SecondaryWorkload
metadata:
    name: secondary-workload
spec:
    secret: ""

Procédure

  • Configurer le chemin d'accès spec.secret en spécifiant une valeur dans le CR ServiceBinding et lier ce chemin d'accès à un emplacement personnalisé spec.application.bindingPath.secretPath:

    Exemple : ServiceBinding CR avec le chemin d'accès spec.secret dans un emplacement personnalisé

    apiVersion: binding.operators.coreos.com/v1alpha1
    kind: ServiceBinding
    metadata:
        name: spring-petclinic-pgcluster
    spec:
    ...
        application: 1
          name: secondary-workload
          group: operator.sbo.com
          version: v1
          resource: secondaryworkloads
          bindingPath:
            secretPath: spec.secret 2
    ...

    1
    La charge de travail secondaire, qui n'est pas conforme à la PodSpec.
    2
    L'emplacement personnalisé du chemin secret qui contient le nom de la ressource Secret.

Après avoir spécifié l'emplacement du chemin secret, Service Binding Operator génère les données de liaison, qui deviennent disponibles dans le chemin secret spécifié dans la charge de travail secondaire du CR ServiceBinding.

L'exemple suivant montre le chemin spec.secret avec la valeur binding-request:

Exemple : Charge de travail secondaire CR avec la valeur binding-request

...
apiVersion: "operator.sbo.com/v1"
kind: SecondaryWorkload
metadata:
    name: secondary-workload
spec:
    secret: binding-request-72ddc0c540ab3a290e138726940591debf14c581 1
...

1
Nom unique de la ressource Secret générée par le Service Binding Operator.

6.8.3.3. Cartographie des ressources de la charge de travail

Note
  • Le mappage des ressources de charge de travail est disponible pour les charges de travail secondaires de la ressource personnalisée (CR) ServiceBinding pour les deux groupes API : binding.operators.coreos.com et servicebinding.io.
  • Vous devez définir les ressources ClusterWorkloadResourceMapping uniquement dans le groupe d'API servicebinding.io. Cependant, les ressources ClusterWorkloadResourceMapping interagissent avec les ressources ServiceBinding sous les groupes d'API binding.operators.coreos.com et servicebinding.io.

Si vous ne pouvez pas configurer des emplacements de chemin d'accès personnalisés en utilisant la méthode de configuration du chemin d'accès du conteneur, vous pouvez définir exactement où les données de liaison doivent être projetées. Spécifiez où projeter les données de liaison pour un type de charge de travail donné en définissant les ressources ClusterWorkloadResourceMapping dans le groupe API servicebinding.io.

L'exemple suivant montre comment définir un mappage pour les ressources CronJob.batch/v1.

Exemple : Cartographie des ressources CronJob.batch/v1

apiVersion: servicebinding.io/v1beta1
kind: ClusterWorkloadResourceMapping
metadata:
 name: cronjobs.batch 1
spec:
  versions:
  - version: "v1" 2
    annotations: .spec.jobTemplate.spec.template.metadata.annotations 3
    containers:
    - path: .spec.jobTemplate.spec.template.spec.containers[*] 4
    - path: .spec.jobTemplate.spec.template.spec.initContainers[*]
      name: .name 5
      env: .env 6
      volumeMounts: .volumeMounts 7
    volumes: .spec.jobTemplate.spec.template.spec.volumes 8

1
Nom de la ressource ClusterWorkloadResourceMapping, qui doit être qualifié de plural.group de la ressource de charge de travail mappée.
2
Version de la ressource en cours de mappage. Toute version non spécifiée peut être remplacée par le caractère générique "*".
3
Facultatif : Identifiant du champ .annotations dans un pod, spécifié avec un JSONPath fixe. La valeur par défaut est .spec.template.spec.annotations.
4
Identifiant des champs .containers et .initContainers dans un module, spécifié par un chemin JSONPath. Si aucune entrée sous le champ containers n'est définie, l'opérateur de liaison de services utilise par défaut deux chemins : .spec.template.spec.containers[*] et .spec.template.spec.initContainers[\*], tous les autres champs étant définis par défaut. Toutefois, si vous spécifiez une entrée, vous devez définir le champ .path.
5
Facultatif : Identifiant du champ .name dans un conteneur, spécifié avec un chemin JSONPath fixe. La valeur par défaut est .name.
6
Facultatif : Identifiant du champ .env dans un conteneur, spécifié avec un chemin JSONPath fixe. La valeur par défaut est .env.
7
Facultatif : Identifiant du champ .volumeMounts dans un conteneur, spécifié avec un chemin JSONPath fixe. La valeur par défaut est .volumeMounts.
8
Facultatif : Identifiant du champ .volumes dans un pod, spécifié avec un JSONPath fixe. La valeur par défaut est .spec.template.spec.volumes.
Important
  • Dans ce contexte, un chemin JSONPath fixe est un sous-ensemble de la grammaire JSONPath qui n'accepte que les opérations suivantes :

    • Recherche de champ : .spec.template
    • Indexation des tableaux : .spec['template']

    Toutes les autres opérations ne sont pas acceptées.

  • La plupart de ces champs sont facultatifs. Lorsqu'ils ne sont pas spécifiés, l'opérateur de liaison de services prend des valeurs par défaut compatibles avec les ressources PodSpec.
  • L'opérateur de liaison de services exige que chacun de ces champs soit structurellement équivalent au champ correspondant dans un déploiement de pods. Par exemple, le contenu du champ .env dans une ressource de charge de travail doit pouvoir accepter la même structure de données que le champ .env dans une ressource Pod. Dans le cas contraire, la projection de données de liaison dans une telle charge de travail pourrait entraîner un comportement inattendu de la part de l'opérateur de liaison de services.

Comportement spécifique au groupe d'API binding.operators.coreos.com

Vous pouvez vous attendre aux comportements suivants lorsque les ressources ClusterWorkloadResourceMapping interagissent avec les ressources ServiceBinding dans le cadre du groupe API binding.operators.coreos.com:

  • Si une ressource ServiceBinding avec la valeur de l'indicateur bindAsFiles: false est créée avec l'un de ces mappages, les variables d'environnement sont projetées dans le champ .envFrom sous chaque champ path spécifié dans la ressource ClusterWorkloadResourceMapping correspondante.
  • En tant qu'administrateur de cluster, vous pouvez spécifier à la fois une ressource ClusterWorkloadResourceMapping et le champ .spec.application.bindingPath.containersPath dans une ressource ServiceBinding.bindings.coreos.com à des fins de liaison.

    L'opérateur de liaison de services tente de projeter les données de liaison dans les emplacements spécifiés à la fois dans une ressource ClusterWorkloadResourceMapping et dans le champ .spec.application.bindingPath.containersPath. Ce comportement équivaut à l'ajout d'une entrée de conteneur à la ressource ClusterWorkloadResourceMapping correspondante avec l'attribut path: $containersPath, toutes les autres valeurs prenant leur valeur par défaut.

6.8.4. Délier les charges de travail d'un service d'appui

Vous pouvez délier une charge de travail d'un service de soutien à l'aide de l'outil oc.

  • Pour délier une charge de travail d'un service d'appui, supprimez la ressource personnalisée (CR) ServiceBinding qui lui est liée :

    oc delete ServiceBinding <.metadata.name> $ oc delete ServiceBinding <.metadata.name>

    Exemple

    $ oc delete ServiceBinding spring-petclinic-pgcluster

    où :

    spring-petclinic-pgcluster

    Spécifie le nom du CR ServiceBinding.

6.8.5. Ressources complémentaires

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.