Tuning jądra z uprzywilejowanym kontenerem dokującym


10

Buduję kontener, aby dostroić ustawienia jądra dla modułu równoważenia obciążenia. Wolę wdrożyć te zmiany na hoście na obrazie przy użyciu jednego uprzywilejowanego kontenera. Na przykład:

docker run --rm --privileged ubuntu:latest sysctl -w net.core.somaxconn=65535

Podczas testowania zmiany obowiązują, ale tylko dla tego kontenera. Miałem wrażenie, że przy w pełni uprzywilejowanym kontenerze zmiany w / proc zmieniłyby podstawowy system operacyjny.

$docker run --rm --privileged ubuntu:latest \
    sysctl -w net.core.somaxconn=65535
net.core.somaxconn = 65535

$ docker run --rm --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep somaxconn"
net.core.somaxconn = 128

Czy tak właśnie powinny działać uprzywilejowane kontenery?

Czy robię coś głupiego?

Jaki jest najlepszy sposób na wprowadzenie trwałych zmian?

Informacje o wersji:

Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8
OS/Arch (client): linux/amd64
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8

Przykładowe polecenie z zamontowanym / proc:

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -p /updates/sysctl.conf"
net.ipv4.ip_local_port_range = 2000 65000

$ docker run -v /proc:/proc ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

$ docker run -v /proc:/proc --privileged ubuntu:latest \
    /bin/bash -c "sysctl -a | grep local_port"
net.ipv4.ip_local_port_range = 32768    61000

Czy muszę zrobić coś głupiego jak mount / proc jako wolumin?
allingeek

Próbowałem zamontować / proc: / proc bez powodzenia. Kolejne wywołania sysctl -a zwracają oryginalne wartości.
allingeek

Wygląda na to, że teraz działa w Docker 18.09
Jairo Andres Velasco Romero

Odpowiedzi:


8

To szczególne ustawienie podlega wpływowi przestrzeni nazw sieci, w której działa doker.

Zasadniczo /proczmienia się ustawienia, które są odpowiednie dla całego systemu, technicznie rzecz biorąc, jednak zmienia się ustawienia, w /proc/netktórych wyniki są zwracane dla przestrzeni nazw dla poszczególnych sieci.

Zauważ, że /proc/nettak naprawdę jest dowiązaniem symbolicznym, /proc/self/netponieważ tak naprawdę odzwierciedla ustawienia przestrzeni nazw, w której pracujesz.


Więc jeśli dokonam tych zmian w kontenerze z zamontowanym / proc hostem i --net hostem, mogę wprowadzić zmiany na hoście. Ale jeśli rozumiem twoją odpowiedź, kolejne kontenery zachowają stare wartości (bootstrapped z utrwalonych ustawień hosta) we własnej przestrzeni nazw. Musiałbym uruchomić ten kontener z czymś takim jak CAP_NET_ADMIN, aby wprowadzić te same zmiany w czasie wykonywania w kontenerze modułu równoważenia obciążenia. Brzmi dobrze?
allingeek

Tak, uruchamianie z CAP_NET_ADMIN nie powinno stanowić problemu w przypadku utworzenia dla niego przestrzeni nazw.
Matthew Ife

Matthew_Ife W tym przypadku nie ma problemu, że kontener ma być uprzywilejowany. Wydaje mi się, że CAP_NET_ADMIN może pozwolić na ucieczkę od ograniczenia dokera (przynajmniej kontener może zmienić konfigurację interfejsu, aby podszyć się pod inny kontener)
Ángel

@Angel To zależy od tego, jakie łącze zostanie skonfigurowane w oknie dokowanym. Generalnie jednak należy wprowadzić wymuszanie ruchu w nadrzędnej przestrzeni nazw. Nie byłoby możliwe przełączenie przestrzeni nazw w inne miejsce, ponieważ potrzebujesz do tego CAP_SYS_ADMIN.
Matthew Ife

TAK używając --net = host będzie działał?
Jairo Andres Velasco Romero,

7

Docker 1.12+ ma natywną obsługę poprawiania wartości sysctl wewnątrz kontenerów. Oto fragment dokumentacji :

Skonfiguruj parametry jądra z przestrzenią nazw (sysctls) w czasie wykonywania

--Sysctl ustawia parametry jądra w przestrzeni nazw (sysctls) w kontenerze. Na przykład, aby włączyć przekazywanie IP w przestrzeni nazw sieci kontenerów, uruchom następującą komendę:

docker run --sysctl net.ipv4.ip_forward=1 someimage

Korzystając z Twojego przykładu, poprawnym sposobem na podbicie net.core.somaxconnbyłoby:

docker run ... --sysctl net.core.somaxconn=65535 ...

3

Uprzywilejowany kontener nadal używa własnej przestrzeni nazw procesu /proc. Co możesz zrobić, to zamontować prawdziwe /procwnętrze kontenera:

docker run --rm --privileged -v /proc:/host-proc ubuntu:latest \
  'echo 65535 > /host-proc/sys/net/core/somaxconn'

Po prostu spróbowałem tego i to nie działa.
allingeek

Od małego wiem o dokerze; ma to być samodzielna instancja, taka jak więzienie na FreeBSD, więc można ją łatwo przenosić, przenosić itp. ... Nie należy mieszać doku z systemem operacyjnym hosta.
DutchUncle

2
Istnieje kilka prawidłowych przypadków użycia kontenerów uprzywilejowanych i wydaje się to idealnym przypadkiem. Wszystkie kontenery używają tego samego jądra. Standardowe pojemniki montowane / proc jako tylko do odczytu.
allingeek

@allingeek CAP_NET_ADMIN może być rzeczywiście brakującym bitem.
Ángel

1
Wypróbowałem z NET_ADMIN i nadal nie działa - uruchomienie dokera --cap-add NET_ADMIN --net = host -v / proc: / proc_host ubuntu: 14.04 bash -c 'echo 1> / proc_host / sys / net / ipv4 / ip_forward '&& sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 0
tomdee

2

Działa to dla mnie z Dockerem 1.5.0:

docker run --privileged --net=host --rm ubuntu:latest /bin/sh -c \
   'echo 65535 > /proc/sys/net/core/somaxconn'   
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.