Déployer Ingress dans les clusters

Vous trouverez sur cette page la procédure pour déployer un objet Ingress qui diffuse une application sur plusieurs clusters GKE. Pour en savoir plus sur l'entrée multicluster, consultez la page Entrée multicluster.

Tutoriel sur le déploiement

Dans les tâches ci-dessous, vous allez déployer une application fictive nommée zoneprinter et Ingress multicluster dans deux clusters. L'objet Ingress fournit une adresse IP virtuelle (IPV) partagée pour les déploiements d'applications.

Cette page s'appuie sur le travail effectué sur la page Configurer Ingress multicluster, où vous avez créé et enregistré deux clusters. Vérifiez que vous disposez de deux clusters qui sont également enregistrés auprès d'un parc :

gcloud container clusters list

Le résultat ressemble à ce qui suit :

NAME    LOCATION        MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION     NUM_NODES  STATUS
gke-eu  europe-west1-c  1.16.8-gke.9    ***             e2-medium      1.16.8-gke.9     2          RUNNING
gke-us  us-central1-a   1.16.8-gke.9    ***             e2-medium      1.16.6-gke.13 *  2          RUNNING

Créer l'espace de noms

Comme les Fleet sont dotées de la propriété d'uniformité de l'espace de noms, nous vous recommandons de coordonner la création et la gestion des espaces de noms entre les clusters afin que les espaces de noms identiques soient détenus et gérés par le même groupe. Vous pouvez créer des espaces de noms par équipe, par environnement, par application ou par composant d'application. Les espaces de noms peuvent être aussi précis que nécessaire, à condition qu'un espace de noms ns1 dans un cluster ait la même signification et la même utilisation que ns1 dans un autre cluster.

Dans cet exemple, vous créez un espace de noms zoneprinter pour l'ensemble des applications dans chaque cluster.

  1. Créez un fichier nommé namespace.yaml ayant le contenu suivant :

    apiVersion: v1
    kind: Namespace
    metadata:
      name: zoneprinter
    
  2. Basculez vers le contexte gke-us :

    kubectl config use-context gke-us
    
  3. Créez l'espace de noms :

    kubectl apply -f namespace.yaml
    
  4. Basculez vers le contexte gke-eu :

    kubectl config use-context gke-eu
    
  5. Créez l'espace de noms :

    kubectl apply -f namespace.yaml
    

    Le résultat ressemble à ce qui suit :

    namespace/zoneprinter created
    

Déployer l'application

  1. Créez un fichier nommé deploy.yaml ayant le contenu suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: zone-ingress
      namespace: zoneprinter
      labels:
        app: zoneprinter
    spec:
      selector:
        matchLabels:
          app: zoneprinter
      template:
        metadata:
          labels:
            app: zoneprinter
        spec:
          containers:
          - name: frontend
            image: gcr.io/google-samples/zone-printer:0.2
            ports:
            - containerPort: 8080
    
  2. Basculez vers le contexte gke-us :

    kubectl config use-context gke-us
    
  3. Déployez l'application zoneprinter :

    kubectl apply -f deploy.yaml
    
  4. Basculez vers le contexte gke-eu :

    kubectl config use-context gke-eu
    
  5. Déployez l'application zoneprinter :

    kubectl apply -f deploy.yaml
    
  6. Vérifiez que l'application zoneprinter a bien été déployée dans chaque cluster :

    kubectl get deployment --namespace zoneprinter
    

    Le résultat des deux clusters est semblable à ce qui suit :

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    zone-ingress   1/1     1            1           12m
    

Effectuer le déploiement à l'aide du cluster de configuration

Maintenant que l'application est déployée sur gke-us et gke-eu, vous allez déployer un équilibreur de charge en déployant des ressources MultiClusterIngress (MCI) et MultiClusterService (MCS) dans le cluster de configuration. MCI et MCS sont des ressources personnalisées (CRD) multicluster équivalentes aux ressources Ingress et Service.

Dans le guide de configuration, vous avez défini le cluster gke-us comme cluster de configuration. Le cluster de configuration permet de déployer et de configurer des objets Ingress dans tous les clusters.

  1. Définissez le contexte du cluster de configuration.

    kubectl config use-context gke-us
    

MultiClusterService

  1. Créez un fichier nommé mcs.yaml ayant le contenu suivant :

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: zone-mcs
      namespace: zoneprinter
    spec:
      template:
        spec:
          selector:
            app: zoneprinter
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    
  2. Déployez la ressource MultiClusterService correspondant à l'application zoneprinter :

    kubectl apply -f mcs.yaml
    
  3. Vérifiez que la ressource zone-mcs a bien été déployée dans le cluster de configuration :

    kubectl get mcs -n zoneprinter
    

    Le résultat ressemble à ce qui suit :

    NAME       AGE
    zone-mcs   9m26s
    

    Cette ressource MCS crée un service dérivé sans adresse IP dans chaque cluster correspondant aux pods à l'aide de app: zoneprinter. Vous pouvez constater qu'il en existe un dans le cluster gke-us kubectl get service -n zoneprinter.

    Le résultat ressemble à ce qui suit :

    NAME                                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    mci-zone-mcs-svc-lgq966x5mxwwvvum   ClusterIP   None          <none>        8080/TCP         4m59s
    

