Tutoriales

Captura paquetes en Kubernetes con esta herramienta de código abierto

La creación de redes es una habilidad esencial del administrador de sistemas, pero a menudo se pasa por alto. Muchos administradores de sistemas consideran que los temas de redes son desafiantes y es difícil progresar desde las habilidades básicas de redes hasta las habilidades avanzadas de resolución de problemas sin una práctica regular. Probablemente es por eso que las redes son un tema candente en Habilitar Sysadmin.

Kubernetes y sus extensiones relacionadas, como mallas de servicio, introducen complejidades de red adicionales que los administradores deben estar preparados para enfrentar.Herramientas básicas de networking como ping y traceroute, puede ser útil durante la fase inicial de solución de problemas. Sin embargo, siempre he descubierto que mirar los paquetes que pasan por el cable es la mejor manera de solucionar y comprender problemas complejos de protocolo y nivel de aplicación.

Este artículo presenta ksniff, una excelente herramienta de código abierto que he estado usando. Ksniff es un complemento para kubectl que le permite capturar paquetes en pods de Kubernetes. Le mostraré cómo capturar, filtrar y guardar paquetes para su posterior análisis. ¡Empecemos!

Descargo de responsabilidad: las técnicas descritas en este artículo solo deben usarse en un entorno de desarrollo con pleno conocimiento de lo que está haciendo. La documentación oficial de ksniff aún no lo recomienda para uso en producción, debe tener en cuenta que carga un binario tcpdump precompilado en un pod en ejecución.

Instalar ksniff y herramientas relacionadas

Ksniff es un complemento para kubectl que debe instalar antes de poder comenzar a usarlo. Las instrucciones oficiales de instalación de ksniff recomiendan usar el administrador de complementos Krew, que es mi método de instalación preferido. Puede encontrar instrucciones de instalación para Krew en el sitio web del proyecto. Después de instalar Krew, puede instalar ksniff con un solo comando:

$ kubectl krew install sniff
Updated the local copy of plugin index.
Installing plugin: sniff
Installed plugin: sniff
\
 | Use this plugin:
 | 	kubectl sniff
 | Documentation:
 | 	https://github.com/eldadru/ksniff
 | Caveats:
 | \
 |  | This plugin needs the following programs:
 |  | * wireshark (optional, used for live capture)
 | /
/
WARNING: You installed plugin "sniff" from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.

Si desea rastrear y ver paquetes capturados en una interfaz gráfica de usuario (GUI) o terminal, también debe instalar Wireshark y tshark.

[ You might be wondering: Red Hat OpenShift and Kubernetes … what’s the difference? ]

Configurar la carga de trabajo para la prueba

La mejor manera de comenzar con ksniff es realizar la captura de paquetes en una carga de trabajo familiar, como un servidor web básico. Recomiendo un pod Nginx simple que puede ejecutar con un comando. Estos ejemplos implementan una carga de trabajo simple en una instalación de K0s de un solo nodo que se ejecuta en mi estación de trabajo:

$ kubectl run --image=nginx nginx
pod/nginx created

$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          4s

Una vez que el pod se está ejecutando, puede exponerlo como un servicio de NodePort. Si bien la mayoría de los administradores generalmente evitan usar los servicios de NodePort en entornos de producción, brindan una manera conveniente de probar los servicios rápidamente:

$ kubectl expose pod nginx --port 80 --type=NodePort
service/nginx exposed

$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1               443/TCP        2d5h
nginx        NodePort    10.99.139.251           80:32209/TCP   2s

Finalmente, puede confirmar que el servicio está operativo con una simple acción curl Al servicio NodePort:

$ kubectl get nodes -o wide
NAME            STATUS   ROLES           AGE    VERSION       INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION    CONTAINER-RUNTIME
acritelli-k8s   Ready    control-plane   3d5h   v1.23.3+k0s   10.10.0.207           Ubuntu 20.04.4 LTS   5.14.0-1029-oem   containerd://1.5.9

$ curl 10.10.0.207:32209



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

[ Free online course: Red Hat Enterprise Linux technical overview. ]

captura de paquetes

