Linux docker shaper: Управление траффиком внутри контейнера: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
Строка 136: | Строка 136: | ||
<PRE> |
<PRE> |
||
tc filter add dev ${CONTAINER_INTERFACE} parent 1: prio 1 protocol ip u32 match ip dst 192.168.250.3 action mirred egress redirect dev ifb0 |
tc filter add dev ${CONTAINER_INTERFACE} parent 1: prio 1 protocol ip u32 match ip dst 192.168.250.3 action mirred egress redirect dev ifb0 |
||
− | tc filter add dev ${CONTAINER_INTERFACE} parent ffff: |
+ | tc filter add dev ${CONTAINER_INTERFACE} parent ffff: protocol ip u32 match ip src 192.168.250.3 action mirred egress redirect dev ifb1 |
</PRE> |
</PRE> |
||
Версия 14:11, 12 марта 2020
Ограничение траффика в контейнере
Постановка задачи
Настроить гибкое управление траффиком в том числе задержками и потерями внутри контейнера==
Предварительно определнные значения переменных
В примере 6142712b1eef это индентификатор контейнера
Получения PID
Получить PID процесса докера (внутри контейнера этот процесс будет иметь PID=1)
docker inspect -f '{{.State.Pid}}' "6142712b1eef"
Далее можно этот пид подставлять везде в комманды или исподбзовать переполучение его каждый раз (что более гибко)
для удобства помещаем идентификатор контейнера в переменную окружения
export DOCKER_CONTAINER_UUID="6142712b1eef"
Подготовительный шаги
Для утилиты ip требуются файлы в /var/run/netns
mkdir -p /var/run/netns
ln -sf /proc/$(docker inspect -f '{{.State.Pid}}' "${DOCKER_CONTAINER_UUID}")/ns/net "/var/run/netns/${DOCKER_CONTAINER_UUID}"
По сути тут делается симлинк с файла который указывает на неймспейс созданный докером в место где ожидает его найти ip
подробнее можно прочитать тут : мануал
Кототкая цитата:
By convention a named network namespace is an object at /var/run/netns/NAME that can be opened. The file descriptor resulting from opening /var/run/netns/NAME refers to the specified network namespace. Holding that file descriptor open keeps the network namespace alive. The file descriptor can be used with the setns(2) system call to change the network namespace associated with a task.
После проделанных шагов набюлюдаю доступный для работы netns
# ip netns 6142712b1eef (id: 6)
Управление траффиком внутри контейнера
Создание псевдоинтерфейсов ifb
modprobe ifb numifbs=10
Перенос интерфейсов из глобального неймспейса в докер
ip link set dev ifb0 netns ${DOCKER_CONTAINER_UUID} ip link set dev ifb1 netns ${DOCKER_CONTAINER_UUID}
Переход в контейнер
Тут можно воспользоваться альтернативным путем - утилитой nsenter но в данном случае это мне кажется излишним
ip netns exec ${DOCKER_CONTAINER_UUID} bash
Проверка состояния интерфейсов
ifconfig -a eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.255.5 netmask 255.255.255.0 broadcast 192.168.255.255 ether 02:42:c0:a8:ff:05 txqueuelen 0 (Ethernet) RX packets 1680190 bytes 287513973 (287.5 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1094755 bytes 119082164 (119.0 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ifb0: flags=130<BROADCAST,NOARP> mtu 1500 ether b2:fa:b3:1f:cc:21 txqueuelen 32 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ifb1: flags=130<BROADCAST,NOARP> mtu 1500 ether ca:44:06:d0:6d:c9 txqueuelen 32 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) <skipped>
Поднять псевдоинтерфейсы
ip link set up dev ifb0 ip link set up dev ifb1
Для простоты помещаем имя интерфейса на котором будем управлять трафикомв переменную окружения
export CONTAINER_INTERFACE="eth0"
Очистить существующие правила
tc qdisc delete dev ${CONTAINER_INTERFACE} ingress tc qdisc delete dev ${CONTAINER_INTERFACE} root
Ощибки тут можо проигнорировать (если на самом деле не было настроено политик)
tc qdisc delete dev ${CONTAINER_INTERFACE} root RTNETLINK answers: No such file or directory
Добавить корневые правила
tc qdisc add dev ${CONTAINER_INTERFACE} ingress tc qdisc add dev ${CONTAINER_INTERFACE} root handle 1:0 htb default 3
tc filter add dev ${CONTAINER_INTERFACE} parent 1:0 protocol ip u32
Перенаправляем входящий / исходящий траффик на разные интерфейсы
tc filter add dev ${CONTAINER_INTERFACE} parent 1: prio 1 protocol ip u32 match ip dst 192.168.250.3 action mirred egress redirect dev ifb0 tc filter add dev ${CONTAINER_INTERFACE} parent ffff: protocol ip u32 match ip src 192.168.250.3 action mirred egress redirect dev ifb1
Проверка работы перенаправления
# tcpdump -n -i ifb0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ifb0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C12:08:26.032289 IP 192.168.255.5 > 192.168.250.3: ICMP echo request, id 12785, seq 21, length 64 12:08:27.033178 IP 192.168.255.5 > 192.168.250.3: ICMP echo request, id 12785, seq 22, length 64
# cpdump -n -i ifb1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ifb1, link-type EN10MB (Ethernet), capture size 262144 bytes ^C12:08:33.140209 IP 192.168.250.3 > 192.168.255.5: ICMP echo reply, id 12785, seq 28, length 64 12:08:34.141523 IP 192.168.250.3 > 192.168.255.5: ICMP echo reply, id 12785, seq 29, length 64
tc qdisc del dev ifb0 root tc qdisc add dev ifb0 root netem delay 500ms