Un service similaire sans adresse IP de cluster se trouve également dans gke-eu. Ces services locaux permettent de sélectionner les points de terminaison des pods de manière dynamique afin de programmer l'équilibreur de charge d'Ingress global avec des backends.

MultiClusterIngress

  1. Créez un fichier nommé mci.yaml ayant le contenu suivant :

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: zone-ingress
      namespace: zoneprinter
    spec:
      template:
        spec:
          backend:
            serviceName: zone-mcs
            servicePort: 8080
    

    Notez que cette configuration achemine tout le trafic vers la ressource MultiClusterService nommée zone-mcs qui existe dans l'espace de noms zoneprinter.

  2. Déployez la ressource MultiClusterIngress faisant référence à zone-mcs en tant que backend :

    kubectl apply -f mci.yaml
    

    Le résultat ressemble à ce qui suit :

    multiclusteringress.networking.gke.io/zone-ingress created
    

    Notez que MultiClusterIngress présente le même schéma que les objets Ingress Kubernetes. La sémantique de la ressource Ingress est identique, à l'exception du champ backend.serviceName.

Le champ backend.serviceName d'une ressource MultiClusterIngress fait référence à une ressource MultiClusterService dans l'API Fleet au lieu d'un service dans un cluster Kubernetes. Cela signifie que tous les paramètres d'Ingress, tels que la terminaison TLS, peuvent être configurés de la même manière.

Valider un état de déploiement réussi

Le déploiement de nouveaux équilibreurs de charge par l'équilibreur de charge Google Cloud peut prendre plusieurs minutes. La mise à jour des équilibreurs de charge existants est plus rapide, car il n'est pas nécessaire de déployer de nouvelles ressources. La ressource MCI décrit les ressources Compute Engine sous-jacentes créées en son nom.

  1. Vérifiez que le déploiement a réussi :

    kubectl describe mci zone-ingress -n zoneprinter
    

    Le résultat ressemble à ce qui suit :

    Name:         zone-ingress
    Namespace:    zoneprinter
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"zone-ingress","namespace":"zon...
    API Version:  networking.gke.io/v1
    Kind:         MultiClusterIngress
    Metadata:
      Creation Timestamp:  2020-04-10T23:35:10Z
      Finalizers:
        mci.finalizer.networking.gke.io
      Generation:        2
      Resource Version:  26458887
      Self Link:         /apis/networking.gke.io/v1/namespaces/zoneprinter/multiclusteringresses/zone-ingress
      UID:               62bec0a4-8a08-4cd8-86b2-d60bc2bda63d
    Spec:
      Template:
        Spec:
          Backend:
            Service Name:  zone-mcs
            Service Port:  8080
    Status:
      Cloud Resources:
        Backend Services:
          mci-8se3df-8080-zoneprinter-zone-mcs
        Firewalls:
          mci-8se3df-default-l7
        Forwarding Rules:
          mci-8se3df-fw-zoneprinter-zone-ingress
        Health Checks:
          mci-8se3df-8080-zoneprinter-zone-mcs
        Network Endpoint Groups:
          zones/europe-west1-c/networkEndpointGroups/k8s1-e4adffe6-zoneprint-mci-zone-mcs-svc-lgq966x5m-808-88670678
          zones/us-central1-a/networkEndpointGroups/k8s1-a6b112b6-zoneprint-mci-zone-mcs-svc-lgq966x5m-808-609ab6c6
        Target Proxies:
          mci-8se3df-zoneprinter-zone-ingress
        URL Map:  mci-8se3df-zoneprinter-zone-ingress
      VIP:        34.98.102.37
    Events:
      Type    Reason  Age                    From                              Message
      ----    ------  ----                   ----                              -------
      Normal  ADD     3m35s                  multi-cluster-ingress-controller  zoneprinter/zone-ingress
      Normal  UPDATE  3m10s (x2 over 3m34s)  multi-cluster-ingress-controller  zoneprinter/zone-ingress
    

    Plusieurs champs indiquent l'état du déploiement d'Ingress :

    • Events est le premier endroit à consulter. Si une erreur s'est produite, elle est répertoriée dans ce champ.

    • Cloud Resource répertorie les ressources Compute Engine, telles que les règles de transfert, les services de backend et les règles de pare-feu, créées par le contrôleur multicluster Ingress. Si elles ne sont pas répertoriées, cela signifie qu'elles n'ont pas encore été créées. Vous pouvez inspecter l'état des ressources Compute Engine individuelles à l'aide de la console ou de la commande gcloud.

    • VIP répertorie une adresse IP lorsqu'elle a été allouée. Notez que l'équilibreur de charge ne traite pas encore le trafic, même si l'adresse IPV existe. Si une adresse IPV ne s'affiche pas après quelques minutes ou si l'équilibreur de charge ne diffuse pas de réponse 200 dans les 10 minutes, consultez la page Dépannage et opérations.

    Si l'état des événements de sortie est Normal, le déploiement de la ressource MCI est probablement réussi. Cependant, le seul moyen de déterminer si le chemin de trafic complet est fonctionnel est de le tester.

  2. Vérifiez que l'application est diffusée sur l'adresse IPV à l'aide du point de terminaison /ping :

    curl INGRESS_VIP/ping
    

    Remplacez INGRESS_VIP par l'adresse IP virtuelle.

    Le résultat ressemble à ce qui suit :

    {"Hostname":"34.98.102.37","Version":"1.0","GCPZone":"us-central1-a","Backend":"zone-ingress-5554bb95b4-svv5d"}
    

    Le résultat doit indiquer la région et le backend de l'application.

  3. Vous pouvez également accéder à l'URL http://INGRESS_VIP dans votre navigateur pour afficher une version graphique de l'application indiquant la région depuis laquelle elle est diffusée.

    Le cluster vers lequel le trafic est transféré dépend de votre situation géographique. L'équilibreur de charge Google Cloud est conçu pour transférer le trafic client vers le backend disponible le plus proche disposant de la capacité nécessaire.

