Sécuriser le trafic pour GKE Ingress

Cette page vous explique comment sécuriser et optimiser le trafic pour Google Kubernetes Engine (GKE) Ingress. Vous pouvez configurer des certificats SSL entre le client et l'équilibreur de charge, et sécuriser le trafic entre l'équilibreur de charge et votre application de backend. Avant de continuer, assurez-vous de savoir comment GKE sécurise Ingress avec HTTPS.

Cette page s'adresse aux spécialistes de la mise en réseau qui conçoivent et implémentent le réseau pour leur organisation, et installent, configurent et gèrent l'équipement réseau. Pour en savoir plus sur les rôles courants et les exemples de tâches que nous citons dans le contenuGoogle Cloud , consultez Rôles utilisateur et tâches courantes de GKE.

Sécuriser et optimiser le trafic entre le client et l'équilibreur de charge

Pour accepter les requêtes HTTPS de vos clients, l'équilibreur de charge doit disposer d'un certificat pour justifier son identité auprès de vos clients. L'équilibreur de charge doit également disposer d'une clé privée pour effectuer le handshake HTTPS. Pour en savoir plus sur la fourniture de certificats SSL à un équilibreur de charge HTTP(S), consultez Configurer TLS entre le client et l'équilibreur de charge.

Utiliser des certificats gérés par Google

Pour configurer un ou plusieurs certificats SSL gérés par Google et les associer à un objet Ingress, procédez comme suit :

  • Créez un ou plusieurs objets ManagedCertificate dans le même espace de noms que l'objet Ingress. Vous pouvez spécifier jusqu'à 15 certificats pour l'équilibreur de charge.
  • Associez les objets ManagedCertificate à un Ingress en ajoutant l'annotation networking.gke.io/managed-certificates à l'Ingress. Cette annotation est une liste d'objets ManagedCertificate séparés par une virgule.

Limites

Cette section décrit les limites des certificats gérés par Google. Si vous avez besoin de certificats autogérés ou si vous possédez déjà des certificats SSL que vous souhaitez configurer sur votre Ingress, consultez Configurer HTTPS (TLS) entre le client et l'équilibreur de charge.

  • Les certificats gérés par Google sont moins flexibles que ceux que vous obtenez et gérez vous-même. Les certificats gérés par Google acceptent jusqu'à 100 domaines ne comportant pas de caractères génériques. Contrairement aux certificats autogérés, les certificats gérés par Google ne sont pas compatibles avec les domaines comprenant des caractères génériques.

  • Le nombre et le type des certificats compatibles avec un objet Ingress sont définis par les limites des certificats SSL gérés par Google.

  • Les mises à jour des certificats gérés par Google ne sont pas acceptées. Pour en savoir plus, consultez la page Mettre à jour manuellement un certificat géré par Google.

  • Si le certificat est révoqué directement auprès de l'autorité de certification, Google n'effectue pas sa rotation automatique. Vous devez supprimer le certificat géré et en créer un autre.

  • GKE Ingress n'accepte pas les certificats gérés par le gestionnaire de certificats. Pour utiliser des certificats gérés par Certificate Manager, utilisez l'API Gateway.

