Contando el ancho de banda desde un contenedor Docker

13

Estoy tratando de descubrir cómo rastrear el ancho de banda proveniente de un contenedor Docker.

Normalmente lo uso --uid-ownercomo marca para realizar un seguimiento del uso del ancho de banda para un usuario determinado. Sin embargo, incluso cuando ejecuto todos los procesos ya que el usuario dentro del contenedor docker --uid-ownerno funciona. En lugar de usar --uid-owner, intenté simplemente rastrear todos los paquetes que provienen del dispositivo virtual de Ethernet que crea Docker.

Esto, sin embargo, terminó sin hacer nada: no importa lo que intente, no se capturan paquetes.

Por pura desesperación, intenté simplemente poner las reglas en todas las cadenas, pero tampoco tuve ningún resultado.

Chain PREROUTING (policy ACCEPT 3041 packets, 7849454 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1

Chain INPUT (policy ACCEPT 273 packets, 23305 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1

Chain FORWARD (policy ACCEPT 2750 packets, 7821109 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1
2           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1
3           0        0            all  --  veth5a36 eth0    anywhere             anywhere             mark match 0x1

Chain OUTPUT (policy ACCEPT 293 packets, 80020 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1

Chain POSTROUTING (policy ACCEPT 3043 packets, 7901129 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1

¿Alguien puede decirme cómo marcar con éxito los paquetes desde un contenedor acoplable? Preferiblemente usando --uid-ownerpero tomaré cualquier cosa en este punto :)

Maran
fuente

Respuestas:

4

El problema está relacionado con los espacios de nombres. Docker los usa para aislar recursos, lo que también significa que no cuentan para los totales del host.

Cuando se ejecuta iptablesen el host, básicamente solo está mirando el espacio de nombres del host, y los paquetes que le interesan se contabilizan en el espacio de nombres del contenedor. Para solucionar este problema, puede ip netnsseguir ejecutando iptables en el host, pero en el espacio de nombres de red del contenedor.

Primero, ip netnstiene una interfaz algo intuitiva. Para adjuntar al espacio de nombres de un proceso existente (en este caso su contenedor), debe crear un enlace /var/run/netns/al espacio de nombres del proceso:

# ln -sf /proc/`docker inspect -f '{{ .State.Pid }}' YOUR_CONTAINER`/ns/net /var/run/netns/SOME_NAME

(puede que tenga que mkdir /var/run/netns)

Ahora puede ejecutar iptables en el espacio de nombres de su contenedor:

# ip netns exec SOME_NAME iptables -L -nv

Tenga en cuenta que esto genera el conjunto de reglas de iptables dentro del contenedor, que probablemente estará vacío.

Si actualmente usa --uid-owner solo para tener contadores por usuario, ya ni siquiera lo necesita, porque en este caso los contadores de cadena se aplican solo al contenedor y deberían ser suficientes.

Finalmente, puedes limpiar /var/run/netns .

Múltiples contenedores por usuario

Si tiene varios contenedores por usuario y desea unirlos, puede comenzar sus contenedores con --net=container:OTHER_CONTAINER_FROM_USER para que se fusionen sus espacios de nombres.

Esto tiene la desventaja de fusionar todos los aspectos de la pila de red, incluidos los puertos abiertos, por lo que no puede tener dos contenedores para el mismo usuario escuchando en el mismo puerto.

Si esta es una limitación prohibitiva, puede contar los contenedores individualmente y agruparlos en función de uid más adelante.

Puede encontrar más información sobre este tema aquí .

Leo Antunes
fuente
0

No es exactamente lo que pediste, pero creo que hará el trabajo.

Cita del blog de Docker :

Contadores de nivel de interfaz

Como cada contenedor tiene una interfaz Ethernet virtual, es posible que desee verificar directamente los contadores TX y RX de esta interfaz.

[...]

Pero por ahora, la mejor manera es verificar las métricas desde los contenedores. No estoy hablando de ejecutar un agente especial en el contenedor, ni nada de eso. Vamos a ejecutar un ejecutable desde el entorno host, pero dentro del espacio de nombres de red de un contenedor.

El formato exacto del comando es:

ip netns exec <nsname> <command...>

Por ejemplo:

ip netns exec mycontainer netstat -i

Trisell
fuente
2
Modifiqué mucho su respuesta, intente citar recursos en un estilo similar en sus respuestas futuras para que sean más útiles.
fuero