Spécifications des ressources

Spécification MultiClusterService

La définition de MultiClusterService comprend deux parties :

  1. Une section template qui définit le service à créer dans les clusters Kubernetes. Notez que même si la section template contient des champs compatibles avec un service standard, seuls deux champs sont acceptés dans un MultiClusterService : selector et ports. Les autres champs sont ignorés.

  2. Une section clusters facultative qui définit les clusters qui reçoivent le trafic et les propriétés d'équilibrage de charge pour chaque cluster. Si la section clusters n'est pas spécifiée ou si aucun cluster n'est répertorié, tous les clusters sont utilisés par défaut.

Le fichier manifeste suivant décrit une ressource MCS standard :

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      selector:
        app: POD_LABEL
      ports:
      - name: web
        protocol: TCP
        port: PORT
        targetPort: TARGET_PORT

Remplacez les éléments suivants :

  • NAME : le nom du MCS. Ce nom est référencé par le champ serviceName dans les ressources MCI.
  • NAMESPACE : l'espace de noms Kubernetes dans lequel la ressource MCS est déployée. Il doit se trouver dans le même espace de noms que la ressource MCI et les pods sur tous les clusters de la Fleet.
  • POD_LABEL : le libellé qui détermine les pods sélectionnés comme backends pour la ressource MCS sur tous les clusters du parc.
  • PORT doit correspondre au port référencé par la ressource MCI faisant référence à la ressource MCS.
  • TARGET_PORT : le port utilisé pour envoyer du trafic au pod à partir de l'équilibreur de charge Google Cloud. Un NEG est créé dans chaque cluster avec ce port défini comme port de diffusion.

Spécification MultiClusterIngress

Le fichier mci.yaml suivant décrit l'interface de l'équilibreur de charge :

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      backend:
       serviceName: DEFAULT_SERVICE
       servicePort: PORT
      rules:
        - host: HOST_HEADER
          http:
            paths:
            - path: PATH
              backend:
                serviceName: SERVICE
                servicePort: PORT

Remplacez les éléments suivants :

  • NAME : le nom de la ressource MCI.
  • NAMESPACE : l'espace de noms Kubernetes dans lequel la ressource MCI est déployée. Il doit se trouver dans le même espace de noms que la ressource MCS et les pods sur tous les clusters de la Fleet.
  • DEFAULT_SERVICE : sert de backend par défaut pour tout le trafic qui ne correspond à aucune règle d'hôte ou de chemin d'accès. Ce champ est obligatoire. Vous devez spécifier un backend par défaut dans la ressource MCI, même si d'autres correspondances d'hôte ou de chemin d'accès sont configurées.
  • PORT : un numéro de port valide. Ce champ doit correspondre au champ port des ressources MCS.
  • HOST_HEADER : correspond au trafic via le champ d'en-tête de l'hôte HTTP. Le champ host est facultatif.
  • PATH : correspond au trafic via le chemin d'accès à l'URL HTTP. Le champ path est facultatif.
  • SERVICE : le nom d'une ressource MCS déployée dans le même espace de noms et cluster de configuration que cette ressource MCI.