Prérequis

  • Vous devez détenir le nom de domaine. Celui-ci ne doit pas dépasser 63 caractères. Vous pouvez utiliser n'importe quel service d'enregistrement de noms de domaine pour obtenir un nom de domaine.

  • Si vous utilisez un cluster GKE Standard, le module complémentaire HttpLoadBalancing doit être activé.

  • Votre fichier manifeste Ingress doit inclure l'annotation kubernetes.io/ingress.class: "gce". Le champ ingressClassName n'est pas disponible.

  • Vous devez appliquer les ressources Ingress et ManagedCertificate dans le même projet et le même espace de noms.

  • Créez une adresse IP externe réservée (statique). La réservation d'une adresse IP statique garantit que celle-ci restera en votre possession même si vous supprimez l'objet Ingress. En l'absence de réservation, l'adresse IP pourrait changer, vous obligeant alors à reconfigurer les enregistrements DNS de votre domaine. Utilisez Google Cloud CLI ou la console Google Cloud pour créer une adresse IP réservée.

    gcloud

    Pour créer une adresse IP réservée, exécutez la commande suivante :

    gcloud compute addresses create ADDRESS_NAME --global
    

    Remplacez ADDRESS_NAME par le nom de l'adresse IP réservée que vous créez.

    Pour trouver l'adresse IP statique que vous avez créée, exécutez la commande suivante :

    gcloud compute addresses describe ADDRESS_NAME --global
    

    Le résultat ressemble à ce qui suit :

    address: 203.0.113.32
    ...
    

    Console

    Pour créer une adresse IP réservée, procédez comme suit :

    1. Accédez à la page Adresses IP externes de la console Google Cloud .

      Accéder à la page Adresses IP externes

    2. Indiquez un nom pour l'adresse IP (par exemple, example-ip-address).

    3. Indiquez si vous souhaitez obtenir une adresse IPv4 ou IPv6.

    4. Sélectionnez l'option Global pour le champ Type.

    5. Cliquez sur Réserver. L'adresse IP s'affiche dans la colonne Adresse externe.

    Config Connector

    Remarque : Cette étape nécessite Config Connector. Suivez les instructions d'installation pour l'installer sur votre cluster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    Pour déployer ce manifeste, téléchargez le fichier sur votre ordinateur sous le nom compute-address.yaml, puis exécutez la commande suivante :

    kubectl apply -f compute-address.yaml
    

Configurer un certificat géré par Google

  1. Créer un objet ManagedCertificate. Cette ressource spécifie les domaines du certificat SSL. Les domaines avec des caractères génériques ne sont pas acceptés.

    Le fichier manifeste suivant décrit un objet ManagedCertificate. Enregistrez le fichier manifeste sous le nom managed-cert.yaml.

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: FIRST_CERT_NAME
    spec:
      domains:
        - FIRST_DOMAIN
    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: SECOND_CERT_NAME
    spec:
      domains:
        - SECOND_DOMAIN
    

    Remplacez les éléments suivants :

    • FIRST_CERT_NAME : nom de votre premier objet ManagedCertificate.
    • FIRST_DOMAIN : premier domaine que vous possédez.
    • SECOND_CERT_NAME : nom du deuxième objet ManagedCertificate.
    • SECOND_DOMAIN : deuxième domaine que vous possédez.

    Les noms des objets ManagedCertificate sont différents de ceux des certificats réels qu'ils créent. Il vous suffit de connaître le nom des objets ManagedCertificate pour les utiliser dans votre objet Ingress.

  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f managed-cert.yaml
    
  3. Suivez les instructions pour créer un déploiement et un service afin d'exposer votre application à Internet.

  4. Pour que cet objet ManagedCertificate devienne Active, associez-le à votre objet Ingress à l'aide de l'annotation networking.gke.io/managed-certificates, comme dans l'exemple suivant. La condition ManagedCertificate ne doit pas nécessairement être Active pour être associée à un objet Ingress.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-gmc-ingress
       annotations:
         networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    
    Note: It might take several hours for Google Cloud to provision the load
    balancer and the managed certificates, and for the load balancer to begin
    using the new certificates. For more information, see
    [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).
    
  5. Attendez que les certificats gérés par Google soient provisionnés. Cette opération peut prendre jusqu'à 60 minutes. Vous pouvez vérifier l'état des certificats à l'aide de la commande suivante :

    kubectl describe managedcertificate managed-cert
    

    Le résultat ressemble à ce qui suit :

    Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains:
       FQDN_1
       FQDN_2
    Status:
     CertificateStatus: Active
    (...)
    

    La valeur du champ Status.CertificateStatus indique que le certificat a été provisionné. Si Status.CertificateStatus n'est pas défini sur Active, le certificat n'est pas encore provisionné.

  6. Vérifiez que le protocole SSL fonctionne en accédant à vos domaines à l'aide du préfixe https://. Votre navigateur indique que la connexion est sécurisée et que vous pouvez afficher les détails du certificat.

Passer de certificats autogérés à des certificats gérés par Google

