Usa el balanceo de cargas nativo del contenedor

En esta página, se explica cómo usar el balanceo de cargas nativo del contenedor en Google Kubernetes Engine.

Descripción general

El balanceo de cargas nativo del contenedor habilita a que los balanceadores de cargas HTTP(S) se orienten a los pods de modo directo y distribuyan su tráfico de forma equitativa a los pods.

El balanceo de cargas nativo del contenedor aprovecha un modelo de datos llamado grupos de extremo de red (NEGs), que es una colección de extremos de red representada por pares de puertos IP.

Beneficios

El balanceo de cargas nativo del contenedor ofrece los beneficios siguientes:

Los pods son elementos destacados para el balanceo de cargas.
El kube-proxy configura las reglas iptables de los nodos para distribuir el tráfico hacia los pods. Sin el balanceo de cargas nativo del contenedor, el tráfico del balanceador de cargas viaja a los grupos de instancias de nodos y se enruta por medio de reglas iptables hacia los pods que pueden estar o no en el mismo nodo. Con el balanceo de cargas nativo del contenedor, el tráfico del balanceador de cargas se distribuye de forma directa en los pods que deben recibir el tráfico y borra el salto de red adicional. El balanceo de cargas nativo del contenedor también ayuda a mejorar la comprobación de estado, ya que se dirige a los pods de forma directa.

Diagrama que compara el comportamiento predeterminado (izquierda) con el comportamiento del balanceador de cargas nativo del contenedor.
Rendimiento de red mejorado
Debido a que el balanceador de cargas nativo del contenedor se comunica directo con los pods y que las conexiones tienen menos saltos de red, tanto la latencia como la capacidad de procesamiento se ven mejoradas.
Mayor visibilidad
Con el balanceo de cargas nativo del contenedor, cuentas con visibilidad en el tiempo de ida y vuelta (RTT) desde el cliente hasta el balanceador de cargas de HTTP(S), incluida la asistencia de IU de Stackdriver. Esto facilita la solución de problemas de tus servicios en el nivel NEG.
Asistencia para las características de balanceo de cargas de HTTP(S)
El balanceo de cargas nativo del contenedor ofrece asistencia nativa en Google Kubernetes Engine para varias características del balanceador de cargas de HTTP(S), como la integración con servicios de GCP como Cloud Armor, Cloud CDN y Cloud Identity-Aware Proxy. También cuenta con algoritmos de balanceo de cargas para lograr una distribución de tráfico precisa.

Requisitos

Los balanceadores de cargas nativos del contenedor en Google Kubernetes Engine deben cumplir con los requisitos siguientes:

Google Kubernetes Engine versión 1.10
Los balanceadores de cargas nativos del contenedor están disponibles en los clústeres de Google Kubernetes Engine que ejecutan Google Kubernetes Engine versión 1.10 o posterior.
VPC nativa
Para usar el balanceo de cargas nativos del contenedor, los clústeres deben ser nativos de VPC. Si quieres obtener más información, consulta Crea clústeres nativos de VPC mediante las IP de alias.

Restricciones

Los balanceadores de cargas nativos del contenedor no funcionan con redes heredadas.

Limitaciones

Los balanceadores de cargas nativos no admiten balanceadores de cargas internos ni balanceadores de cargas de red.

Precios

Se te cobra por el balanceador de cargas de HTTP(S) que aprovisiona el Ingress que creas en esta guía. Para obtener información sobre los precios del balanceador de cargas, consulta Balanceo de cargas y reglas de reenvío en la página de precios de Compute Engine.

Usa el balanceo de cargas nativo del contenedor

En las secciones a continuación, se te guía en la configuración del balanceo de cargas nativo del contenedor en Google Kubernetes Engine.

Crea un clúster nativo de VPC

Para usar el balanceo de cargas nativo del contenedor, tienes que crear un clúster con las IP de alias habilitadas.

Por ejemplo, con el comando siguiente, se crea un clúster neg-demo-cluster con una subred aprovisionada de forma automática en la zona us-central1-a:

gcloud container clusters create neg-demo-cluster \
    --enable-ip-alias \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

Crea una implementación

A continuación, implementa una carga de trabajo en el clúster.

En la Implementación siguiente de muestra, neg-demo-app ejecuta una sola instancia de un servidor HTTP en contenedor:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec: # Deployment's specification
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: k8s.gcr.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname # Container name
      terminationGracePeriodSeconds: 60 # Number of seconds to wait for connections to terminate before shutting down Pods

En esta implementación, cada contenedor ejecuta un servidor HTTP. El servidor HTTP solo muestra el nombre del host del servidor de la aplicación (el nombre del pod en el que se ejecuta el servidor) como respuesta.

Guarda el manifiesto como neg-demo-app.yaml y, luego, crea la implementación mediante la ejecución del comando siguiente:

kubectl apply -f neg-demo-app.yaml

Crea un servicio para un balanceador de cargas nativo del contenedor

Una vez creada una implementación, tienes que agrupar sus pods en un Servicio.

