Zählen der Bandbreite eines Docker-Containers

13

Ich versuche herauszufinden, wie man die Bandbreite eines Docker-Containers verfolgt.

Normalerweise verwende ich --uid-ownerals Markierung, um die Bandbreitennutzung für einen bestimmten Benutzer zu verfolgen. Selbst wenn ich alle Prozesse als Benutzer innerhalb des Docker-Containers ausführe, --uid-ownerfunktioniert dies nicht. Anstatt zu verwenden --uid-owner, habe ich versucht, alle Pakete zu verfolgen, die von dem virtuellen Ethernet-Gerät stammen, das Docker erstellt.

Dies hat jedoch auch nichts bewirkt: Egal was ich versuche, es werden keine Pakete abgefangen.

Aus purer Verzweiflung habe ich versucht, die Regeln in alle Ketten zu schreiben, aber ich hatte auch kein Ergebnis.

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

Kann mir jemand sagen, wie man erfolgreich Pakete aus einem Docker-Container markiert? --uid-ownerAm liebsten benutze ich aber ich werde an dieser Stelle nichts nehmen :)

Maran
quelle

Antworten:

4

Das Problem hängt mit Namespaces zusammen. Docker verwendet sie, um Ressourcen zu isolieren. Dies bedeutet auch, dass sie nicht zu den Gesamtsummen des Hosts zählen.

Wenn Sie iptablesauf dem Host ausgeführt werden, sehen Sie im Grunde nur den Namespace des Hosts, und die Pakete, an denen Sie interessiert sind, werden mit dem Namespace des Containers verglichen. Um dieses Problem zu umgehen, können Sie ip netnsweiterhin iptables auf dem Host ausführen, jedoch im Netzwerknamespace des Containers.

Erstens ip netnshat eine etwas entgegengesetzte intuitive Benutzeroberfläche. Um eine Verknüpfung zum Namespace eines vorhandenen Prozesses (in diesem Fall Ihres Containers) herzustellen, müssen Sie eine Verknüpfung /var/run/netns/zum Namespace des Prozesses erstellen :

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

(Möglicherweise müssen Sie mkdir /var/run/netns)

Jetzt können Sie iptables im Namespace Ihres Containers ausführen:

# ip netns exec SOME_NAME iptables -L -nv

Beachten Sie, dass dies den Regelsatz von iptables im Container ausgibt, der wahrscheinlich leer sein wird.

Wenn Sie derzeit --uid-owner verwenden, um nur Benutzerzähler zu haben, benötigen Sie diesen nicht einmal mehr, da in diesem Fall die Kettenzähler nur für den Container gelten und dann ausreichen sollten.

Schließlich können Sie aufräumen /var/run/netns.

Mehrere Container pro Benutzer

Wenn Sie mehrere Container pro Benutzer haben und diese zusammenfassen möchten, können Sie Ihre Container mit starten --net=container:OTHER_CONTAINER_FROM_USER, damit ihre Namespaces zusammengeführt werden.

Dies hat den Nachteil, dass alle Aspekte des Netzwerkstapels, einschließlich der offenen Ports, zusammengeführt werden, sodass nicht zwei Container für denselben Benutzer denselben Port überwachen können.

Wenn dies eine unzulässige Einschränkung ist, können Sie die Container später anhand der UID einzeln und in Gruppen zusammenfassen.

Weitere Informationen zu diesem Thema finden Sie hier .

Leo Antunes
quelle
0

Nicht genau das, was Sie gefragt haben, aber ich glaube, es wird die Arbeit erledigen.

Zitat aus dem Docker-Blog :

Zähler auf Schnittstellenebene

Da jeder Container über eine virtuelle Ethernet-Schnittstelle verfügt, können Sie die TX- und RX-Zähler dieser Schnittstelle direkt überprüfen.

[...]

Derzeit ist es jedoch am besten, die Metriken in den Containern zu überprüfen. Ich spreche nicht davon, einen Spezialagenten in den Container zu schicken, oder so etwas. Wir werden eine ausführbare Datei von der Host-Umgebung ausführen, jedoch innerhalb des Netzwerk-Namespaces eines Containers.

Das genaue Format des Befehls lautet:

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

Zum Beispiel:

ip netns exec mycontainer netstat -i

Trisell
quelle
2
Ich habe Ihre Antwort stark umformatiert und in Ihren zukünftigen Antworten Ressourcen in einem ähnlichen Stil zitiert, um sie nützlicher zu machen.
Füro