Fonctionnalités de l'objet Ingress multicluster

Cette section explique comment configurer des fonctionnalités supplémentaires de l'objet Ingress multicluster.

Sélection des clusters

Par défaut, les services dérivés de l'objet Ingress multicluster sont programmés sur chaque cluster membre. Toutefois, vous pouvez appliquer des règles d'entrée à des clusters spécifiques. Voici quelques exemples d'utilisation :

  • Appliquer un objet Ingress multicluster à tous les clusters, sauf au cluster de configuration afin d'isoler ce dernier.
  • Migrer des charges de travail entre les clusters en mode bleu-vert
  • Router vers des backends d'application qui n'existent que dans un sous-ensemble de clusters
  • Utiliser une seule adresse IPV L7 pour le routage hôte/chemin vers les backends qui résident sur différents clusters

La sélection de clusters vous permet de choisir des clusters par région et par nom dans l'objet MultiClusterService. Cette commande détermine les clusters vers lesquels l'objet Ingress multicluster pointe et où les services dérivés sont programmés. Les clusters d'un même Fleet et d'une même région ne doivent pas porter le même nom afin que chaque cluster soit référencé de façon unique.

  1. Ouvrir mcs.yaml

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: zone-mcs
      namespace: zoneprinter
    spec:
      template:
        spec:
          selector:
            app: zoneprinter
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    

    Cette spécification crée actuellement des services dérivés dans tous les clusters. Il s'agit du comportement par défaut.

  2. Ajoutez les lignes suivantes dans la section des clusters :

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: zone-mcs
      namespace: zoneprinter
    spec:
      template:
        spec:
          selector:
            app: zoneprinter
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
      clusters:
      - link: "us-central1-a/gke-us"
      - link: "europe-west1-c/gke-eu"
    

    Cet exemple de code ne crée des ressources de service dérivé que dans les clusters gke-us et gke-eu. Vous devez sélectionner des clusters pour appliquer les règles d'entrée de manière sélective. Si la section "clusters" de MultiClusterService n'est pas spécifiée ou si aucun cluster n'est répertorié, "tous" les clusters sont sélectionnés par défaut.

Compatibilité HTTPS

La compatibilité HTTPS est assurée par un secret Kubernetes. Avant d'activer le protocole HTTPS, vous devez créer une adresse IP statique. Cette adresse IP statique permet de partager la même adresse IP pour les protocoles HTTP et HTTPS. Pour plus d'informations, consultez la section Créer une adresse IP statique.

Une fois l'adresse IP statique établie, vous pouvez créer un secret.

  1. Créez un secret :

    kubectl -n prod create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
    

    Remplacez les éléments suivants :

    • SECRET_NAME par le nom de votre secret.
    • PATH_TO_KEYFILE par le chemin d'accès au fichier de clé TLS.
    • PATH_TO_CERTFILE par le chemin d'accès au fichier de certificat TLS.
  2. Mettez à jour le fichier mci.yaml avec le nom du secret :

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: zone-ingress
      namespace: zoneprinter
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: zone-mcs
            servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    

    Remplacez le SECRET_NAME par le nom de votre secret. Le STATIC_IP_ADDRESS correspond à l'adresse IP ou à l'URL complète de l'adresse que vous avez allouée à la section Créer une adresse IP statique.

  3. Redéployez la ressource MultiClusterIngress :

    kubectl apply -f mci.yaml
    

    Le résultat ressemble à ce qui suit :

    multiclusteringress.networking.gke.io/zone-ingress configured
    

Compatibilité BackendConfig

L'objet CRD BackendConfig vous permet de personnaliser les paramètres de la ressource BackendService de Compute Engine. La spécification acceptée est la suivante :

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: zone-health-check-cfg
  namespace: zoneprinter
spec:
  healthCheck:
    checkIntervalSec: [int]
    timeoutSec: [int]
    healthyThreshold: [int]
    unhealthyThreshold: [int]
    type: [HTTP | HTTPS | HTTP2 | TCP]
    port: [int]
    requestPath: [string]
  timeoutSec: [int]
  connectionDraining:
    drainingTimeoutSec: [int]
  sessionAffinity:
    affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
    affinityCookieTtlSec: [int]
  cdn:
    enabled: [bool]
    cachePolicy:
      includeHost: [bool]
      includeQueryString: [bool]
      includeProtocol: [bool]
      queryStringBlacklist: [string list]
      queryStringWhitelist: [string list]
  securityPolicy:
    name: ca-how-to-security-policy
  logging:
    enable: [bool]
    sampleRate: [float]
  iap:
    enabled: [bool]
    oauthclientCredentials:
      secretName: [string]

