En esta página, se muestra cómo resolver problemas de conectividad en tu clúster.
Problemas de conectividad relacionados con la captura de paquetes de red en GKE
En esta sección, se describe cómo solucionar problemas de conectividad relacionados con la captura de paquetes de red, incluidos los síntomas como los tiempos de espera de conexión, los errores de conexión rechazada o el comportamiento inesperado de la aplicación. Estos problemas de conectividad pueden ocurrir a nivel del nodo o del pod.
Los problemas de conectividad en la red de tu clúster suelen estar en las siguientes categorías:
- No se puede acceder a los Pods: Es posible que no se pueda acceder a un Pod desde el interior ni el exterior del clúster debido a una configuración incorrecta de la red.
- Interrupciones del servicio: Un servicio puede estar experimentando interrupciones o retrasos.
- Problemas de comunicación entre Pods: Es posible que los Pods no puedan comunicarse entre sí de manera eficaz.
Los problemas de conectividad en tu clúster de GKE pueden originarse por varias causas, incluidas las siguientes:
- Parámetros de configuración incorrectos de la red: Políticas de red, reglas de firewall o tablas de enrutamiento incorrectas
- Errores de la aplicación: Errores en el código de la aplicación que afectan las interacciones de red.
- Problemas de infraestructura: Congestión de red, fallas de hardware o limitaciones de recursos.
En la siguiente sección, se muestra cómo resolver el problema en los nodos o Pods problemáticos.
Identifica el nodo en el que se ejecuta el Pod problemático con el siguiente comando:
kubectl get pods
POD_NAME -o=wide -nNAMESPACE Reemplaza lo siguiente:
POD_NAME
por el nombre del Pod.NAMESPACE
por el espacio de nombres de Kubernetes.
Conéctate al nodo:
gcloud compute ssh
NODE_NAME \ --zone=ZONE Reemplaza lo siguiente:
NODE_NAME
: el nombre de tu nodo.ZONE
: el nombre de la zona en la que se ejecuta el nodo.
Para depurar un Pod específico, identifica la interfaz
veth
asociada con el Pod:ip route | grep
POD_IP Reemplaza
POD_IP
por la dirección IP del Pod.Ejecuta los comandos de la caja de herramientas.
Comandos toolbox
toolbox
es una utilidad que proporciona un entorno alojado en contenedores dentro de tus nodos de GKE para depurar y solucionar problemas. En esta sección, se describe cómo instalar la utilidad toolbox
y usarla para solucionar problemas del nodo.
Cuando estés conectado al nodo, inicia la herramienta de
toolbox
:toolbox
Esta acción descarga los archivos que facilitan la utilidad
toolbox
.En el mensaje raíz
toolbox
, instalatcpdump
:Para clústeres con direcciones IP externas o Cloud NAT:
apt update -y && apt install -y tcpdump
Para clústeres privados sin Cloud NAT:
Si tienes un clúster privado sin Cloud NAT, no puedes instalar
tcpdump
medianteapt
. En su lugar, descarga los archivos de actualizaciónlibpcap
ytcpdump
del repositorio oficial y copia los archivos en la VM mediantegcloud compute scp
ogsutil
. Luego, instala las bibliotecas manualmente con los siguientes pasos:cp /media/root/home/
USER_NAME /tcpdump-VERSION .tar.gz /usr/sbin/ cp /media/root/home/USER_NAME /libpcap-VERSION .tar.gz /usr/sbin/ cd /usr/sbin/ tar -xvzf tcpdump-VERSION .tar.gz tar -xvzf libpcap-VERSION .tar.gz cd libpcap-VERSION ./configure ; make ; make install cd ../tcpdump-VERSION ./configure ; make ; make install tcpdump --versionReemplaza lo siguiente:
USER_NAME
: Tu nombre de usuario en el sistema en el que se encuentran los archivos.VERSION
: El número de versión específico de los paquetestcpdump
ylibpcap
.
Inicia la captura de paquetes:
tcpdump -i eth0 -s 100 "port
PORT " \ -w /media/root/mnt/stateful_partition/CAPTURE_FILE_NAME Reemplaza lo siguiente:
PORT
: el nombre de tu número de puerto.CAPTURE_FILE_NAME
: el nombre de tu archivo de captura.
Detén la captura de paquetes e interrumpe el
tcpdump
.Para salir de la caja de herramientas, escribe
exit
.Enumera el archivo de captura de paquetes y verifica su tamaño:
ls -ltr /mnt/stateful_partition/
CAPTURE_FILE_NAME Copia la captura de paquetes del nodo al directorio de trabajo actual de tu computadora:
gcloud compute scp
NODE_NAME :/mnt/stateful_partition/CAPTURE_FILE_NAME \ --zone=ZONE Reemplaza lo siguiente:
NODE_NAME
: el nombre de tu nodo.CAPTURE_FILE_NAME
: el nombre de tu archivo de captura.ZONE
: el nombre de tu zona.
Comandos alternativos
También puedes usar las siguientes formas para solucionar problemas de conectividad en los Pods problemáticos:
Carga de trabajo de depuración efímera adjunta al contenedor de Pod.
Ejecuta un shell directamente en el Pod de destino con
kubectl exec
y, luego, instala y, luego, inicia el comandotcpdump
.
Problemas de conectividad de red del pod
Como se mencionó en el debate de Descripción general de la red, es importante comprender cómo los Pods están conectados desde sus espacios de nombres de red con el espacio de nombres raíz en el nodo para solucionar problemas de manera efectiva. En el siguiente debate, supone que el clúster usa el CNI nativo de GKE en lugar del de Calico, a menos que se indique lo contrario. Es decir, no se aplicó ninguna política de red.
Los pods en nodos seleccionados no tienen disponibilidad
Si los pods en nodos seleccionados no tienen conectividad de red, asegúrate de que el puente de Linux esté activo:
ip address show cbr0
En caso contrario, actívalo:
sudo ip link set cbr0 up
Asegúrate de que el nodo esté aprendiendo las direcciones MAC de pod adjuntas en cbr0:
arp -an
Los pods en los nodos seleccionados tienen conectividad mínima
Si los pods en los nodos seleccionados tienen una conectividad mínima, primero debes confirmar si hay paquetes perdidos. Para ello, ejecuta tcpdump
en el contenedor de la caja de herramientas:
sudo toolbox bash
Instala tcpdump
en la caja de herramientas si aún no lo hiciste:
apt install -y tcpdump
Ejecuta tcpdump
para cbr0:
tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]
Si parece que los paquetes grandes se descartan más adelante en el puente (por ejemplo, el protocolo de enlace TCP se completa, pero no se reciben saludos SSL), asegúrate de que la MTU para cada interfaz de Pod de Linux esté configurada de manera correcta en la MTU de la red de VPC del clúster.
ip address show cbr0
Cuando se utilizan superposiciones (por ejemplo, Weave o Flannel), esta MTU debe reducirse aún más para acomodar la sobrecarga de encapsulación en la superposición.
MTU de GKE
La MTU seleccionada para una interfaz de Pod depende de la Interfaz de red de contenedor (CNI) que usan los nodos del clúster y la configuración de MTU de VPC subyacente. Para obtener más información, consulta Pods.
El valor de MTU de la interfaz del Pod es 1460
o se hereda de la interfaz principal del nodo.
CNI | MTU | GKE Standard |
---|---|---|
kubenet | 1,460 | Predeterminado |
kubenet (GKE versión 1.26.1 y posteriores) |
Heredada | Predeterminado |
Calico | 1,460 |
Se habilita mediante Para obtener más información, consulta Controla la comunicación entre Pods y Services mediante las políticas de red. |
netd | Heredada | Se habilita mediante cualquiera de las siguientes opciones: |
GKE Dataplane V2 | Heredada |
Se habilita mediante Para obtener más información, consulta Usa GKE Dataplane V2. |
Conexiones fallidas intermitentes
iptables reenvía las conexiones hacia y desde los pods. Los flujos se registran como entradas en la tabla conntrack y, cuando hay muchas cargas de trabajo por nodo, el agotamiento de la tabla de conntrack puede manifestarse como un error. Estos se pueden registrar en la consola en serie del nodo, por ejemplo:
nf_conntrack: table full, dropping packet
Si puedes determinar que los problemas intermitentes se generan debido al agotamiento de conntrack, es recomendable aumentar el tamaño del clúster (y así reducir la cantidad de cargas de trabajo y flujos por nodo) o aumentar nf_conntrack_max
:
new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
&& echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf
También puedes usar NodeLocal DNSCache para reducir las entradas de seguimiento de conexiones.
Se informa un mensaje que dice "vincular: la dirección ya está en uso" para un contenedor
Un contenedor en un pod no puede iniciarse porque, de acuerdo con los registros del contenedor, el puerto al que la aplicación intenta vincularse ya está reservado. El contenedor entra en una falla de repetición. Por ejemplo, en Cloud Logging, se muestra lo siguiente:
resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"
2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use
Cuando Docker falla, a veces un contenedor en ejecución se retrasa y queda inactivo. El proceso todavía se está ejecutando en el espacio de nombres de red asignado para el pod, y está escuchando en su puerto. Debido a que Docker y el kubelet no saben sobre el contenedor inactivo, intentan iniciar un nuevo contenedor con un proceso nuevo, que no puede vincularse en el puerto, ya que se agrega al espacio de nombres de red ya asociado con el pod.
Para diagnosticar este problema, haz lo siguiente:
Necesitas el UUID del pod en el campo
.metadata.uuid
:kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg name UUID ubuntu-6948dd5657-4gsgg db9ed086-edba-11e8-bdd6-42010a800164
Obtén el resultado de los siguientes comandos del nodo:
docker ps -a ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]
Verifica los procesos en ejecución de este pod. Debido a que el UUID de los espacios de nombres de cgroup contiene el UUID del pod, puedes usar el comando grep para buscar el UUID del pod en el resultado
ps
. Usa también el comando grep para analizar la línea anterior, de modo que obtengas los procesosdocker-containerd-shim
que tienen el ID del contenedor en el argumento. Corta el resto de la columna cgroup para obtener un resultado más simple:# ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/ 1283089 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 276e173b0846e24b704d4 12: 1283107 1283089 Ss sys_pause 4026532393 pause /pause 12: 1283150 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim ab4c7762f5abf40951770 12: 1283169 1283150 Ss do_wait 4026532393 sh /bin/sh -c echo hello && sleep 6000000 12: 1283185 1283169 S hrtimer_nanosleep 4026532393 sleep sleep 6000000 12: 1283244 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 44e76e50e5ef4156fd5d3 12: 1283263 1283244 Ss sigsuspend 4026532393 nginx nginx: master process nginx -g daemon off; 12: 1283282 1283263 S ep_poll 4026532393 nginx nginx: worker process
En esta lista, puedes ver los ID de contenedor, que también deben estar visibles en
docker ps
.En este caso, ocurre lo siguiente:
docker-containerd-shim 276e173b0846e24b704d4
para pausardocker-containerd-shim ab4c7762f5abf40951770
para SH con sleep (sleep-ctr)docker-containerd-shim 44e76e50e5ef4156fd5d3
para nginx (echoserver-ctr)
Verifica aquellos en el resultado de
docker ps
:# docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3' 44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f gcr.io/google_containers/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc "nginx -g 'daemon off;'" 14 hours ago Up 14 hours k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475 ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78 "/bin/sh -c 'echo hello && sleep 6000000'" 14 hours ago Up 14 hours k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327 registry.k8s.io/pause-amd64:3.1
En casos normales, verás todos los ID de contenedor de
ps
que aparecen endocker ps
. Si hay uno que no ves, es un contenedor inactivo, y es probable que veas un proceso secundario del procesodocker-containerd-shim process
a la escucha en el puerto TCP que informa que ya está en uso.Para verificar esto, ejecuta
netstat
en el espacio de nombres de red del contenedor. Obtén el pid de cualquier proceso de contenedor (así que NOdocker-containerd-shim
) del pod.En el ejemplo anterior, se incluye lo siguiente:
- 1283107 - pause
- 1283169 - sh
- 1283185 - sleep
- 1283263 - nginx master
- 1283282 - nginx worker
# nsenter -t 1283107 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast
También puedes ejecutar
netstat
medianteip netns
, pero necesitas vincular el espacio de nombres de red del proceso de forma manual, ya que Docker no realiza la vinculación:# ln -s /proc/1283169/ns/net /var/run/netns/1283169 gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list 1283169 (id: 2) gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
Mitigación:
La mitigación a corto plazo consiste en identificar procesos inactivos con el método descrito antes y finalizar los procesos mediante el comando kill [PID]
.
La mitigación a largo plazo implica identificar por qué Docker falla y solucionar el problema. Algunos motivos posibles son los siguientes:
- Los procesos zombie se acumulan, por lo que no hay espacios de nombres PID
- Error en Docker
- Presión de recursos / OOM
¿Qué sigue?
- Para obtener información general sobre el diagnóstico de problemas de DNS de Kubernetes, consulta Depuración de la resolución de DNS.