En el servicio de muestra a continuación, neg-demo-svc se orienta a la implementación de muestra que creaste en la sección anterior:

apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc # Name of Service
  annotations:
    cloud.google.com/neg: '{"ingress": true}' # Creates an NEG after an Ingress is created
spec: # Service's specification
  type: NodePort
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - port: 80 # Service's port
    protocol: TCP
    targetPort: 9376

La anotación del servicio cloud.google.com/neg: '{"ingress": true}' habilita el balanceo de cargas nativo del contenedor. Sin embargo, el balanceador de cargas no se crea hasta que crees un Ingress para el servicio.

Guarda el manifiesto como neg-demo-svc.yaml y, luego, crea el servicio con la ejecución del comando a continuación:

kubectl apply -f neg-demo-svc.yaml

Crea un Ingress para el servicio

En el Ingress de muestra a continuación, neg-demo-ing se orienta al servicio que creaste:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: neg-demo-ing
spec:
  backend:
    serviceName: neg-demo-svc # Name of the Service targeted by the Ingress
    servicePort: 80 # Should match the port used by the Service

Guarda el manifiesto como neg-demo-ing.yaml y, luego, crea el Ingress con la ejecución del comando a continuación:

kubectl apply -f neg-demo-ing.yaml

Una vez creado el Ingress, se crea un balanceador de cargas de HTTP(S) en el proyecto y los NEG se crean en cada zona en la que se ejecuta el clúster. Los extremos en el NEG y los del servicio se mantienen sincronizados.

Verifica el Ingress

Después de que implementaste una carga de trabajo, agrupaste sus pods en un servicio y creaste un Ingress para el servicio, tienes que verificar si el Ingress aprovisionó el balanceador de cargas nativo del contenedor de forma correcta.

Para recuperar el estado del Ingress, ejecuta el comando siguiente:

kubectl describe ingress neg-demo-ing

En el resultado del comando, busca los eventos ADD y CREATE:

Events:
Type     Reason   Age                From                     Message
----     ------   ----               ----                     -------
Normal   ADD      16m                loadbalancer-controller  default/neg-demo-ing
Normal   Service  4s                 loadbalancer-controller  default backend set to neg-demo-svc:32524
Normal   CREATE   2s                 loadbalancer-controller  ip: 192.0.2.0

Prueba la funcionalidad del balanceador de cargas

En las secciones a continuación, se explica cómo puedes probar la funcionalidad de un balanceador de cargas nativo del contenedor.

Visita la dirección IP del Ingress

Espera varios minutos hasta que el balanceador de cargas de HTTP(S) se configure.

Puedes verificar que el balanceador de cargas nativo del contenedor funciona si visitas la dirección IP del Ingress.

Para obtener la dirección IP del Ingress, ejecuta el comando siguiente:

kubectl get ingress neg-demo-ing

En el resultado del comando, la dirección IP del Ingress se muestra en la columna ADDRESS. Visita la dirección IP en un navegador web.

Comprueba el estado del servicio de backend

También puedes obtener el estado de los [servicios de backend] de los balanceadores de cargas.

Primero, obtén una lista de los servicios de backend que se ejecutan en tu proyecto:

gcloud beta compute backend-services list

Copia el nombre del backend que incluye el nombre del servicio, como neg-demo-svc. Luego, obtén el estado del servicio de backend:

gcloud compute backend-services get-health [BACKEND_SERVICE_NAME] --global

Verifica la funcionalidad del Ingress

Otra manera de probar que el balanceador de cargas funciona como lo esperado es mediante el escalamiento de la implementación de muestra, el envío de solicitudes de prueba al Ingress y la verificación de la respuesta de la cantidad correcta de réplicas.

El comando siguiente escala la implementación de neg-demo-app desde una instancia hasta dos instancias:

kubectl scale deployment neg-demo-app --replicas 2

Espera unos minutos para que se complete el lanzamiento. Para verificar si se completó el lanzamiento, ejecuta el comando siguiente:

kubectl get deployment neg-demo-app

En el resultado del comando, verifica que hayan dos réplicas disponibles:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
neg-demo-app   2         2         2            2           26m

Luego, ejecuta el comando siguiente para contar la cantidad de respuestas distintas provenientes del balanceador de cargas:

for i in `seq 1 100`; do \
  curl --connect-timeout 1 -s [IP_ADDRESS] && echo; \
done  | sort | uniq -c

donde [IP_ADDRESS] es la dirección IP del Ingress. Puedes obtener la dirección IP del Ingress desde kubectl describe ingress neg-demo-ing.

En el resultado del comando, observa que el número de respuestas distintas es el mismo que el número de réplicas, lo que indica que todos los pods de backend están entregando tráfico:

44 neg-demo-app-7f7dfd7bc6-dcn95
56 neg-demo-app-7f7dfd7bc6-jrmzf

Limpieza

Después de completar las tareas de esta página, sigue estos pasos para quitar los recursos a continuación y prevenir cargos no deseados a tu cuenta:

Borra el clúster

gcloud

gcloud container clusters delete neg-demo-cluster

