Подсчет пропускной способности из контейнера Docker

13

Я пытаюсь выяснить, как отслеживать пропускную способность, поступающую из контейнера Docker.

Обычно я использую --uid-ownerкак метку, чтобы отслеживать использование полосы пропускания для данного пользователя. Тем не менее, даже когда я запускаю все процессы, поскольку пользователь внутри контейнера Docker --uid-ownerне работает. Вместо того, чтобы использовать --uid-owner, я попытался просто отслеживать все пакеты, поступающие с виртуального устройства Ethernet, которое создает Docker.

Это, однако, закончилось тем, что ничего не делало: независимо от того, что я пытаюсь, пакеты не перехватываются.

Из чистого отчаяния я попытался просто поставить правила во всех цепях, но ничего не дало.

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

Кто-нибудь может сказать мне, как успешно пометить пакеты из контейнера Docker? Желательно использовать, --uid-ownerно я возьму все, что на этом этапе :)

Маран
источник

Ответы:

4

Проблема связана с пространствами имен. Docker использует их для изоляции ресурсов, что также означает, что они не учитываются при подсчете общего количества ресурсов хоста.

Когда вы работаете iptablesна хосте, вы в основном смотрите только на пространство имен хоста, и пакеты, которые вас интересуют, привязываются к пространству имен контейнера. Чтобы обойти эту проблему, вы можете использовать ip netnsдля запуска iptables на хосте, но в сетевом пространстве имен контейнера.

Во-первых, ip netnsимеет несколько интуитивно понятный интерфейс. Чтобы присоединиться к пространству имен существующего процесса (в данном случае к вашему контейнеру), вы должны создать ссылку /var/run/netns/на пространство имен процесса:

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

(возможно, вам придется mkdir /var/run/netns)

Теперь вы можете запускать iptables в пространстве имен вашего контейнера:

# ip netns exec SOME_NAME iptables -L -nv

Обратите внимание, что это выводит набор правил iptables внутри контейнера, который, вероятно, будет пустым.

Если вы в настоящее время используете --uid-owner только для того, чтобы иметь счетчики для каждого пользователя, он вам даже больше не нужен, потому что в этом случае счетчики цепочек применяются только к контейнеру и их должно быть достаточно.

Наконец, вы можете очистить /var/run/netns.

Несколько контейнеров на пользователя

Если у вас есть несколько контейнеров на пользователя и вы хотите объединить их вместе, вы можете начать контейнеры --net=container:OTHER_CONTAINER_FROM_USER, чтобы их пространства имен были объединены.

Недостатком этого является объединение всех аспектов сетевого стека, включая открытые порты, поэтому нельзя иметь два контейнера для одного и того же пользователя, прослушивающего один и тот же порт.

Если это запретительное ограничение, вы можете подсчитать контейнеры индивидуально и сгруппировать на основе идентификатора пользователя позже.

Вы можете найти более подробную информацию об этой проблеме здесь .

Лев Антунес
источник
0

Не совсем то, что вы просили, но я полагаю, что это сделает работу.

Цитата из блога Docker :

Счетчики уровня интерфейса

Поскольку каждый контейнер имеет виртуальный интерфейс Ethernet, вы можете проверить непосредственно счетчики TX и RX этого интерфейса.

[...]

Но на данный момент лучший способ - это проверить метрики из контейнеров. Я не говорю о запуске специального агента в контейнере или о чем-то подобном. Мы собираемся запустить исполняемый файл из среды хоста, но в сетевом пространстве имен контейнера.

Точный формат команды:

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

Например:

ip netns exec mycontainer netstat -i

Trisell
источник
2
Я сильно переформатировал ваш ответ, попробуйте цитировать ресурсы в похожем стиле в ваших будущих ответах, чтобы сделать их более полезными.
Fuero