Complemento Kubectl-debug para depurar en pods de Kubernetes



A finales del año pasado, Reddit introdujo un complemento para kubectl, que ayuda a depurar en las vainas del clúster de Kubernetes : kubectl-debug . Esta idea inmediatamente pareció interesante y útil para nuestros ingenieros, por lo que decidimos analizar su implementación y estamos felices de compartir nuestros resultados con los lectores del Habra.

¿Por qué es esto necesario?


Por el momento, existe un grave inconveniente en el proceso de depuración de algo dentro del marco de los pods. El objetivo principal al ensamblar la imagen del contenedor es minimizarlo , es decir hazlo lo más pequeño posible y que contenga el menor "exceso" posible en su interior. Sin embargo, cuando se trata de problemas en la operación del software final en contenedores o la depuración de su comunicación con otros servicios en el clúster / exterior ... el minimalismo nos juega un truco, después de todo, no hay nada en los contenedores para el proceso real de encontrar problemas. Como regla general, las utilidades como netstat / ip / ping / curl / wget, etc. no están disponibles.

Y a menudo todo termina con el hecho de que el ingeniero prepara el software necesario directamente en el contenedor en ejecución para "ver" y ver el problema. Fue para tales casos que el complemento kubectl-debug parecía una herramienta muy útil, ya que salva del dolor urgente.

Con su ayuda, puede iniciar un contenedor con todas las herramientas necesarias a bordo en el contexto de un pod de problema con un comando y estudiar todos los procesos "desde afuera", mientras está dentro. Si alguna vez te has encontrado con la solución de problemas de Kubernetes ahora, eso suena atractivo, ¿no?

¿Qué es este complemento?


En términos generales, la arquitectura de esta solución parece un paquete del complemento para kubectl y un agente que comienza a usar el controlador DaemonSet. El complemento sirve comandos que comienzan con kubectl debug … e interactúa con agentes en los nodos del clúster. El agente, a su vez, se ejecuta en la red del host, y el host docker.sock está montado en el pod del agente para tener acceso completo a los contenedores en este servidor.

En consecuencia, cuando solicite iniciar un contenedor de depuración en el pod especificado:
hay un proceso para identificar el hostIP , y se envía una solicitud al agente (trabajando en un host adecuado) para iniciar un contenedor de depuración en los espacios de nombres correspondientes al pod de destino.

Una vista más detallada de estos pasos está disponible en la documentación del proyecto .

¿Qué se requiere para trabajar?


El autor de kubectl-debug afirma ser compatible con las versiones del cliente / clúster Kubernetes 1.12.0+ , sin embargo, tenía K8s 1.10.8 a mano, en el que todo funcionaba sin problemas visibles ... con una sola nota: para que el equipo de kubectl debug funcione De esta forma, la versión de Kubectl es exactamente 1.12+ . De lo contrario, todos los comandos son similares, pero solo se kubectl-debug … mediante kubectl-debug …

Cuando inicie la plantilla DaemonSet descrita en README no debe olvidarse de la contaminación que usa en los nodos: sin las tolerancias apropiadas, las cápsulas del agente no se asentarán allí y, como resultado, no podrá utilizar las cápsulas que viven en dichos nodos Se puede conectar con un depurador.

La Ayuda del depurador es muy completa y parece describir todas las posibilidades actuales para iniciar / configurar el complemento. En general, la utilidad satisface una gran cantidad de directivas para ejecutar: puede adjuntar certificados, especificar el contexto de kubectl, especificar una configuración de kubectl o la dirección del servidor API del clúster, y más.

Trabaja con un depurador


La instalación hasta el momento en que "todo funciona" se reduce a dos etapas:

  1. ejecutar kubectl apply -f agent_daemonset.yml ;
  2. instale directamente el complemento en sí mismo; en general, todo es como se describe aquí .

¿Cómo usarlo? Supongamos que tenemos el siguiente problema: las métricas de uno de los servicios en el clúster no se recopilan, y queremos verificar si hay problemas de red entre Prometheus y el servicio de destino. Como puede suponer, la imagen de Prometheus carece de las herramientas necesarias.

Intentemos conectarnos al contenedor con Prometheus (si hay varios contenedores en el pod, necesitará especificar a cuál conectarse, de lo contrario el depurador seleccionará el primero por defecto):

 kubectl-debug --namespace kube-prometheus prometheus-main-0 Defaulting container name to prometheus. pulling image nicolaka/netshoot:latest... latest: Pulling from nicolaka/netshoot 4fe2ade4980c: Already exists ad6ddc9cd13b: Pull complete cc720038bf2b: Pull complete ff17a2bb9965: Pull complete 6fe9f5dade08: Pull complete d11fc7653a2e: Pull complete 4bd8b4917a85: Pull complete 2bd767dcee18: Pull complete Digest: sha256:897c19b0b79192ee5de9d7fb40d186aae3c42b6e284e71b93d0b8f1c472c54d3 Status: Downloaded newer image for nicolaka/netshoot:latest starting debug container... container created, open tty... [1] → root @ / 

