Linux docker shaper: Управление траффиком внутри контейнера
Ограничение траффика в контейнере
Постановка задачи
Настроить гибкое управление траффиком в том числе задержками и потерями внутри контейнера==
Предварительно определнные значения переменных
В примере 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 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
tc qdisc del dev ifb0 root tc qdisc add dev ifb0 root netem delay 500ms