Lorsque vous migrez un Ingress pour qu'il utilise des certificats SSL gérés par Google au lieu de certificats SSL autogérés, ne supprimez pas vos certificats SSL autogérés avant que ceux gérés par Google soient actifs. Ces derniers deviennent automatiquement actifs une fois provisionnés. Lorsque les certificats SSL gérés par Google sont actifs, vous pouvez supprimer vos certificats SSL autogérés.

Suivez la procédure suivante pour passer de certificats SSL autogérés à des certificats SSL gérés par Google :

  1. Ajoutez un nouveau certificat géré par Google à l&#Ingress, comme décrit dans la section précédente.
  2. Attendez que l'état du certificat géré par Google soit Active. Vérifiez l'état du certificat à l'aide de la commande suivante :

    kubectl describe managedcertificate managed-cert
    
  3. Une fois que l'état est défini sur Active, mettez à jour l'objet Ingress pour supprimer les références au certificat autogéré.

Supprimer un certificat géré par Google

Pour supprimer un certificat géré par Google de votre cluster, vous devez supprimer l'objet ManagedCertificate ainsi que l'annotation de l'objet Ingress qui y fait référence.

  1. Supprimez l'objet ManagedCertificate :

    kubectl delete -f managed-cert.yaml
    

    Le résultat ressemble à ce qui suit :

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. Supprimez l'annotation de l'Ingress :

    kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-
    

    Vous remarquerez le signe moins, -, à la fin de la commande.

  3. Libérez l'adresse IP statique que vous avez réservée pour votre équilibreur de charge.

    Vous pouvez utiliser Google Cloud CLI, la console Google Cloud ou Config Connector pour libérer une adresse IP réservée.

    gcloud

    Utilisez la commande suivante pour libérer l'adresse IP réservée :

    gcloud compute addresses delete ADDRESS_NAME --global
    

    Remplacez ADDRESS_NAME par le nom de l'adresse IP.

    Console

    Pour libérer l'adresse IP réservée, procédez comme suit :

    1. Accédez à la page Adresses IP externes de la console Google Cloud .

      Accéder à la page Adresses IP externes

    2. Cochez la case en regard de l'adresse IP que vous souhaitez libérer.

    3. Cliquez sur Libérer l'adresse IP.

    Config Connector

    Remarque : Cette étape nécessite Config Connector. Suivez les instructions d'installation pour l'installer sur votre cluster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    Pour déployer ce manifeste, téléchargez le fichier sur votre ordinateur sous le nom compute-address.yaml, puis exécutez la commande suivante :

    kubectl delete -f compute-address.yaml
    

Créer des certificats et des clés

Pour utiliser des certificats prépartagés ou des secrets Kubernetes, vous devez d'abord disposer d'un ou de plusieurs certificats, avec les clés privées correspondantes. Chaque certificat doit avoir un nom commun (CN) correspondant à un nom de domaine que vous possédez. Si vous avez déjà deux fichiers de certificat avec les valeurs appropriées pour le nom commun, vous pouvez passer à la section suivante.

  1. Créez votre première clé :

    openssl genrsa -out test-ingress-1.key 2048
    
  2. Créez votre première requête de signature de certificat :

    openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \
        -subj "/CN=FIRST_DOMAIN"
    

    Remplacez FIRST_DOMAIN par un nom de domaine que vous possédez, tel que example.com.

  3. Créez votre premier certificat :

    openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \
        -out test-ingress-1.crt
    
  4. Créez votre deuxième clé :

    openssl genrsa -out test-ingress-2.key 2048
    
  5. Créez votre deuxième requête de signature de certificat :

    openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \
        -subj "/CN=SECOND_DOMAIN"
    

    Remplacez SECOND_DOMAIN par un autre nom de domaine que vous possédez, tel que examplepetstore.com.

  6. Créez votre deuxième certificat :

    openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \
        -out test-ingress-2.crt
    

Pour en savoir plus sur les certificats et les clés, consultez la présentation des certificats SSL.

Vous possédez maintenant deux fichiers de certificat et deux fichiers de clé.

