GNU/Linux >> Tutoriales Linux >  >> Linux

Una introducción a bpftrace para Linux

Bpftrace es un nuevo rastreador de código abierto para Linux para analizar problemas de rendimiento de producción y software de solución de problemas. Sus usuarios y colaboradores incluyen Netflix, Facebook, Red Hat, Shopify y otros, y fue creado por Alastair Robertson, un talentoso desarrollador con sede en el Reino Unido que ganó varios concursos de codificación.

Linux ya tiene muchas herramientas de rendimiento, pero a menudo se basan en contadores y tienen una visibilidad limitada. Por ejemplo, iostat(1) o un agente de monitoreo pueden indicarle la latencia de disco promedio, pero no la distribución de esta latencia. Las distribuciones pueden revelar múltiples modos o valores atípicos, cualquiera de los cuales puede ser la causa real de sus problemas de rendimiento. Bpftrace es adecuado para este tipo de análisis:descomposición de métricas en distribuciones o registros por evento y creación de nuevas métricas para la visibilidad de puntos ciegos.

Puede usar bpftrace a través de frases ingeniosas o scripts, y viene con muchas herramientas preescritas. Aquí hay un ejemplo que rastrea la distribución de la latencia de lectura para PID 181 y lo muestra como un histograma de potencia de dos:

# bpftrace -e 'kprobe:vfs_read /pid == 30153/ { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }'
Attaching 2 probes...
^C

@ns:
[256, 512)         10900 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      |
[512, 1k)          18291 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[1k, 2k)            4998 |@@@@@@@@@@@@@@                                      |
[2k, 4k)              57 |                                                    |
[4k, 8k)             117 |                                                    |
[8k, 16k)             48 |                                                    |
[16k, 32k)           109 |                                                    |
[32k, 64k)             3 |                                                    |

Este ejemplo instrumenta un evento de miles disponibles. Si tiene algún problema de rendimiento extraño, probablemente haya alguna frase de bpftrace que pueda aclararlo. Para entornos grandes, esta capacidad puede ayudarlo a ahorrar millones. Para entornos más pequeños, puede ser más útil para ayudar a eliminar los valores atípicos de latencia.

La terminal de Linux

  • Los 7 mejores emuladores de terminal para Linux
  • 10 herramientas de línea de comandos para el análisis de datos en Linux
  • Descargar ahora:hoja de referencia de SSH
  • Hoja de trucos de comandos avanzados de Linux
  • Tutoriales de línea de comandos de Linux

Anteriormente escribí sobre bpftrace frente a otros rastreadores, incluido BCC (BPF Compiler Collection). BCC es ideal para herramientas y agentes complejos enlatados. Bpftrace es mejor para guiones breves e investigaciones ad hoc. En este artículo, resumiré el lenguaje bpftrace, los tipos de variables, las sondas y las herramientas.

Bpftrace utiliza BPF (Berkeley Packet Filter), un motor de ejecución en el kernel que procesa un conjunto de instrucciones virtuales. BPF se ha ampliado (también conocido como eBPF) en los últimos años para proporcionar una forma segura de ampliar la funcionalidad del núcleo. También se ha convertido en un tema candente en la ingeniería de sistemas, con al menos 24 charlas sobre BPF en la última Linux Plumber's Conference. BPF está en el kernel de Linux y bpftrace es la mejor manera de comenzar a usar BPF para la observabilidad.

Consulte la guía de INSTALACIÓN de bpftrace para saber cómo instalarlo y obtener la última versión; 0.9.2 acaba de ser lanzado. Para los clústeres de Kubernetes, también existe kubectl-trace para ejecutarlo.

Sintaxis

probe[,probe,...] /filter/ { action }

La sonda especifica qué eventos instrumentar. El filtro es opcional y puede filtrar los eventos en función de una expresión booleana, y la acción es el miniprograma que se ejecuta.

Aquí está hola mundo:

# bpftrace -e 'BEGIN { printf("Hello eBPF!\n"); }'

La sonda es BEGIN , una sonda especial que se ejecuta al principio del programa (como awk). No hay filtro. La acción es un printf() declaración.

Ahora un ejemplo real:

# bpftrace -e 'kretprobe:sys_read /pid == 181/ { @bytes = hist(retval); }'

