En esta página, se explica cómo usar el balanceo de cargas nativo del contenedor en Google Kubernetes Engine (GKE). El balanceo de cargas nativo del contenedor permite que los balanceadores de cargas se orienten directamente a los pods de Kubernetes y distribuyan el tráfico de manera uniforme a los pods.
Consulta Balanceo de cargas nativo del contenedor para obtener información sobre los beneficios, los requisitos y las limitaciones del balanceo de cargas nativo del contenedor.
Usa el balanceo de cargas nativo del contenedor
En las siguientes secciones, se explica la configuración de balanceo de cargas nativo del contenedor en GKE. Ten en cuenta que, en los clústeres de GKE de versión 1.17 y posteriores, y en ciertas condiciones, el balanceo de cargas nativo del contenedor es parte de la configuración predeterminada y no requiere una anotación de Service cloud.google.com/neg: '{"ingress": true}'
explícita.
Crea un clúster nativo de la 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 siguiente comando, 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 un objeto Deployment
A continuación, implementa una carga de trabajo en el clúster.
En el siguiente Deployment de muestra, neg-demo-app
, se ejecuta una única instancia de un servidor HTTP en contenedores. Te recomendamos usar cargas de trabajo que usen los comentarios de preparación de pods, si están disponibles en la versión de GKE que usas. Consulta Preparación de pods para obtener más información y conocer los requisitos de la versión de GKE.
Considera actualizar tu clúster para usar los comentarios de preparación de pods.
Usa comentarios de preparación de pods
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: 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 ports: - containerPort: 9376 protocol: TCP
Usa un retraso codificado
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: 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 # Note: The following line is necessary only on clusters running GKE v1.11 and lower. # For details, see https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing#align_rollouts ports: - containerPort: 9376 protocol: TCP 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 este manifiesto como neg-demo-app.yaml
y, luego, crea la implementación con la ejecución del siguiente comando:
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.
El siguiente servicio de muestra, 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 a NEG after an Ingress is created spec: # Service's specification type: ClusterIP 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 creará hasta que crees un Ingress para el servicio.
Guarda este manifiesto como neg-demo-svc.yaml
y crea el servicio con la ejecución del siguiente comando:
kubectl apply -f neg-demo-svc.yaml
Crea un Ingress para el servicio
En el siguiente ejemplo de Ingress, neg-demo-ing
, se dirige al servicio que creaste:
apiVersion: networking.k8s.io/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 este manifiesto como neg-demo-ing.yaml
y crea el Ingress con la ejecución del siguiente comando:
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 se crean NEG 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 siguiente comando:
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 siguiente comando:
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.
Verifica el estado del servicio de backend
También puedes obtener el estado del servicio de backend de los balanceadores de cargas.
Primero, obtén una lista de los servicios de backend que se ejecutan en tu proyecto:
gcloud 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.
Con el siguiente comando, se escala la implementación neg-demo-app
de una instancia a 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 haya 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
Ve al menú de Google Kubernetes Engine en Cloud Console.
Selecciona neg-demo-cluster y haz clic en delete Delete.
Cuando se te solicite confirmar, haz clic en Borrar.
Soluciona problemas
Usa las siguientes técnicas para verificar tu configuración de red. En las secciones a continuación, se explica cómo resolver problemas específicos relacionados con el balanceo de cargas nativo del contenedor.
Consulta la documentación del balanceo de cargas para obtener información sobre cómo enumerar los grupos de extremos de red.
Puedes encontrar el nombre y las zonas del NEG que corresponde a un servicio en la anotación
neg-status
del servicio. Obtén la especificación de servicio con el siguiente comando:kubectl get svc svc-name -o yaml
La anotación
metadata:annotations:cloud.google.com/neg-status
genera una lista del NEG correspondiente del servicio y las zonas del NEG.Puedes verificar el estado del servicio de backend que corresponde a un NEG con el siguiente comando:
gcloud compute backend-services [--project project-name] \ get-health backend-service-name --global
El servicio de backend tiene el mismo nombre que su NEG.
Para imprimir los registros de eventos de un servicio, usa el siguiente comando:
kubectl describe svc service-name
La string de nombre del servicio incluye el nombre y el espacio de nombres del servicio GKE correspondiente.
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 siguiente error:
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 de forma simultánea. Para obtener más información sobre el uso de IP de alias, consulta Crea un clúster nativo de VPC.
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.
Un contenedor que no controla
SIGTERM
, también puede provocar los errores 502 y las conexiones rechazadas. Si un contenedor no controlaSIGTERM
de forma explícita, termina y deja de controlar solicitudes de inmediato. El balanceador de cargas continúa enviando tráfico entrante al contenedor finalizado, lo que genera errores.El balanceador de cargas nativo del contenedor solo tiene un extremo de backend. Durante una actualización progresiva, el extremo anterior se desprograma antes de que se programe el nuevo extremo.
- Solución
Configura los contenedores para manejar
SIGTERM
y continúa respondiendo a las solicitudes durante todo el período de gracia de terminación (30 segundos de forma predeterminada). Configura pods para comenzar a fallar las verificaciones de estado cuando recibenSIGTERM
. Esto le indica al balanceador de cargas que deje de enviar tráfico al pod mientras la desprogramación del extremo está en progreso.Si la aplicación no se cierra correctamente y deja de responder a las solicitudes cuando se recibe un
SIGTERM
, el hook preStop puede usarse para manejarSIGTERM
y seguir entregando tráfico mientras la desprogramación del extremo está en curso.lifecycle: preStop: exec: # if SIGTERM triggers a quick exit; keep serving traffic instead command: ["sleep","60"]
Consulta la documentación sobre la terminación de pods y esta publicación sobre las prácticas recomendadas de terminación de pods para obtener más información.
Si el backend del balanceador de cargas tiene una sola instancia, configura la estrategia de implementación para evitar que se destruya la única instancia antes de que la instancia nueva se programe por completo. En el caso de los pods de aplicaciones administrados por la carga de trabajo de
Deployment
, esto se puede lograr mediante la configuración de la estrategia de lanzamiento con el parámetromaxUnavailable
igual a0
.strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0
Para solucionar problemas de tráfico que no llega a los extremos, verifica que las reglas de firewall permitan el tráfico entrante de TCP a tus extremos en los rangos
130.211.0.0/22
y35.191.0.0/16
. Para obtener más información, consulta Crea verificaciones de estado en la documentación de Cloud Load Balancing.Revisa los servicios de backend de tu proyecto. La string de nombre del servicio de backend relevante incluye el nombre y el espacio de nombres del servicio de Google Kubernetes Engine correspondiente:
gcloud compute backend-services list
Recupera el estado del backend desde el servicio de backend:
gcloud 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 compute network-endpoint-groups list-network-endpoints neg
Verifica que todos los extremos esperados estén en el NEG.
Lanzamiento suspendido
- Síntomas
- El lanzamiento de puestos de implementación actualizados y la cantidad de réplicas actualizadas no coincide con la cantidad deseada de réplicas.
- Causas posibles
Las verificaciones de estado de la implementación están fallando. La imagen del contenedor puede ser mala o la verificación de estado puede estar mal configurada. El reemplazo continuo de pods espera hasta que el pod recién iniciado pase su puerta de preparación de pod. Esto solo ocurre si el Pod responde a las verificaciones de estado del balanceador de cargas. Si el pod no responde o la verificación de estado está mal configurada, no se pueden cumplir las condiciones de la puerta de preparación y el lanzamiento no puede continuar.
Si usas
kubectl
1.13 o superior, puedes verificar el estado de las puertas de preparación de un pod con el siguiente comando:kubectl get pod my-pod -o wide
Verifica la columna
READINESS GATES
.Esta columna no existe en
kubectl
1.12 y versiones anteriores. Un pod que está marcado en estadoREADY
puede tener una puerta de preparación con errores. Para verificar esto, usa el siguiente comando:kubectl get pod my-pod -o yaml
Las puertas de preparación y sus estados se enumeran en la salida.
- Resolución
Verifica que la imagen del contenedor en la especificación de su pod de implementación funcione correctamente y pueda responder a las verificaciones de estado. Comprueba que las verificaciones de estado estén configuradas correctamente.
Problemas conocidos
El balanceo de cargas nativo del contenedor en Google Kubernetes Engine tiene los siguientes problemas conocidos:
Recolección incompleta de elementos no utilizados
Google Kubernetes Engine recolecta elementos no utilizados de los balanceadores de cargas nativos de contenedores cada dos 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 compute network-endpoint-groups list
En el resultado del comando, busca los NEG relevantes.
Para borrar un NEG, ejecuta el siguiente comando, en que neg es el nombre del NEG:
gcloud compute network-endpoint-groups delete neg
Alinea los lanzamientos de carga de trabajo con la propagación de extremos
Cuando implementas una carga de trabajo en tu clúster o 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. En la implementación de muestra que se implementa en esta guía, se usan dos campos para alinear su lanzamiento con la propagación de extremos: terminationGracePeriodSeconds
y minReadySeconds
.
terminationGracePeriodSeconds
permite al pod cerrarse de forma correcta. Esto es posible ya que espera que las conexiones terminen después de que se programe la eliminación de un pod.
minReadySeconds
agrega un período de latencia después de que se crea un pod. Especifica un número mínimo de segundos durante los cuales un pod nuevo debe estar en estado Ready
, sin que ninguno de sus contenedores falle, para que el pod se considere disponible.
Debes configurar los valores de las cargas de trabajo minReadySeconds
y terminationGracePeriodSeconds
en 60 segundos o más a fin de garantizar que el servicio no se interrumpa por lanzamientos de cargas 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.
No se respeta initialDelaySeconds
en el readinessProbe
del Pod
Quizás esperes que el balanceador de cargas nativo del contenedor respete la configuración de initialDelaySeconds
en el readinessProbe
del Pod. Sin embargo, kubelet implementa el readinessProbe
, y la configuración de initialDelaySeconds
controla la verificación de estado de kubelet, no el balanceador de cargas nativo del contenedor. El balanceo de cargas nativo del contenedor tiene su propia verificación de estado del balanceo de cargas.
¿Qué sigue?
- Obtén más información sobre los NEG.
- Obtén más información sobre los clústeres nativos de VPC.
- Obtén más información sobre el balanceo de cargas de HTTP(S).
- Mira una charla de KubeCon sobre las puertas de preparación de pods.