Con ksniff instalado y pods en ejecución, es hora de capturar algo de tráfico de red.corriendo kubectl sniff $POD_NAME Comenzará una captura de paquetes, se iniciará Wireshark y la captura de paquetes se enviará directamente a Wireshark:

$ kubectl sniff nginx
INFO[0000] using tcpdump path at: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' 
INFO[0000] no container specified, taking first container we found in pod. 
INFO[0000] selected container: 'nginx'                  
INFO[0000] sniffing method: upload static tcpdump       
INFO[0000] sniffing on pod: 'nginx' [namespace: 'default', container: 'nginx', filter: '', interface: 'any'] 
INFO[0000] uploading static tcpdump binary from: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to: '/tmp/static-tcpdump' 
INFO[0000] uploading file: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to '/tmp/static-tcpdump' on container: 'nginx' 
INFO[0000] executing command: '[/bin/sh -c test -f /tmp/static-tcpdump]' on container: 'nginx', pod: 'nginx', namespace: 'default' 
INFO[0000] command: '[/bin/sh -c test -f /tmp/static-tcpdump]' executing successfully exitCode: '0', stdErr :'' 
INFO[0000] file found: ''                               
INFO[0000] file was already found on remote pod         
INFO[0000] tcpdump uploaded successfully                
INFO[0000] spawning wireshark!                          
INFO[0000] start sniffing on remote container           
INFO[0000] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'nginx', pod: 'nginx', namespace: 'default'
(Anthony Critley, CC BY-SA 4.0)

[ Get this free eBook: Managing your Kubernetes clusters for dummies. ]

Si prefiere quedarse completamente con la interfaz de línea de comandos (por ejemplo, si está en un servidor remoto), también puede enviar la salida de ksniff al programa de terminal tshark:

$ kubectl sniff nginx -o - | tshark -r -
INFO[0000] using tcpdump path at: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' 
INFO[0000] no container specified, taking first container we found in pod. 
INFO[0000] selected container: 'nginx'                  
INFO[0000] sniffing method: upload static tcpdump       
INFO[0000] sniffing on pod: 'nginx' [namespace: 'default', container: 'nginx', filter: '', interface: 'any'] 
INFO[0000] uploading static tcpdump binary from: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to: '/tmp/static-tcpdump' 
INFO[0000] uploading file: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to '/tmp/static-tcpdump' on container: 'nginx' 
INFO[0000] executing command: '[/bin/sh -c test -f /tmp/static-tcpdump]' on container: 'nginx', pod: 'nginx', namespace: 'default' 
INFO[0000] command: '[/bin/sh -c test -f /tmp/static-tcpdump]' executing successfully exitCode: '0', stdErr :'' 
INFO[0000] file found: ''                               
INFO[0000] file was already found on remote pod         
INFO[0000] tcpdump uploaded successfully                
INFO[0000] output file option specified, storing output in: '-' 
INFO[0000] start sniffing on remote container           
INFO[0000] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'nginx', pod: 'nginx', namespace: 'default' 
    1   0.000000   10.244.0.1 → 10.244.0.18  TCP 76 29681 → 80 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM=1 TSval=420487628 TSecr=0 WS=128
    2   0.000023  10.244.0.18 → 10.244.0.1   TCP 76 80 → 29681 [SYN, ACK] Seq=0 Ack=1 Win=64260 Len=0 MSS=1440 SACK_PERM=1 TSval=3356168433 TSecr=420487628 WS=128
    3   0.000040   10.244.0.1 → 10.244.0.18  TCP 68 29681 → 80 [ACK] Seq=1 Ack=1 Win=65536 Len=0 TSval=420487628 TSecr=3356168433
    4   0.000069   10.244.0.1 → 10.244.0.18  HTTP 149 GET / HTTP/1.1 
    5   0.000072  10.244.0.18 → 10.244.0.1   TCP 68 80 → 29681 [ACK] Seq=1 Ack=82 Win=64256 Len=0 TSval=3356168433 TSecr=420487628
    6   0.000160  10.244.0.18 → 10.244.0.1   TCP 306 HTTP/1.1 200 OK  [TCP segment of a reassembled PDU]
    7   0.000178   10.244.0.1 → 10.244.0.18  TCP 68 29681 → 80 [ACK] Seq=82 Ack=239 Win=65408 Len=0 TSval=420487628 TSecr=3356168433
    8   0.000192  10.244.0.18 → 10.244.0.1   HTTP 683 HTTP/1.1 200 OK  (text/html)
    9   0.000198   10.244.0.1 → 10.244.0.18  TCP 68 29681 → 80 [ACK] Seq=82 Ack=854 Win=64896 Len=0 TSval=420487628 TSecr=3356168433
   10   0.000296   10.244.0.1 → 10.244.0.18  TCP 68 29681 → 80 [FIN, ACK] Seq=82 Ack=854 Win=65536 Len=0 TSval=420487628 TSecr=3356168433
   11   0.000326  10.244.0.18 → 10.244.0.1   TCP 68 80 → 29681 [FIN, ACK] Seq=854 Ack=83 Win=64256 Len=0 TSval=3356168433 TSecr=420487628
   12   0.000354   10.244.0.1 → 10.244.0.18  TCP 68 29681 → 80 [ACK] Seq=83 Ack=855 Win=65536 Len=0 TSval=420487628 TSecr=3356168433