Console

  1. Dirígete al menú de Google Kubernetes Engine en GCP Console.

    Ir al menú de Google Kubernetes Engine

  2. Selecciona neg-demo-cluster.

  3. Haz clic en Borrar.

Solución de problemas

En las secciones a continuación, se explica cómo resolver problemas comunes relacionados con el balanceo de cargas nativo del contenedor.

No se puede crear un clúster con IP de alias

Síntomas
Cuando intentas crear un clúster con IP de alias, tal vez encuentres el error siguiente:
ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
Causas posibles
Este error se produce si intentas crear un clúster con IP de alias que también usan redes heredadas.
Resolución
Asegúrate de no crear un clúster con IP de alias y una red heredada habilitadas a la misma vez. Para obtener más información sobre el uso de IP de alias, consulta Crea clústeres nativos de VPC con IP de alias.

El tráfico no alcanza los extremos

Síntomas
Errores 502 o conexiones rechazadas.
Causas posibles
A los extremos nuevos, por lo general, se los puede alcanzar después de adjuntarlos al balanceador de cargas, siempre que respondan a la verificación de estado. Tal vez encuentres errores 502 o conexiones rechazadas si el tráfico no puede alcanzar los extremos.
Resolución

A fin de resolver este problema, verifica que las reglas de firewall permitan tráfico de TCP entrante a tus extremos en los rangos 130.211.0.0/22 y 35.191.0.0/16. Para obtener más información, consulta Agrega verificación de estado en la documentación de Cloud Load Balancing.

Revisa los servicios de backend de tu proyecto. El servicio de backend relevante tiene el nombre del servicio de Google Kubernetes Engine Service correspondiente:

gcloud beta compute backend-services list

Recupera el estado del backend desde el servicio de backend:

gcloud beta compute backend-services get-health [BACKEND_SERVICE_NAME]

Si todos los backends están en mal estado, puede que tu firewall, Ingress o servicio estén mal configurados.

Si algunos backends están en mal estado durante un período breve, la causa podría ser la latencia de programación de la red.

Si algunos backends no aparecen en la lista de servicios de backend, la causa podría ser la latencia de programación de la red. Puedes verificar esto con la ejecución del comando siguiente, en que [NEG] es el nombre del servicio de backend. (Los NEG y los servicios de backend comparten el mismo nombre):

gcloud beta compute network-endpoint-groups list-network-endpoints [NEG]

Verifica que todos los extremos esperados estén en el NEG.

Problemas comunes

El balanceo de cargas nativo de contenedor en Google Kubernetes Engine tiene los siguientes problemas comunes en Beta:

Alinea los lanzamientos de carga de trabajo con la propagación de extremos

Cuando implementas una carga de trabajo en tu clúster o cuando actualizas una carga de trabajo existente, el balanceador de cargas nativo del contenedor puede demorar más en propagar extremos nuevos que lo que demora en terminar el lanzamiento de la carga de trabajo. La implementación de muestra que implementas en esta guía usa dos campos para alinear su lanzamiento con la propagación de extremos: terminationGracePeriodSeconds y minReadySeconds.

terminationGracePeriodSeconds permite al pod cerrarse con facilidad mediante la espera de que las conexiones terminen después de que se programe un pod para su borrado.

minReadySeconds agrega un período de latencia después de que se crea un pod. Especifica una cantidad mínima de segundos que debe tardar un pod nuevo en estar en estado Ready, sin que ninguno de sus contenedores fallen, con el fin de que el pod se considere disponible.

Debes configurar tus valores minReadySeconds y terminationGracePeriodSeconds de la carga de trabajo en 60 segundos o más para asegurarte de que el servicio no se interrumpa por lanzamientos de carga de trabajo.

terminationGracePeriodSeconds está disponible en todas las especificaciones de pod y minReadySeconds está disponible para implementaciones y DaemonSets.

Para obtener más información sobre el ajuste preciso de los lanzamientos, consulta RollingUpdateStrategy.

Recolección de elementos no utilizados incompleta

Google Kubernetes Engine recolecta elementos no utilizados de los balanceadores de cargas nativos de contenedores cada diez minutos. Si se borra un clúster antes de que los balanceadores de cargas se quiten por completo, tienes que borrar los NEG del balanceador de cargas de forma manual.

Para revisar los NEG en tu proyecto, ejecuta el comando siguiente:

gcloud beta compute network-endpoint-groups list

En el resultado del comando, busca los NEG relevantes.

Para borrar un NEG, ejecuta el comando siguiente, en que [NEG] es el nombre del NEG:

gcloud beta compute network-endpoint-groups delete [NEG]

Interrupción de las cargas de trabajo que escalan a cero

Las cargas de trabajo que escalan a cero pueden experimentar interrupciones momentáneas cuando el número de extremos en una transición de NEG desde cero a un valor distinto de cero y viceversa. Durante estas interrupciones, el balanceador de cargas podría mostrar respuestas que no sean 200 y los backends pueden parecer estar en mal estado.

Pasos siguientes

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...