Les tâches restantes utilisent les espaces réservés suivants pour désigner vos domaines, certificats et clés :

  • FIRST_CERT_FILE : chemin d'accès à votre premier fichier de certificat.
  • FIRST_KEY_FILE : chemin d'accès au fichier de clé qui accompagne votre premier certificat.
  • FIRST_DOMAIN : un nom de domaine que vous possédez.
  • FIRST_SECRET_NAME : nom du secret contenant votre premier certificat et votre première clé.
  • SECOND_CERT_FILE : chemin d'accès à votre deuxième fichier de certificat.
  • SECOND_KEY_FILE : chemin d'accès au fichier de clé qui accompagne votre deuxième certificat.
  • SECOND_DOMAIN : un deuxième nom de domaine que vous possédez.
  • SECOND_SECRET_NAME : nom du secret contenant votre deuxième certificat et votre deuxième clé.

Utiliser des certificats prépartagés

Vous pouvez utiliser des certificats SSL autogérés que vous importez dans votre projet Google Cloud . C'est ce qu'on appelle les certificats prépartagés. Vous pouvez spécifier un ou plusieurs certificats prépartagés pour un Ingress.

Pour utiliser plusieurs certificats prépartagés, procédez comme suit :

  1. Pour chaque paire certificat/clé, créez une ressource de certificat SSL visible publiquement dans Google Cloud.

     gcloud compute ssl-certificates create FIRST_CERT_NAME \
         --certificate=FIRST_CERT_FILE \
         --private-key=FIRST_KEY_FILE
     ```
    
    ```sh
     gcloud compute ssl-certificates create SECOND_CERT_NAME \
         --certificate=SECOND_CERT_FILE \
         --private-key=SECOND_KEY_FILE
     ```
    
    Replace the following:
    
    • FIRST_CERT_NAME, SECOND_CERT_NAME : noms de votre premier et de votre deuxième certificat.
    • FIRST_CERT_FILE, SECOND_CERT_FILE : vos premier et deuxième fichiers de certificat.
    • FIRST_KEY_FILE : SECOND_KEY_FILE, vos premier et deuxième fichiers de clé.
  2. Dans votre fichier manifeste Ingress, ajoutez l'annotation ingress.gcp.kubernetes.io/pre-shared-cert. La valeur de l'annotation est une liste de noms de certificats séparés par une virgule. De plus, dans la section spec.rules, incluez les champs host pour spécifier les domaines de vos services.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-psc-ingress
       annotations:
         ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    

Utiliser les secrets Kubernetes

Pour fournir à un équilibreur de charge HTTP(S) des certificats et des clés que vous avez vous-même créés, créez un ou plusieurs objets Secret Kubernetes. Chaque secret contient un certificat et une clé. Ajoutez les secrets au champ tls de votre fichier manifeste Ingress. L'équilibreur de charge utilise l'indication du nom du serveur SNI (Server Name Indication) pour déterminer le certificat à présenter au client, en fonction du nom de domaine figurant dans le handshake TLS.

Pour utiliser plusieurs certificats, procédez comme suit :

  1. Créez un secret pour chacune de vos paires de certificat et de clé :

     kubectl create secret tls FIRST_SECRET_NAME \
         --cert=FIRST_CERT_FILE \
         --key=FIRST_KEY_FILE
     ```
    
    ```sh
     kubectl create secret tls SECOND_SECRET_NAME \
         --cert=SECOND_CERT_FILE \
         --key=SECOND_KEY_FILE
     ```
    
  2. Dans votre fichier manifeste Ingress, dans la section spec.tls, listez les secrets que vous avez créés. De plus, dans la section spec.rules, incluez les champs host pour spécifier les domaines de vos services.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-mc-ingress
    spec:
      tls:
      - secretName: FIRST_SECRET_NAME
      - secretName: SECOND_SECRET_NAME
      rules:
      - host: FIRST_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60001
      - host: SECOND_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60002
    

    Remplacez FIRST_DOMAIN et SECOND_DOMAIN par des noms de domaine que vous possédez, par exemple example.com et examplepetstore.com.

Les modifications apportées aux objets Secret sont collectées périodiquement. Ainsi, si vous modifiez les données contenues dans l'objet Secret, ces modifications seront appliquées à l'équilibreur de charge en moins de 10 minutes.

