Contando largura de banda de um contêiner do Docker

13

Estou tentando descobrir como rastrear a largura de banda proveniente de um contêiner do Docker.

Normalmente eu uso --uid-ownercomo marca para acompanhar o uso da largura de banda para um determinado usuário. No entanto, mesmo quando eu executo todos os processos, o usuário dentro do contêiner do docker --uid-ownernão está funcionando. Em vez de usar --uid-owner, tentei apenas rastrear todos os pacotes provenientes do dispositivo Ethernet virtual criado pelo docker.

Isso, no entanto, acabou não fazendo nada também: não importa o que eu tente, nenhum pacote será capturado.

Por puro desespero, tentei colocar as regras em todas as cadeias, mas também não tive 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

Alguém pode me dizer como marcar com êxito pacotes de um contêiner de docker? De preferência usando, --uid-ownermas vou levar qualquer coisa neste momento :)

Maran
fonte

Respostas:

4

O problema está relacionado aos espaços para nome. O Docker os utiliza para isolar recursos, o que também significa que eles não contam para os totais do host.

Quando você executa iptablesno host, basicamente está apenas olhando para o namespace do host e os pacotes nos quais você está interessado são computados no namespace do contêiner. Para contornar esse problema, você ip netnsainda pode executar o iptables no host, mas no namespace de rede do contêiner.

Primeiro, ip netnspossui uma interface um tanto contra-intuitiva. Para se conectar ao espaço para nome de um processo existente (neste caso, seu contêiner), você deve criar um link /var/run/netns/para o espaço para nome do processo:

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

(você pode precisar mkdir /var/run/netns)

Agora você está livre para executar o iptables no namespace do seu contêiner:

# ip netns exec SOME_NAME iptables -L -nv

Observe que isso gera o conjunto de regras do iptables dentro do contêiner, que provavelmente estará vazio.

Se você estiver usando o --uid-owner atualmente apenas para ter contadores por usuário, nem precisará mais dele, porque nesse caso os contadores de cadeia se aplicam apenas ao contêiner e devem ser suficientes.

Finalmente, você pode limpar /var/run/netns.

Vários contêineres por usuário

Se você possui vários contêineres por usuário e deseja juntá-los, é possível iniciar seus contêineres --net=container:OTHER_CONTAINER_FROM_USERpara que os espaços de nomes sejam mesclados.

Isso tem a desvantagem de mesclar todos os aspectos da pilha de rede, incluindo portas abertas, para que você não possa ter dois contêineres para o mesmo usuário ouvindo na mesma porta.

Se essa é uma limitação proibitiva, é possível contabilizar os contêineres individualmente e agrupá-los com base no uid posteriormente.

Você pode encontrar mais informações sobre esse problema aqui .

Leo Antunes
fonte
0

Não é exatamente o que você pediu, mas acho que vai fazer o trabalho.

Citação do blog Docker :

Contadores no nível da interface

Como cada contêiner possui uma interface Ethernet virtual, convém verificar diretamente os contadores TX e RX dessa interface.

[...]

Mas, por enquanto, a melhor maneira é verificar as métricas de dentro dos contêineres. Não estou falando sobre a execução de um agente especial no contêiner, ou algo assim. Vamos executar um executável no ambiente host, mas dentro do namespace de rede de um contêiner.

O formato exato do comando é:

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

Por exemplo:

ip netns exec mycontainer netstat -i

Trisell
fonte
2
Eu reformatei sua resposta fortemente, tente citar recursos de um estilo semelhante em suas respostas futuras para torná-los mais úteis.
fuero