Pour utiliser un objet BackendConfig, associez-le à votre ressource MultiClusterService à l'aide d'une annotation :

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: zone-mcs
  namespace: zoneprinter
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"8080":"zone-health-check-cfg"}}'
spec:
 template:
   spec:
     selector:
       app: zoneprinter
     ports:
     - name: web
       protocol: TCP
       port: 8080
       targetPort: 8080

Pour plus d'informations sur la sémantique BackendConfig, consultez la section Associer un port de service à un objet BackendConfig.

Compatibilité avec gRPC

La configuration d'applications gRPC sur un objet Ingress multicluster nécessite une configuration très spécifique. Voici quelques conseils pour vous assurer que votre équilibreur de charge est correctement configuré :

  1. Assurez-vous que le trafic de l'équilibreur de charge vers votre application est HTTP/2. Utilisez les protocoles d'application pour configurer cela.
  2. Assurez-vous que votre application est correctement configurée pour SSL, car il s'agit d'une exigence de HTTP/2. Notez que l'utilisation de certificats autosignés est acceptable.
  3. Vous devez désactiver l'authentification mTLS sur votre application, car elle n'est pas compatible avec les équilibreurs de charge externes L7.

Cycle de vie des ressources

Modifications de configuration

Les ressources MultiClusterIngress et MultiClusterService se comportent comme des objets Kubernetes standards. Par conséquent, les modifications apportées aux objets sont reflétées de manière asynchrone dans le système. Toute modification produisant une configuration incorrecte entraîne le maintien des objets Google Cloud associés et génère une erreur dans le flux d'événements d'objet. Les erreurs associées à la configuration sont signalées sous forme d'événements.

Gérer les ressources Kubernetes

La suppression d'un objet Ingress entraîne l'arrêt de l'équilibreur de charge HTTP(S). Par conséquent, le trafic n'est plus acheminé vers une ressource MultiClusterService définie.

La suppression de la ressource MultiClusterService entraîne celle des services dérivés associés dans chacun des clusters.

Gérer des clusters

Vous pouvez modifier l'ensemble de clusters ciblé par l'équilibreur de charge en ajoutant ou en supprimant un ou plusieurs membres.

Par exemple, pour supprimer le cluster gke-eu en tant que backend pour une entrée, exécutez la commande ci-dessous :

gcloud container hub memberships unregister CLUSTER_NAME \
  --gke-uri=URI

Remplacez les éléments suivants :

  • CLUSTER_NAME : nom du cluster
  • URI : l'URI du cluster GKE.

Pour ajouter un cluster en Europe, exécutez la commande suivante :

gcloud container hub memberships register europe-cluster \
  --context=europe-cluster --service-account-key-file=PATH_TO_SERVICE_ACCOUNT_KEY_FILE

Remplacez PATH_TO_SERVICE_ACCOUNT_KEY_FILE par le chemin d'accès au fichier de clé du compte de service.

Notez que l'enregistrement ou l'annulation de l'enregistrement d'un cluster modifie son statut de backend pour tous les objets Ingress. Dans le cas ci-dessus, l'annulation de l'enregistrement du cluster gke-eu le supprime en tant que backend disponible pour tous les objets Ingress que vous créez. L'inverse est vrai pour l'enregistrement d'un nouveau cluster.

Désactiver l'objet Ingress multicluster

Avant de désactiver une entrée multicluster, vous devez d'abord supprimer vos ressources MultiClusterIngress et MultiClusterService, et vérifier que les ressources réseau associées sont bien supprimées.

Ensuite, pour désactiver l'entrée multicluster, utilisez la commande suivante :

gcloud alpha container hub ingress disable

Si vous ne supprimez pas les ressources MultiClusterIngress et MultiClusterService avant de désactiver l'entrée multicluster, vous pouvez rencontrer une erreur semblable à la suivante :

Feature has associated resources that should be cleaned up before deletion.

Si vous souhaitez forcer la désactivation de l'entrée multicluster, utilisez la commande suivante :

gcloud alpha container hub ingress disable --force

Annotations

Les annotations suivantes sont compatibles avec les ressources MultiClusterIngress et MultiClusterService.

Annotations MultiClusterIngress

Annotation Description
networking.gke.io/frontend-config Fait référence à une ressource FrontendConfig dans le même espace de noms que la ressource MultiClusterIngress.
networking.gke.io/static-ip Fait référence à l'adresse IP littérale d'une adresse IP statique globale.
networking.gke.io/pre-shared-certs Fait référence à une ressource SSLCertificate globale.

Annotations MultiClusterService

