Вопрос или проблема
Я пытаюсь перенастроить некоторые параметры сетевого ядра в /proc/sys/net/core в моем контейнере. Но кажется, что некоторые параметры отсутствуют в docker ubuntu:14.04, поэтому я не могу их настроить. пример:
$ sysctl -w net.core.rmem_max=262144
sysctl: cannot stat /proc/sys/net/core/rmem_max: No such file or directory
В моем docker доступны только несколько параметров:
В моей хостовой Ubuntu:
$ ls /proc/sys/net/core/
bpf_jit_enable message_burst rmem_default xfrm_acq_expires
busy_poll message_cost rmem_max xfrm_aevent_etime
busy_read netdev_budget rps_sock_flow_entries xfrm_aevent_rseqth
default_qdisc netdev_max_backlog somaxconn xfrm_larval_drop
dev_weight netdev_rss_key warnings
flow_limit_cpu_bitmap netdev_tstamp_prequeue wmem_default
flow_limit_table_len optmem_max wmem_max
В моей docker Ubuntu:
$ ls /proc/sys/net/core/
somaxconn xfrm_acq_expires xfrm_aevent_etime xfrm_aevent_rseqth xfrm_larval_drop
Я попытался запустить docker с параметрами –net=none/default (я не хочу использовать host) или –v /proc/sys/net:/proc/sys/net, но ничего не меняется.
Я прочитал на kernel.org: “/proc/sys/net … Вы можете увидеть только некоторые из них, в зависимости от конфигурации вашего ядра.”
Есть ли какой-либо способ получить полный набор опций?
Спасибо!
Эти файлы представляют конфигурацию вашей хостовой сетевой среды. Без --net=host
вы создаете новую сетевую среду внутри контейнера, и файлы “перезаписываются” контейнерными.
Если вам нужен доступ к хостовой среде, вы можете рассмотреть возможность её монтирования в другое место, например, в /net, используя -v /proc/sys/net/:/net
, и затем просто использовать echo значение > /net/my/file
вместо использования sysctl.
Ответ или решение
Для решения проблемы недоступности некоторых параметров сети в контейнере Ubuntu под управлением Docker, необходимо понять специфичность функционирования файловой системы /proc
в рамках контейнерной архитектуры. Файлы и директории в /proc/sys/net/
отражают конфигурацию сетевого стека операционной системы, и их доступность и содержимое зависят от настроек ядра и самого контейнера.
Теоретическая часть
Контейнеры Docker, такие как тот, который вы используете на базе Ubuntu 14.04, обычно создают изолированное окружение, которое включает в себя собственный сетевой стек, отдельный от хоста. Это обусловлено использованием пространств имен (namespaces) и групп Cgroups для реализации контейнеризации, что позволяет окружению быть изолированным от базовой операционной системы.
Когда вы запускаете контейнер без опции --net=host
, Docker предоставляет ему собственный сетевой стек, и как результат, /proc/sys/net/
внутри контейнера может иметь ограниченный набор параметров по сравнению с хостовой системой. Это объясняет, почему некоторые параметры, такие как rmem_max
, недоступны в контейнере.
В ситуации с контейнерами, доступ к определенным сетевым параметрам может быть ограничен из-за соображений безопасности и конфигурации сети. Более того, даже если вы монтируете /proc/sys/net
из хоста, это может не сработать так, как вы ожидаете, без использования соответствующих флагов или изменений в конфигурации.
Пример
Рассмотрим конфигурацию хостовой системы и контейнера. В хостовой системе Ubuntu вы можете увидеть множество параметров в /proc/sys/net/core/
, включая rmem_max
:
$ ls /proc/sys/net/core/
bpf_jit_enable message_burst rmem_default xfrm_acq_expires
busy_poll message_cost rmem_max xfrm_aevent_etime
busy_read netdev_budget rps_sock_flow_entries xfrm_aevent_rseqth
default_qdisc netdev_max_backlog somaxconn xfrm_larval_drop
Однако, в контейнере Docker Ubuntu 14.04
, который вы используете, вывод ограничен:
$ ls /proc/sys/net/core/
somaxconn xfrm_acq_expires xfrm_aevent_etime xfrm_aevent_rseqth xfrm_larval_drop
Как видно, множество параметров, доступных на хосте, отсутствует в контейнере.
Применение
Чтобы получить доступ ко всем параметрам, существует несколько возможных подходов:
-
Использование флага
--net=host
: Этот флаг позволяет контейнеру использовать сетевой стек хоста. Однако, как вы уже упомянули, это не соответствует вашим требованиям, так как вы хотите избегать использования сетевого стека хоста. -
Монтирование сетевых файлов систем хоста в другом месте: Например, смонтировать
/proc/sys/net
хоста в другую директорию контейнера и изменять параметры вручную через нее:docker run -it --rm -v /proc/sys/net:/host-net ubuntu:14.04 /bin/bash
В этом случае, вы можете воздействовать на параметры, используя:
echo 262144 > /host-net/core/rmem_max
Обратите внимание, что этот метод модифицирует параметры хоста, что может не всегда быть безопасно и может создать конфликт с логикой виртуализации безопасной изоляции контейнеров.
-
Изменение параметров ядра на стадии сборки образа: Если модификация осуществляется в пределах допустимых, можно сконфигурировать параметры на стадии сборки контейнера через
Dockerfile
или заскриптованные установки, модифицируя значения в их изолированном пространстве имен. -
Проверка и использование специальных Docker-образов: Некоторыми провайдерами и сообществом могут быть предоставлены образы Docker, которые специально сконфигурированы с необходимыми системными параметрами. Это может потребовать дополнительного поиска и интеграции в вашу работу.
Подведем итог. Контейнеры Docker создают изолированное окружение, и эта изоляция затрагивает сетевой стек, влияя на видимость параметров в /proc/sys/net/
. Для обеспечения доступа ко всем параметрам, вам может потребоваться использование сетевого стека хоста или специальных конфигураций контейнера, которые отходят от стандартных практик контейнеризации. Не забывайте учитывать безопасность и возможные последствия изменений на общую архитектуру системы.