Utiliser HTTP/2 pour l'équilibrage de charge avec Ingress

Cette page décrit comment utiliser les objets Kubernetes Ingress et Service pour configurer un équilibreur de charge HTTP(S) externe afin qu'il utilise HTTP/2 pour communiquer avec les services de backend. Cette fonctionnalité est disponible à partir de la version 1.11.2 de Google Kubernetes Engine.

Aperçu

Un équilibreur de charge HTTP(S) joue le rôle de proxy entre vos clients et votre application. Les clients peuvent utiliser HTTP/1.1 ou HTTP/2 pour communiquer avec le proxy de l'équilibreur de charge. Cependant, la connexion entre le proxy de l'équilibreur de charge et votre application utilise le protocole HTTP/1.1 par défaut. Si votre application, qui s'exécute dans un pod Kubernetes Engine, est capable de recevoir des requêtes HTTP/2, configurez l'équilibreur de charge externe pour qu'il utilise HTTP/2 lorsqu'il transmet des requêtes à votre application.

Schéma montrant HTTP/2 entre l'équilibreur de charge et le pod (cliquez pour agrandir)

Dans cet exercice, vous allez créer un déploiement, un service et une entrée. Vous insérerez une annotationcloud.google.com/app-protocols dans le fichier manifeste du service pour indiquer que l'équilibreur de charge doit utiliser HTTP/2 pour communiquer avec votre application. Ensuite, vous appellerez votre service et vérifierez que votre application a bien reçu une requête HTTP/2.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

Configurez les paramètres gcloud par défaut à l'aide de l'une des méthodes suivantes :

  • Utilisez gcloud init pour suivre les instructions permettant de définir les paramètres par défaut.
  • Utilisez gcloud config pour définir individuellement l'ID, la zone et la région de votre projet.

Utiliser gcloud init

Si le message d'erreur One of [--zone, --region] must be supplied: Please specify location s'affiche, effectuez les tâches ci-dessous.

  1. Exécutez gcloud init et suivez les instructions :

    gcloud init

    Si vous utilisez SSH sur un serveur distant, utilisez l'option --console-only pour empêcher la commande d'ouvrir un navigateur :

    gcloud init --console-only
  2. Suivez les instructions pour autoriser gcloud à utiliser votre compte Google Cloud.
  3. Créez ou sélectionnez une configuration.
  4. Choisissez un projet Google Cloud.
  5. Choisissez une zone Compute Engine par défaut.

Utiliser gcloud config

  • Définissez votre ID de projet par défaut :
    gcloud config set project project-id
  • Si vous travaillez avec des clusters zonaux, définissez votre zone de calcul par défaut :
    gcloud config set compute/zone compute-zone
  • Si vous utilisez des clusters régionaux, définissez votre région de calcul par défaut :
    gcloud config set compute/region compute-region
  • Mettez à jour gcloud vers la dernière version :
    gcloud components update

Créer le déploiement

Ce fichier manifeste de déploiement déclare que vous souhaitez exécuter deux instances dupliquées de l'application Web echoheaders :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoheaders
spec:
  replicas: 2
  selector:
    matchLabels:
      app: echoheaders
  template:
    metadata:
      labels:
        app: echoheaders
    spec:
      containers:
      - name: echoheaders
        image: k8s.gcr.io/echoserver:1.10
        ports:
        - containerPort: 8443

Copiez le fichier manifeste dans un fichier nommé my-deployment.yaml, puis créez le déploiement :

kubectl apply -f my-deployment.yaml

Créer le service

Voici un fichier manifeste pour le service :

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

Enregistrez le fichier manifeste dans un fichier nommé my-service.yaml, puis créez le service :

kubectl apply -f my-service.yaml

Consultez le Service :

kubectl get service echoheaders --output yaml

Le résultat est semblable à ceci :

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