Anteriormente, descubrimos que el servicio problemático vive en la dirección 10.244.1.214 y escucha en el puerto 8080. Por supuesto, también podemos verificar la disponibilidad de los hosts, sin embargo, para un proceso de depuración confiable, estas operaciones deben reproducirse en condiciones idénticas (o lo más cercanas posible). Por lo tanto, verificar desde un pod / contenedor con Prometheus es la mejor opción. Comencemos con uno simple:

  [1] → ping 10.244.1.214 PING 10.244.1.214 (10.244.1.214) 56(84) bytes of data. 64 bytes from 10.244.1.214: icmp_seq=1 ttl=64 time=0.056 ms 64 bytes from 10.244.1.214: icmp_seq=2 ttl=64 time=0.061 ms 64 bytes from 10.244.1.214: icmp_seq=3 ttl=64 time=0.047 ms 64 bytes from 10.244.1.214: icmp_seq=4 ttl=64 time=0.049 ms ^C --- 10.244.1.214 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 61ms rtt min/avg/max/mdev = 0.047/0.053/0.061/0.007 ms 

Todo esta bien. Tal vez el puerto no está disponible?

  [1] → curl -I 10.244.1.214:8080 HTTP/1.1 200 OK Date: Sat, 12 Jan 2019 14:01:29 GMT Content-Length: 143 Content-Type: text/html; charset=utf-8 

Y no hay problema. Luego verificaremos si la comunicación real entre Prometheus y el punto final con métricas se lleva a cabo:

  [2] → tcpdump host 10.244.1.214 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 14:04:19.234101 IP prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278 > 10.244.1.214.8080: Flags [P.], seq 4181259750:4181259995, ack 2078193552, win 1444, options [nop,nop,TS val 3350532304 ecr 1334757657], length 245: HTTP: GET /metrics HTTP/1.1 14:04:19.234158 IP 10.244.1.214.8080 > prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278: Flags [.], ack 245, win 1452, options [nop,nop,TS val 1334787600 ecr 3350532304], length 0 14:04:19.290904 IP 10.244.1.214.8080 > prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278: Flags [P.], seq 1:636, ack 245, win 1452, options [nop,nop,TS val 1334787657 ecr 3350532304], length 635: HTTP: HTTP/1.1 200 OK 14:04:19.290923 IP prometheus-main-0.prometheus-operated.kube-prometheus.svc.cluster.local.36278 > 10.244.1.214.8080: Flags [.], ack 636, win 1444, options [nop,nop,TS val 3350532361 ecr 1334787657], length 0 ^C 4 packets captured 4 packets received by filter 0 packets dropped by kernel 

Las solicitudes de respuestas vienen. En base a los resultados de estas operaciones, podemos concluir que no hay problemas a nivel de interacción de red, lo que significa (muy probablemente) que debe mirar desde el lado aplicado. Nos conectamos al contenedor con el exportador (también, por supuesto, usando el depurador en cuestión, porque los exportadores siempre tienen imágenes extremadamente minimalistas) y ... nos sorprende descubrir que hay un problema en la configuración del servicio; por ejemplo, olvidamos dirigir al exportador al correcto Dirección de solicitud de destino ¡El caso está resuelto!

Por supuesto, otras formas de depuración son posibles en la situación descrita aquí, pero las dejaremos fuera del alcance del artículo. El resultado es que kubectl-debug tiene muchas oportunidades de uso: puede ejecutar cualquier imagen en el trabajo y, si lo desea, incluso puede ensamblar alguna específica (con el conjunto de herramientas necesarias).

¿Qué otras aplicaciones vienen a la mente de inmediato?

  • Una aplicación "silenciosa", en la cual los desarrolladores dañinos no implementaron el registro normal. Pero tiene la capacidad de conectarse al puerto de servicio y depurar con una herramienta específica, que, por supuesto, no debe colocarse en la imagen final.
  • Inicie al lado de la aplicación de combate idéntica en modo "manual", pero con la depuración activada, para verificar la interacción con los servicios vecinos.

En general, es obvio que hay muchas más situaciones en las que dicha herramienta puede ser útil. Los ingenieros que los encuentren en el trabajo todos los días podrán evaluar el potencial de la empresa en términos de depuración "en vivo".

Conclusiones


Kubectl-debug es una herramienta útil y prometedora. Por supuesto, hay grupos y aplicaciones de Kubernetes para los que no tiene mucho sentido, pero todavía hay casos más probables en los que proporcionará una ayuda invaluable en la depuración, especialmente si se trata del entorno de combate y la necesidad de encontrar rápidamente las razones, aquí y ahora. el problema que has encontrado

La primera experiencia de uso reveló una necesidad urgente de la capacidad de conectarse a un pod / contenedor, que no se inicia hasta el final (por ejemplo, se cuelga en CrashLoopbackOff ), solo para verificar sobre la marcha los motivos por los que la aplicación no se inicia. En esta ocasión, creé un problema correspondiente en el repositorio del proyecto, al que el desarrollador respondió positivamente y prometió la implementación en un futuro próximo. Muy satisfecho con los comentarios rápidos y adecuados. Por lo tanto, ¡esperamos nuevas características de la utilidad y su desarrollo posterior!

PS


Lea también en nuestro blog:

Source: https://habr.com/ru/post/es436112/


All Articles