Esto utiliza un kretprobe para instrumentar el retorno de sys_read() función del núcleo. Si el PID es 181, una variable de mapa especial @bytes se rellena con una función de histograma log2 con el valor de retorno retval de sys_read() . Esto produce un histograma del tamaño de lectura devuelto para PID 181. ¿Su aplicación está haciendo muchas lecturas de un byte? Tal vez eso se pueda optimizar.

Tipos de sonda

Estas son bibliotecas de sondas relacionadas. Los tipos admitidos actualmente son (se agregarán más):

    La instrumentación dinámica (también conocida como rastreo dinámico) es el superpoder que le permite rastrear cualquier función de software en un binario en ejecución sin reiniciarlo. Esto le permite llegar al fondo de casi cualquier problema. Sin embargo, las funciones que expone no se consideran una API estable, ya que pueden cambiar de una versión de software a otra. Por lo tanto, la instrumentación estática, donde los puntos de eventos están codificados y se convierten en una API estable. Cuando escriba programas bpftrace, trate de usar primero los tipos estáticos, antes de los dinámicos, para que sus programas sean más estables.

    Tipos de variables

    Tipo Descripción
    punto de seguimiento Puntos de instrumentación estática del kernel
    usdt Seguimiento definido estáticamente a nivel de usuario
    kprobe Instrumentación de funciones dinámicas del kernel
    kretprobe Instrumentación de devolución de funciones dinámicas del kernel
    sondeo Instrumentación de funciones dinámicas a nivel de usuario
    uretprobe Instrumentación de retorno de funciones dinámicas a nivel de usuario
    software Eventos basados ​​en software del kernel
    hardware Instrumentación basada en contador de hardware
    punto de vigilancia Eventos de punto de observación de memoria (en desarrollo)
    perfil Muestreo temporizado en todas las CPU
    intervalo Informes cronometrados (desde una CPU)
    COMENZAR Inicio de bpftrace
    FIN Fin de bpftrace

      Variables con @ El prefijo usa mapas BPF, que pueden comportarse como matrices asociativas. Se pueden completar de una de dos maneras:

      • Asignación de variables:@name =x;
      • Asignación de funciones:@nombre =hist(x);

      Varias funciones de llenado de mapas están integradas para proporcionar formas rápidas de resumir datos.

      Variables y funciones integradas

      Estas son algunas de las variables y funciones integradas, pero hay muchas más.

      Variables integradas:

      Variable Descripción
      @nombre globales
      @nombre[clave] hash
      @nombre[tid] subproceso local
      $nombre rasguño

        Funciones integradas:

        Variable Descripción
        pid identificación del proceso
        comunicación Nombre de proceso o comando
        nsegs Hora actual en nanosegundos
        kstack Seguimiento de la pila del kernel
        ustack Seguimiento de pila a nivel de usuario
        arg0...argN Argumentos de función
        argumentos Argumentos de punto de seguimiento
        recuperación Valor de retorno de la función
        nombre Nombre completo de la sonda

          Consulte la guía de referencia para obtener más información.

          Tutorial de frases sencillas

          Una excelente manera de aprender bpftrace es a través de frases ingeniosas, que convertí en un tutorial de frases ingeniosas que cubre lo siguiente:

          Función Descripción
          printf("...") Imprimir cadena con formato
          hora("...") Imprimir hora formateada
          sistema("...") Ejecutar comando de shell
          @ =cuenta() Contar eventos
          @ =hist(x) Histograma potencia de 2 para x
          @ =lhist(x, min, max, paso) Histograma lineal para x

          Consulte el tutorial para obtener una explicación de cada uno.

          Herramientas provistas

          Aparte de las frases ingeniosas, los programas bpftrace pueden ser scripts de varias líneas. Bpftrace se envía con 28 de ellos como herramientas:

          Estos se pueden encontrar en /herramientas directorio:

          tools# ls *.bt
          bashreadline.bt  dcsnoop.bt         oomkill.bt    syncsnoop.bt   vfscount.bt
          biolatency.bt    execsnoop.bt       opensnoop.bt  syscount.bt    vfsstat.bt
          biosnoop.bt      gethostlatency.bt  pidpersec.bt  tcpaccept.bt   writeback.bt
          bitesize.bt      killsnoop.bt       runqlat.bt    tcpconnect.bt  xfsdist.bt
          capable.bt       loads.bt           runqlen.bt    tcpdrop.bt
          cpuwalk.bt       mdflush.bt         statsnoop.bt  tcpretrans.bt

          Aparte de su uso en el diagnóstico de problemas de rendimiento y la resolución de problemas generales, también proporcionan otra forma de aprender bpftrace. Estos son algunos ejemplos.

          Fuente

          Aquí está el código para biolatency.bt :

          tools# cat -n biolatency.bt
               1  /*
               2   * biolatency.bt    Block I/O latency as a histogram.
               3   *                  For Linux, uses bpftrace, eBPF.
               4   *
               5   * This is a bpftrace version of the bcc tool of the same name.
               6   *
               7   * Copyright 2018 Netflix, Inc.
               8   * Licensed under the Apache License, Version 2.0 (the "License")
               9   *
              10   * 13-Sep-2018  Brendan Gregg   Created this.
              11   */
              12
              13  BEGIN
              14  {
              15          printf("Tracing block device I/O... Hit Ctrl-C to end.\n");
              16  }
              17
              18  kprobe:blk_account_io_start
              19  {
              20          @start[arg0] = nsecs;
              21  }
              22
              23  kprobe:blk_account_io_done
              24  /@start[arg0]/
              25
              26  {
              27          @usecs = hist((nsecs - @start[arg0]) / 1000);
              28          delete(@start[arg0]);
              29  }
              30 
              31  END
              32  {
              33          clear(@start);
              34  }

          Es sencillo, fácil de leer y lo suficientemente breve como para incluirlo en una diapositiva. Esta versión utiliza el seguimiento dinámico del núcleo para instrumentar blk_account_io_start() y blk_account_io_done() funciones, y pasa una marca de tiempo entre ellas tecleada en arg0 a cada. arg0 en kprobe es el primer argumento de esa función, que es la solicitud de estructura * y su dirección de memoria se utiliza como un identificador único.

          Archivos de ejemplo

          Puede ver capturas de pantalla y explicaciones de estas herramientas en el repositorio de GitHub como *_example.txt archivos Por ejemplo:

          tools# more biolatency_example.txt
          Demonstrations of biolatency, the Linux BPF/bpftrace version.


          This traces block I/O, and shows latency as a power-of-2 histogram. For example:

          # biolatency.bt
          Attaching 3 probes...
          Tracing block device I/O... Hit Ctrl-C to end.
          ^C

          @usecs:
          [256, 512)             2 |                                                    |
          [512, 1K)             10 |@                                                   |
          [1K, 2K)             426 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
          [2K, 4K)             230 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
          [4K, 8K)               9 |@                                                   |
          [8K, 16K)            128 |@@@@@@@@@@@@@@@                                     |
          [16K, 32K)            68 |@@@@@@@@                                            |
          [32K, 64K)             0 |                                                    |
          [64K, 128K)            0 |                                                    |
          [128K, 256K)          10 |@                                                   |

          While tracing, this shows that 426 block I/O had a latency of between 1K and 2K
          usecs (1024 and 2048 microseconds), which is between 1 and 2 milliseconds.
          There are also two modes visible, one between 1 and 2 milliseconds, and another
          between 8 and 16 milliseconds: this sounds like cache hits and cache misses.
          There were also 10 I/O with latency 128 to 256 ms: outliers. Other tools and
          instrumentation, like biosnoop.bt, can shed more light on those outliers.
          [...]

          A veces puede ser más efectivo cambiar directamente al archivo de ejemplo cuando se trata de comprender estas herramientas, ya que el resultado puede ser evidente (¡por diseño!).

          Páginas man

          También hay páginas man para cada herramienta en el repositorio de GitHub en /man/man8. Incluyen secciones sobre los campos de salida y la sobrecarga esperada de la herramienta.

          # nroff -man man/man8/biolatency.8
          biolatency(8)               System Manager's Manual              biolatency(8)



          NAME
                 biolatency.bt - Block I/O latency as a histogram. Uses bpftrace/eBPF.

          SYNOPSIS
                 biolatency.bt

          DESCRIPTION
                 This  tool  summarizes  time  (latency) spent in block device I/O (disk
                 I/O) as a power-of-2 histogram. This  allows  the  distribution  to  be
                 studied,  including  modes and outliers. There are often two modes, one
                 for device cache hits and one for cache misses, which can be  shown  by
                 this tool. Latency outliers will also be shown.
          [...]

          Escribir todas estas páginas man fue la parte menos divertida del desarrollo de estas herramientas, y algunas tardaron más en escribirse que la herramienta en desarrollarse, pero es bueno ver el resultado final.

          bpftrace vs. BCC

          Dado que eBPF se ha estado fusionando en el kernel, la mayor parte del esfuerzo se ha puesto en la interfaz de BCC, que proporciona una biblioteca BPF e interfaces Python, C++ y Lua para escribir programas. He desarrollado muchas herramientas en BCC/Python; funciona muy bien, aunque la codificación en BCC es detallada. Si está solucionando un problema de rendimiento, bpftrace es mejor para sus consultas personalizadas únicas. Si está escribiendo una herramienta con muchas opciones de línea de comandos o un agente que usa bibliotecas de Python, querrá considerar usar BCC.

          En el equipo de desempeño de Netflix, usamos BCC para desarrollar herramientas enlatadas que otros pueden usar fácilmente y para desarrollar agentes; y bpftrace para análisis ad hoc. El equipo de ingeniería de red ha estado utilizando BCC para desarrollar un agente para sus necesidades. El equipo de seguridad está más interesado en bpftrace para una instrumentación ad hoc rápida para detectar vulnerabilidades de día cero. Y espero que los equipos de desarrolladores usen ambos sin saberlo, a través de las GUI de autoservicio que estamos construyendo (Vector), y ocasionalmente pueden SSH en una instancia y ejecutar una herramienta enlatada o bpftrace ad hoc one-liner.

          Más información

          • El repositorio bpftrace en GitHub
          • Tutorial de frases ingeniosas de bpftrace
          • La guía de referencia de bpftrace
          • El repositorio BCC para herramientas más complejas basadas en BPF

          También tengo un libro que saldrá este año que cubre bpftrace:BPF Performance Tools:Linux System and Application Observability , que será publicado por Addison Wesley, y que contiene muchas herramientas nuevas de bpftrace.


          Gracias a Alastair Robertson por crear bpftrace y a las comunidades de bpftrace, BCC y BPF por todo el trabajo de los últimos cinco años.


          Linux
          1. Comandos de FreeDOS para fanáticos de Linux

          2. Introducción a Nmap en Kali Linux

          3. 10 comandos de Linux para diagnóstico de red

          4. Una introducción a los firewalls de aplicaciones web para administradores de sistemas Linux

          5. Una breve introducción a los roles de Ansible para la administración del sistema Linux

          Las mejores distribuciones para juegos en Linux

          25 libros gratuitos para aprender Linux gratis

          Introducción a la gestión de contenedores de Linux

          Una introducción rápida al sistema de archivos de Linux para usuarios de Windows.

          Una introducción a Cockpit, una herramienta de administración basada en navegador para Linux

          Zorin OS para principiantes de Linux

            Lista de sondas bpftrace -l 'tracepoint:syscalls:sys_enter_*'
            Hola mundo bpftrace -e 'COMENZAR { printf("hola mundo\n") }'
            El archivo se abre bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->nombre de archivo)) }'
            Recuentos de Syscall por proceso bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] =cuenta() }'
            Distribución de bytes de lectura() bpftrace -e 'tracepoint:syscalls:sys_exit_read /pid ==18644/ { @bytes =hist(args->retval) }'
            Rastreo dinámico del kernel de bytes read() bpftrace -e 'kretprobe:vfs_read { @bytes =lhist(retval, 0, 2000, 200) }'
            Tiempos de lectura() bpftrace -e 'kprobe:vfs_read { @start[tid] =nsecs } kretprobe:vfs_read /@start[tid]/ { @ns[comm] =hist(nsecs - @start[tid]); eliminar(@start[tid]) }'
            Contar eventos a nivel de proceso bpftrace -e 'tracepoint:sched:sched* { @[nombre] =cuenta() } intervalo:s:5 { salida() }'
            Perfil de pilas de kernel en la CPU bpftrace -e 'perfil:hz:99 { @[pila] =cuenta() }'
            Seguimiento del programador bpftrace -e 'tracepoint:sched:sched_switch { @[pila] =cuenta() }'
            Bloquear E/S bpftrace -e 'tracepoint:block:block_rq_issue { @ =hist(args->bytes); }
            Seguimiento de la estructura del kernel (un script, no una sola línea) Comando: bpftrace path.bt , donde el archivo path.bt es:



            #include

            #include




            kprobe:vfs_open { printf("abrir ruta:%s\n", str(((ruta *)arg0)->entry->d_name .nombre)); }