Pour cet exercice, voici les points importants à noter à propos de l'objet Service :

  • Le service est de type NodePort. Ce type est obligatoire pour les services qui vont être associés à une entrée.

  • Tous les pods comportant les libellés app: echoheaders et sont membres du service. Cette information est spécifiée dans le champ selector.

  • Le service dispose d'un port qui est nommé my-port. L'annotation cloud.google.com/app-protocols indique que my-port doit utiliser le protocole HTTP/2.

  • Le trafic dirigé vers le service sur le port TCP 443 est acheminé vers le port TCP 8443 de l'un des pods membres. Cela est spécifié dans les champs port et targetPort.

Créer l'entrée

Voici un fichier manifeste pour l'entrée :

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echomap
spec:
  backend:
    serviceName: echoheaders
    servicePort: 443

Copiez le fichier manifeste dans un fichier nommé my-ingress.yaml et créez l'entrée :

kubectl apply -f my-ingress.yaml

Attendez quelques minutes que le contrôleur d'entrée Kubernetes configure un équilibreur de charge HTTP(S), puis affichez l'entrée :

kubectl get ingress echomap --output yaml

Le résultat est semblable à ceci :

kind: Ingress
metadata:
  ...
  name: echomap
  ...
spec:
  backend:
    serviceName: echoheaders
    servicePort: 443
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.2

Pour cet exercice, voici les points importants à noter à propos de l'objet Ingress :

  • L'adresse IP du trafic entrant est indiquée sous loadBalancer:ingress.

  • Les requêtes entrantes sont acheminées vers un pod membre de echoheaders. Dans cet exercice, les pods membres ont le libellé app: echoheaders.

  • Les demandes sont acheminées vers le pod sur le port cible spécifié dans le fichier manifeste du service echoheaders. Dans cet exercice, le port cible du pod est 8443.

Vérifier que votre équilibreur de charge est compatible avec le protocole HTTP/2

gcloud

  1. Affichez la liste de vos services de backend :

    gcloud compute backend-services list
    
  2. Décrivez votre service de backend :

    gcloud beta compute backend-services describe backend-service-name --global
    

    backend-service-name est le nom de votre service de backend.

  3. Dans la sortie, vérifiez que le protocole est HTTP/2 :

    backends:
    ...
    description: '{...,"kubernetes.io/service-port":"443","x-features":["HTTP2"]}'
    ...
    kind: compute#backendService
    loadBalancingScheme: EXTERNAL
    protocol: HTTP2
    ...
    

Console

  1. Accédez à la page "Équilibrage de charge" dans la console Google Cloud.

    Accéder à la page Équilibrage de charge

  2. Sous Name (Nom), localisez votre équilibreur de charge.

    Capture d'écran de l'équilibreur de charge HTTP affiché dans Google Cloud Console (cliquez pour agrandir)
  3. Cliquez sur le nom de votre équilibreur de charge pour afficher votre service de backend.

  4. Vérifiez que le Endpoint protocol (Protocole du point de terminaison) de votre service de backend est HTTP/2.

    Capture d'écran du service de backend HTTP/2 affichée dans la console Google Cloud (cliquez pour agrandir)

Appeler votre service

Attendez quelques minutes que l'équilibreur de charge et le service de backend soient configurés. Saisissez l'adresse IP externe de votre équilibreur de charge dans la barre d'adresse de votre navigateur.

La sortie affiche des informations au sujet de la requête de l'équilibreur de charge au pod :

Hostname: echoheaders-7886d5bc68-xnrwj
...
Request Information:
  ...
  method=GET
  real path=/
  query=
  request_version=2
  request_scheme=https
  ...

Request Headers:
  ...
  x-forwarded-for=[YOUR_IP_ADDRESS], 203.0.113.2
  x-forwarded-proto=http
...

Pour cet exercice, voici les points importants à noter à propos de la sortie précédente :

  • La ligne request_version=2 indique que la requête entre l'équilibreur de charge et le pod a utilisé HTTP/2.

  • La ligne x-forwarded-proto=http indique que la requête entre vous et l'équilibreur de charge a utilisé HTTP 1.1 et non HTTP/2.

Étapes suivantes