^C⏎  

El análisis en tiempo real es útil, pero también es común guardar las capturas de paquetes para un análisis posterior. Esto es especialmente útil si está capturando paquetes en una máquina que no tiene acceso a Wireshark o tshark, como un host de salto. Puede escribir paquetes en un archivo especificando la salida de ksniff. Puede abrir el archivo guardado en un analizador de protocolos como Wireshark:

$ k sniff nginx -o /tmp/nginx_capture.pcap
INFO[0000] using tcpdump path at: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' 
INFO[0000] no container specified, taking first container we found in pod. 
INFO[0000] selected container: 'nginx'                  
INFO[0000] sniffing method: upload static tcpdump       
INFO[0000] sniffing on pod: 'nginx' [namespace: 'default', container: 'nginx', filter: '', interface: 'any'] 
INFO[0000] uploading static tcpdump binary from: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to: '/tmp/static-tcpdump' 
INFO[0000] uploading file: '/home/acritelli/.krew/store/sniff/v1.6.2/static-tcpdump' to '/tmp/static-tcpdump' on container: 'nginx' 
INFO[0000] executing command: '[/bin/sh -c test -f /tmp/static-tcpdump]' on container: 'nginx', pod: 'nginx', namespace: 'default' 
INFO[0000] command: '[/bin/sh -c test -f /tmp/static-tcpdump]' executing successfully exitCode: '0', stdErr :'' 
INFO[0000] file found: ''                               
INFO[0000] file was already found on remote pod         
INFO[0000] tcpdump uploaded successfully                
INFO[0000] output file option specified, storing output in: '/tmp/nginx_capture.pcap' 
INFO[0000] start sniffing on remote container           
INFO[0000] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'nginx', pod: 'nginx', namespace: 'default' 
^C⏎

$ file /tmp/nginx_capture.pcap 
/tmp/nginx_capture.pcap: pcap capture file, microsecond ts (little-endian) - version 2.4 (Linux cooked v1, capture length 262144)

Las capturas de paquetes pueden volverse muy complicadas, especialmente para los pods que ejecutan cargas de trabajo complejas o de alta utilización. La capacidad de aplicar filtros tcpdump es fundamental para simplificar las capturas de paquetes complejos, y ksniff admite esto desde el primer momento:

$ kubectl sniff nginx -f "tcp port 80"

envolver

Este artículo le muestra cómo usar ksniff para capturar paquetes en un pod de Kubernetes en ejecución. Las capturas de paquetes brindan una forma poderosa de observar y solucionar problemas complejos de redes y aplicaciones, y su aplicabilidad se vuelve más importante a medida que los entornos se vuelven más complejos.

Realizar una captura de paquetes también es una excelente manera de mejorar sus habilidades de red y profundizar su comprensión de entornos complejos, por lo que le recomiendo que aproveche una herramienta como ksniff en cada oportunidad disponible. ¡Buena suerte y feliz networking!

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Botón volver arriba