Compter la bande passante d'un conteneur Docker

13

J'essaie de comprendre comment suivre la bande passante provenant d'un conteneur Docker.

Normalement, j'utilise --uid-ownercomme marque pour garder une trace de l'utilisation de la bande passante pour un utilisateur donné. Cependant, même lorsque j'exécute tous les processus, l'utilisateur à l'intérieur du conteneur Docker --uid-ownerne fonctionne pas. Au lieu d'utiliser --uid-owner, j'ai essayé de suivre tous les paquets provenant du périphérique Ethernet virtuel créé par Docker.

Cependant, cela n'a finalement rien fait: peu importe ce que j'essaie, aucun paquet n'est capturé.

Par désespoir, j'ai essayé de mettre les règles dans toutes les chaînes, mais je n'ai eu aucun résultat non plus.

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

Quelqu'un peut-il me dire comment marquer avec succès des packages à partir d'un conteneur Docker? Utiliser de préférence --uid-ownermais je prendrai n'importe quoi à ce stade :)

Maran
la source

Réponses:

4

Le problème est lié aux espaces de noms. Docker les utilise pour isoler les ressources, ce qui signifie également qu'elles ne comptent pas dans les totaux de l'hôte.

Lorsque vous exécutez iptablessur l'hôte, vous ne regardez essentiellement que l'espace de noms de l'hôte, et les paquets qui vous intéressent sont comptabilisés dans l'espace de noms du conteneur. Pour contourner ce problème, vous pouvez utiliser ip netnspour exécuter encore iptables sur l'hôte, mais dans l'espace de noms réseau du conteneur.

Tout d'abord, ip netnspossède une interface quelque peu contre-intuitive. Afin de joindre à l'espace de noms d'un processus existant (dans ce cas, votre conteneur), vous devez créer un lien /var/run/netns/vers l'espace de noms du processus:

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

(vous devrez peut-être mkdir /var/run/netns)

Vous êtes maintenant libre d'exécuter iptables dans l'espace de noms de votre conteneur:

# ip netns exec SOME_NAME iptables -L -nv

Notez que cela génère l'ensemble de règles d'iptables à l'intérieur du conteneur, qui sera probablement vide.

Si vous utilisez actuellement --uid-owner uniquement pour avoir des compteurs par utilisateur, vous n'en avez même plus besoin, car dans ce cas, les compteurs de chaîne s'appliquent uniquement au conteneur et devraient alors suffire.

Enfin, vous pouvez nettoyer /var/run/netns.

Plusieurs conteneurs par utilisateur

Si vous avez plusieurs conteneurs par utilisateur et que vous souhaitez les regrouper, vous pouvez démarrer vos conteneurs avec --net=container:OTHER_CONTAINER_FROM_USER, afin que leurs espaces de noms soient fusionnés.

Cela présente l'inconvénient de fusionner tous les aspects de la pile réseau, y compris les ports ouverts, de sorte que vous ne pouvez pas avoir deux conteneurs pour le même utilisateur écoutant sur le même port.

S'il s'agit d'une limitation prohibitive, vous pouvez comptabiliser les conteneurs individuellement et les regrouper en fonction de l'uid ultérieurement.

Vous pouvez trouver plus d'informations sur ce problème ici .

Leo Antunes
la source
0

Pas exactement ce que vous avez demandé, mais je pense que cela fera l'affaire.

Citation du blog Docker :

Compteurs au niveau de l'interface

Étant donné que chaque conteneur possède une interface Ethernet virtuelle, vous souhaiterez peut-être vérifier directement les compteurs TX et RX de cette interface.

[...]

Mais pour l'instant, le meilleur moyen est de vérifier les métriques à l'intérieur des conteneurs. Je ne parle pas d'exécuter un agent spécial dans le conteneur, ou quelque chose comme ça. Nous allons exécuter un exécutable à partir de l'environnement hôte, mais dans l'espace de noms réseau d'un conteneur.

Le format exact de la commande est:

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

Par exemple:

ip netns exec mycontainer netstat -i

Trisell
la source
2
J'ai reformaté votre réponse en profondeur, essayez de citer des ressources dans un style similaire dans vos réponses futures pour les rendre plus utiles.
fuero