Pour sécuriser un objet Ingress chiffré HTTPS pour vos clusters GKE, consultez l'exemple Entrée sécurisée.

Désactiver HTTP

Si vous souhaitez que tout le trafic entre le client et l'équilibreur de charge utilise le protocole HTTPS, vous pouvez désactiver HTTP en incluant l'annotation kubernetes.io/ingress.allow-http dans le fichier manifeste Ingress. Définissez la valeur de cette annotation sur "false".

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: SECRET_NAME
  ...

Ces fichiers manifestes incluent SECRET_NAME, qui correspond au nom de l'objet Secret que vous avez créé.

HTTP/2 entre le client et l'équilibreur de charge

Les clients peuvent utiliser HTTP/2 pour envoyer des requêtes à l'équilibreur de charge. Aucune configuration n'est requise.

Sécuriser et optimiser le trafic entre l'équilibreur de charge et l'application

Vous pouvez configurer le protocole utilisé pour la communication entre l'équilibreur de charge et vos pods d'application afin d'assurer la sécurité de bout en bout ou d'optimiser les performances du trafic interne. Bien que l'équilibreur de charge utilise par défaut le protocole HTTP/1.1 non chiffré pour les connexions de backend, vous pouvez activer HTTPS ou HTTP/2 pour répondre aux exigences spécifiques de votre application.

HTTPS entre l'équilibreur de charge et l'application

Si votre application, qui s'exécute dans un pod GKE, est capable de recevoir des requêtes HTTPS, configurez l'équilibreur de charge pour qu'il utilise HTTPS lorsqu'il transfère des requêtes à votre application. Pour plus d'informations, consultez la section HTTPS (TLS) entre l'équilibreur de charge et votre application.

Pour configurer le protocole utilisé entre l'équilibreur de charge et votre application, incluez l'annotation cloud.google.com/app-protocols dans votre fichier manifeste de service. Ce fichier manifeste de service doit inclure type: NodePort, sauf si vous utilisez l'équilibrage de charge natif en conteneurs. Si vous utilisez l'équilibrage de charge natif en conteneurs, utilisez type: ClusterIP.

Le fichier manifeste de service suivant spécifie deux ports. L'annotation indique que lorsqu'un équilibreur de charge HTTP(S) cible le port 80 du service, il doit utiliser le protocole HTTP. Lorsque l'équilibreur de charge cible le port 443 du service, il doit utiliser le protocole HTTPS.

Le fichier manifeste du service doit inclure une valeur name dans l'annotation de port. Vous ne pouvez modifier le port de service qu'en vous référant à la name qui lui est attribuée, et non par sa valeur targetPort.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-https-port
    port: 443
    targetPort: 8443
  - name: my-http-port
    port: 80
    targetPort: 50001

Utiliser HTTP/2 entre l'équilibreur de charge et l'application

Si votre application, qui s'exécute dans un pod GKE, est capable de recevoir des requêtes HTTP/2, vous pouvez configurer l'équilibreur de charge pour qu'il utilise HTTP/2 lorsqu'il transmet des requêtes à votre application.

Pour activer HTTP/2, vous devez utiliser l'annotation cloud.google.com/app-protocols dans le fichier manifeste du service Kubernetes. Cette annotation spécifie le protocole utilisé par l'équilibreur de charge pour communiquer avec votre application. Pour que l'équilibreur de charge puisse envoyer une requête HTTP/2 appropriée à votre backend, ce dernier doit être configuré avec SSL.

Voici un exemple de fichier manifeste de service configuré pour HTTP/2 :

apiVersion: v1
kind: Service
metadata:
  name: my-http2-service
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
  - name: my-port
    protocol: TCP
    port: 443
    targetPort: 8443

Veuillez noter les points suivants :

  • L'annotation cloud.google.com/app-protocols est définie sur '{"my-port":"HTTP2"}', ce qui indique à l'équilibreur de charge d'utiliser HTTP/2 pour le trafic envoyé au port nommé my-port.
  • Le port est défini sur 443 et dirige le trafic vers les pods sur targetPort 8443.