Annotation Description
networking.gke.io/app-protocols Utilisez cette annotation pour définir le protocole de communication entre l'équilibreur de charge et l'application. Les protocoles possibles sont HTTP, HTTPS et HTTP/2. Consultez les sections HTTPS entre l'équilibreur de charge et votre application et HTTP/2 pour l'équilibrage de charge avec l'objet Ingress.
beta.cloud.google.com/backend-config Utilisez cette annotation pour configurer le service de backend associé à un servicePort. Pour en savoir plus, consultez la page Fonctionnalités Ingress.

Règles SSL et redirections HTTPS

Vous pouvez utiliser la ressource FrontendConfig pour configurer des règles SSL et des redirections HTTPS. Les règles SSL vous permettent de spécifier les suites de chiffrement et les versions TLS acceptées par l'équilibreur de charge. Les redirections HTTPS vous permettent de forcer la redirection depuis HTTP/port 80 vers HTTPS/port 443. Les étapes suivantes permettent de configurer à la fois une règle SSL et une redirection HTTPS. Notez qu'elles peuvent également être configurées indépendamment.

  1. Créez une règle SSL qui refusera les requêtes utilisant une version antérieure à TLS v1.2.

    gcloud compute ssl-policies create tls-12-policy \
     --profile MODERN \
     --min-tls-version 1.2 \
     --project=PROJECT_ID
    

    Remplacez PROJECT_ID par l'ID de projet dans lequel les clusters GKE sont exécutés.

  2. Affichez votre règle pour vous assurer qu'elle a été créée.

    gcloud compute ssl-policies list --project=PROJECT_ID
    

    Le résultat ressemble à ce qui suit :

    NAME           PROFILE  MIN_TLS_VERSION
    tls-12-policy  MODERN   TLS_1_2
    
  3. Créez un certificat pour foo.example.com, comme dans cet exemple. Une fois que vous disposez de key.pem et de cert.pem, stockez ces identifiants en tant que secrets qui seront référencés par la ressource MultiClusterIngress.

    kubectl -n multi-cluster-demo create secret tls SECRET_NAME --key key.pem --cert cert.pem
    
  4. Enregistrez la ressource FrontendConfig suivante en tant que frontendconfig.yaml. Pour en savoir plus sur les champs compatibles avec FrontendConfig, consultez la section Configurer des ressources FrontendConfig.

    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: frontend-redirect-tls-policy
      namespace: multi-cluster-demo
    spec:
      sslPolicy: tls-12-policy
      redirectToHttps:
        enabled: true
    

    Cette configuration FrontendConfig activera les redirections HTTPS et une règle SSL qui applique une version TLS minimale de 1.2.

  5. Déployez frontendconfig.yaml dans votre cluster de configuration.

    kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    

    Remplacez MCI_CONFIG_CLUSTER par le nom de votre cluster de configuration.

  6. Enregistrez l'objet MultiClusterIngress suivant sous mci-frontendconfig.yaml.

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: foo-ingress
      namespace: multi-cluster-demo
      annotations:
        networking.gke.io/frontend-config: frontend-redirect-tls-policy
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: default-backend
            servicePort: 8080
          rules:
          - host: foo.example.com
            http:
              paths:
                - backend:
                    serviceName: foo
                    servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    
    • Remplacez STATIC_IP_ADDRESS par une adresse IP globale statique que vous avez déjà provisionnée.
    • Remplacez SECRET_NAME par le secret dans lequel votre certificat foo.example.com est stocké.

    Deux conditions sont requises pour activer les redirections HTTPS :

    • TLS doit être activé, via le champ spec.tls ou via l'annotation de certificat prépartagé networking.gke.io/pre-shared-certs. La ressource MultiClusterIngress ne se déploiera pas si les redirections HTTPS sont activées, mais que HTTPS ne l'est pas.
    • Une adresse IP statique doit être référencée via l'annotation networking.gke.io/static-ip. Des adresses IP statiques sont requises lors de l'activation de HTTPS sur un objet MultiClusterIngress.
  7. Déployez le MultiClusterIngress sur votre cluster de configuration.

    kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    
  8. Attendez une minute ou deux et inspectez foo-ingress.

    kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
    

    Si la commande aboutit, vous obtiendrez un résultat semblable à ceci :

    • L'état Cloud Resources est renseigné avec les noms de ressources.
    • Le champ VIP est renseigné avec l'adresse IP de l'équilibreur de charge.
    Name:         foobar-ingress
    Namespace:    multi-cluster-demo
    
    ...
    
    Status:
      Cloud Resources:
        Backend Services:
          mci-otn9zt-8080-multi-cluster-demo-bar
          mci-otn9zt-8080-multi-cluster-demo-default-backend
          mci-otn9zt-8080-multi-cluster-demo-foo
        Firewalls:
          mci-otn9zt-default-l7
        Forwarding Rules:
          mci-otn9zt-fw-multi-cluster-demo-foobar-ingress
          mci-otn9zt-fws-multi-cluster-demo-foobar-ingress
        Health Checks:
          mci-otn9zt-8080-multi-cluster-demo-bar
          mci-otn9zt-8080-multi-cluster-demo-default-backend
          mci-otn9zt-8080-multi-cluster-demo-foo
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579
        Target Proxies:
          mci-otn9zt-multi-cluster-demo-foobar-ingress
          mci-otn9zt-multi-cluster-demo-foobar-ingress
        URL Map:  mci-otn9zt-rm-multi-cluster-demo-foobar-ingress
      VIP:        34.149.29.76
    Events:
      Type     Reason  Age                From                              Message
      ----     ------  ----               ----                              -------
      Normal   UPDATE  38m (x5 over 62m)  multi-cluster-ingress-controller  multi-cluster-demo/foobar-ingress
    
  9. Vérifiez que les redirections HTTPS fonctionnent correctement en envoyant une requête HTTP via curl.

    curl VIP
    

    Remplacez VIP par l'adresse IP de MultiClusterIngress.

    Le résultat doit indiquer que la requête a été redirigée vers le port HTTPS, ce qui démontre que les redirections fonctionnent correctement.

  10. Vérifiez que la règle TLS fonctionne correctement en envoyant une requête HTTPS à l'aide de TLS version 1.1. Comme le DNS n'est pas configuré pour ce domaine, utilisez l'option --resolve pour indiquer à curl de résoudre directement l'adresse IP.

    curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
    

    Cette étape nécessite le fichier PEM du certificat qui permet de sécuriser l'objet MultiClusterIngress. Si la commande aboutit, vous obtiendrez un résultat semblable à ceci :

    ...
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=foo.example.com
    *  start date: Sep  1 10:32:03 2021 GMT
    *  expire date: Aug 27 10:32:03 2022 GMT
    *  common name: foo.example.com (matched)
    *  issuer: O=example; CN=foo.example.com
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7fa10f00e400)
    > GET / HTTP/2
    > Host: foo.example.com
    > User-Agent: curl/7.64.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
    < HTTP/2 200
    < content-type: application/json
    < content-length: 308
    < access-control-allow-origin: *
    < server: Werkzeug/1.0.1 Python/3.8.6
    < date: Wed, 01 Sep 2021 11:39:06 GMT
    < via: 1.1 google
    < alt-svc: clear
    <
    {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"}
    * Connection #0 to host foo.example.com left intact
    * Closing connection 0
    

    Le code de réponse est 200 et TLSv1.2 est utilisé, ce qui indique que tout fonctionne correctement.

    Vous pouvez ensuite vérifier que la règle SSL applique la bonne version de TLS en essayant de vous connecter avec TLS 1.1. Pour que cette étape fonctionne, votre règle SSL doit être configurée pour une version minimale de 1.2.

  11. Envoyez la même requête de l'étape précédente, mais appliquez une version TLS de 1.1.

    curl https://foo.example.com --resolve foo.example.com:443:VIP -v \
      --cacert CERT_FILE \
      --tls-max 1.1
    

    Si la commande aboutit, vous obtiendrez un résultat semblable à ceci :

    * Added foo.example.com:443:34.149.29.76 to DNS cache
    * Hostname foo.example.com was found in DNS cache
    *   Trying 34.149.29.76...
    * TCP_NODELAY set
    * Connected to foo.example.com (34.149.29.76) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: cert.pem
      CApath: none
    * TLSv1.1 (OUT), TLS handshake, Client hello (1):
    * TLSv1.1 (IN), TLS alert, protocol version (582):
    * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    * Closing connection 0
    curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    

    L'échec du handshake TLS indique que la règle SSL a bloqué TLS 1.1.

Créer une adresse IP statique

  1. Attribuez une adresse IP statique :

    gcloud compute addresses create ADDRESS_NAME --global
    

    Remplacez ADDRESS_NAME par le nom de l'adresse IP statique à allouer.

    Le résultat contient l'URL complète de l'adresse que vous avez créée, semblable à celle-ci :

    Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
    
  2. Affichez l'adresse IP que vous venez de créer :

    gcloud compute addresses list
    

    Le résultat ressemble à ce qui suit :

    NAME          ADDRESS/RANGE  TYPE      STATUS
    ADDRESS_NAME  STATIC_IP_ADDRESS  EXTERNAL  RESERVED
    

    Ce résultat comprend les éléments suivants :

    • Le ADDRESS_NAME que vous avez défini.
    • Le STATIC_IP_ADDRESS alloué.
  3. Mettez à jour le fichier mci.yaml avec l'adresse IP statique :

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: zone-ingress
      namespace: zoneprinter
    annotations:
      networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: zone-mcs
            servicePort: 8080
    

    Remplacez STATIC_IP_ADDRESS par l'un des éléments suivants :

    • L'adresse IP allouée, semblable à : 34.102.201.47
    • L'URL complète de l'adresse que vous avez créée, semblable à : "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"

    STATIC_IP_ADDRESS n'est pas le nom de la ressource (ADDRESS_NAME).

  4. Redéployez la ressource MultiClusterIngress :

    kubectl apply -f mci.yaml
    

    Le résultat ressemble à ce qui suit :

    multiclusteringress.networking.gke.io/zone-ingress configured
    
  5. Suivez les étapes de la section Valider un état de déploiement réussi pour vérifier que le déploiement est diffusé sur STATIC_IP_ADDRESS.

Certificats prépartagés

Les certificats prépartagés sont des certificats importés dans Google Cloud qui peuvent être utilisés par l'équilibreur de charge pour la terminaison TLS au lieu des certificats stockés dans les secrets Kubernetes. Ces certificats sont importés hors bande depuis GKE vers Google Cloud et référencés par un objet Ingress multicluster. L'utilisation de plusieurs certificats est également acceptée, via des certificats prépartagés ou des secrets Kubernetes.

L'utilisation des certificats dans l'objet Ingress multicluster nécessite l'annotation networking.gke.io/pre-shared-certs et le nom des certificats. Lorsque plusieurs certificats sont spécifiés pour un objet Ingress multicluster donné, un ordre prédéterminé détermine quel certificat est présenté au client.

Vous pouvez répertorier les certificats SSL disponibles en exécutant la commande suivante :

gcloud compute ssl-certificates list

L'exemple ci-dessous décrit le trafic client vers l'un des hôtes spécifiés qui correspond au nom commun des certificats prépartagés, de sorte que chaque certificat correspondant au nom de domaine soit présenté.

kind: MultiClusterIngress
metadata:
  name: shopping-service
  namespace: prod
  annotations:
    networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
  template:
    spec:
      rules:
      - host: my-domain1.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain1-svc
              servicePort: 443
      - host: my-domain2.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain2-svc
              servicePort: 443

Certificats gérés par Google

Les certificats gérés par Google sont compatibles avec l'objet Ingress multicluster via l'annotation networking.gke.io/pre-shared-certs. L'objet Ingress multicluster est compatible avec le rattachement de certificats gérés par Google à une ressource MultiClusterIngress. Toutefois, contrairement à une entrée dans un cluster unique, la génération déclarative d'une ressource Kubernetes ManagedCertificate n'est pas compatible avec l'objet Ingress multicluster. La création initiale du certificat géré par Google doit être effectuée directement via l'API compute ssl-certificates create avant de pouvoir associer le certificat à un MultiClusterIngress. Pour ce faire, procédez comme suit :

  1. Créez un certificat géré par Google comme indiqué à l'étape 1 ici. Ne passez pas à l'étape 2, car l'objet Ingress multicluster associera le certificat pour vous.

    gcloud compute ssl-certificates create my-google-managed-cert \
        --domains=my-domain.gcp.com \
        --global
    
  2. Référencez le nom du certificat dans le fichier MultiClusterIngress à l'aide de l'annotation networking.gke.io/pre-shared-certs.

    kind: MultiClusterIngress
    metadata:
    name: shopping-service
    namespace: prod
    annotations:
      networking.gke.io/pre-shared-certs: "my-google-managed-cert"
    spec:
    template:
      spec:
        rules:
        - host: my-domain.gcp.com
          http:
            paths:
            - backend:
                serviceName: my-domain-svc
                servicePort: 8080
    

Le fichier manifeste précédent associe le certificat à votre MultiClusterIngress afin qu'il puisse arrêter le trafic pour vos clusters GKE de backend. Google Cloud renouvellera automatiquement votre certificat avant son expiration. Les renouvellements se déroulent de manière transparente et ne nécessitent aucune mise à jour de l'objet Ingress multicluster.

Protocoles d'application

La connexion du proxy de l'équilibreur de charge à votre application utilise le protocole HTTP par défaut. À l'aide de l'annotation networking.gke.io/app-protocols, vous pouvez configurer l'équilibreur de charge pour qu'il utilise HTTPS ou HTTP/2 lorsqu'il transfère les requêtes à votre application. Dans le champ annotation de l'exemple suivant, http2 fait référence au nom du port MultiClusterService et HTTP2 fait référence au protocole utilisé par l'équilibreur de charge.

kind: MultiClusterService
metadata:
  name: shopping-service
  namespace: prod
  annotations:
    networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
  template:
    spec:
      ports:
      - port: 443
        name: http2

BackendConfig

Reportez-vous à la section ci-dessus pour savoir comment configurer l'annotation.

Étape suivante