Usa HTTP/2 para el balanceo de cargas con Ingress


En esta página, se muestra cómo usar objetos Ingress y Service de Kubernetes para configurar un balanceador de cargas de aplicaciones externo a fin de usar HTTP/2 para la comunicación con los servicios de backend.

Descripción general

Un balanceador de cargas de aplicaciones actúa como un proxy entre tus clientes y tu aplicación. Los clientes pueden usar HTTP/1.1 o HTTP/2 para comunicarse con el proxy del balanceador de cargas. Sin embargo, la conexión del proxy del balanceador de cargas a tu aplicación usa HTTP/1.1 de forma predeterminada. Si tu aplicación, que se ejecuta en un Pod de Google Kubernetes Engine, puede recibir solicitudes HTTP/2, configura el balanceador de cargas externo para que use HTTP/2 cuando reenvíe solicitudes a tu aplicación.

En este ejercicio, crearás una implementación, un servicio y un Ingress. Debes agregar una anotación cloud.google.com/app-protocols en tu manifiesto de servicio a fin de especificar que el balanceador de cargas debe usar HTTP/2 para comunicarse con tu aplicación. Luego, debes llamar a tu servicio y verificar que tu aplicación haya recibido una solicitud HTTP/2.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Kubernetes Engine de Google.
  • Habilitar la API de Kubernetes Engine de Google
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Crea el objeto Deployment

  1. Luego, copia el siguiente manifiesto a un archivo llamado my-deployment.yaml.

    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: registry.k8s.io/echoserver:1.10
            ports:
            - containerPort: 8443
    

    En este manifiesto, se describe un Deployment con dos réplicas de la aplicación web echoheaders.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f my-deployment.yaml
    

Crea el objeto Service

  1. Luego, copia el siguiente manifiesto a un archivo llamado my-service.yaml.

    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
    

    En este manifiesto, se describe un Service con las siguientes propiedades:

    • type: NodePort: especifica que este es un Service de tipo NodePort.
    • app: echoheaders: especifica que cualquier Pod que tiene esta etiqueta es miembro del Service.
    • cloud.google.com/app-protocols: Especifica que my-port debe usar el protocolo HTTP/2.
    • port: 443, protocol: TCP y targetPort: 8433: Especifican que el tráfico dirigido al servicio en el puerto TCP 443 se debe enrutar al puerto TCP 8422 en uno de los Pods miembro.
  2. Aplica el manifiesto al clúster:

    kubectl apply -f my-service.yaml
    
  3. Observa el Service:

    kubectl get service echoheaders --output yaml
    

    El resultado es similar al siguiente:

    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
    ...
    

Crea el Ingress

  1. Luego, copia el siguiente manifiesto a un archivo llamado my-ingress.yaml:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: echomap
    spec:
      defaultBackend:
        service:
          name: echoheaders
          port:
            number: 443
    

    En este manifiesto, se describe un Ingress que especifica que las solicitudes entrantes se envían a un Pod que es miembro del Service echoheaders. Las solicitudes se dirigen al Pod en el targetPort que se especifica en el manifiesto del Service echoheaders. En este ejercicio, el Pod targetPort es 8443.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f my-ingress.yaml
    

    Este comando puede tardar varios minutos en completarse mientras el controlador de Ingress de Kubernetes configura el balanceador de cargas de la aplicación.

  3. Ve el Ingress:

    kubectl get ingress echomap --output yaml
    

    El resultado es similar al siguiente:

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

    En este resultado, la dirección IP del Ingress es 203.0.113.2.

Prueba el balanceador de cargas

gcloud

  1. Haz una lista de tus servicios de backend:

    gcloud compute backend-services list
    
  2. Describe tu servicio de backend:

    gcloud beta compute backend-services describe BACKEND_SERVICE_NAME --global
    

    Reemplaza BACKEND_SERVICE_NAME por el nombre de la API de backend.

    El resultado especifica que protocol es HTTP2:

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

Consola

  1. Ve a la página Balanceo de cargas en la consola de Google Cloud.

    Ir a Balanceo de cargas

  2. En Nombre, busca tu balanceador de cargas.

  3. Haz clic en el nombre de tu balanceador de cargas para ver el servicio de backend.

  4. Verifica que el Protocolo de extremos de tu servicio de backend sea HTTP/2.

Llama a tu Service

Espera unos minutos a que GKE configure el balanceador de cargas y el servicio de backend y, luego, ingresa la dirección IP externa de tu balanceador de cargas en la barra de direcciones de tu navegador.

El resultado es similar al siguiente:

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
...

Esta información de salida sobre la solicitud del balanceador de cargas al Pod:

  • request_version=2: Indica que la solicitud entre el balanceador de cargas y el Pod usó HTTP/2.
  • x-forwarded-proto=http: Indica que la solicitud entre el navegador y el balanceador de cargas usó HTTP 1.1, no HTTP/2.

¿Qué sigue?