Ottimizzazione del kernel con Privileged Docker Container


10

Sto creando un contenitore per ottimizzare le impostazioni del kernel per un bilanciamento del carico. Preferirei distribuire tali modifiche all'host in un'immagine usando un singolo contenitore privilegiato. Per esempio:

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

Nel test le modifiche hanno effetto ma solo per quel contenitore. Avevo l'impressione che con un contenitore completamente privilegiato le modifiche a / proc avrebbero effettivamente cambiato il sistema operativo sottostante.

$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

È così che dovrebbero funzionare i container privilegiati?

Sto solo facendo qualcosa di stupido?

Qual è il modo migliore per apportare cambiamenti duraturi?

Informazioni sulla versione:

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

Esempio di comando con montato / 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

Devo fare qualcosa di stupido come mount / proc come volume?
allingeek,

Ho provato a montare / proc: / proc senza fortuna. Le chiamate successive a sysctl -a restituiscono i valori originali.
allingeek,

Sembra che ora funzioni su Docker 18.09
Jairo Andres Velasco Romero il

Risposte:


8

Questa particolare impostazione rientra nell'influenza dello spazio dei nomi di rete in cui si trova la finestra mobile.

Come regola generale /proc, le impostazioni sono rilevanti a livello di sistema, tecnicamente parlando, tuttavia si stanno modificando le impostazioni in /proc/netcui vengono restituiti i risultati in base allo spazio dei nomi di rete.

Si noti che in /proc/netrealtà è un collegamento simbolico in /proc/self/netquanto riflette realmente le impostazioni dello spazio dei nomi in cui si sta eseguendo il lavoro.


Quindi, se apporto queste modifiche in un contenitore con / proc montato e --net host, posso apportare modifiche all'host. Ma se capisco la tua risposta, i contenitori successivi manterranno i vecchi valori (avviati dalle impostazioni persistenti dell'host) nel proprio spazio dei nomi. Avrei bisogno di eseguire quel contenitore con qualcosa come CAP_NET_ADMIN per apportare le stesse modifiche in fase di esecuzione nel contenitore del bilanciamento del carico. Sembra giusto?
allingeek,

Sì, l'esecuzione con CAP_NET_ADMIN non dovrebbe costituire un problema in cui è stato istanziato uno spazio dei nomi per esso.
Matthew Ife,

Matthew_Ife Non è un problema in questo caso che il contenitore dovrebbe essere privilegiato. Mi sembra che CAP_NET_ADMIN potrebbe consentire la fuga dalla confinazione della finestra mobile (almeno il contenitore potrebbe riconfigurare la sua interfaccia per impersonare un altro contenitore)
Ángel

@Angel Dipende da quale collegamento è installato all'interno della finestra mobile. In genere, tuttavia, si dovrebbe applicare l'applicazione del traffico nello spazio dei nomi padre. Non sarebbe possibile cambiare gli spazi dei nomi da qualche altra parte poiché per questo è necessario CAP_SYS_ADMIN.
Matthew Ife,

Quindi usando --net = host funzionerà?
Jairo Andres Velasco Romero,

7

Docker 1.12+ ha il supporto nativo per l'ottimizzazione dei valori di sysctl all'interno dei contenitori. Ecco un estratto dalla documentazione :

Configurare i parametri del kernel spaziati dal nome (sysctls) in fase di esecuzione

--Sysctl imposta i parametri del kernel spaziati dal nome (sysctls) nel contenitore. Ad esempio, per attivare l'inoltro IP nello spazio dei nomi di rete dei contenitori, eseguire questo comando:

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

Usando il tuo esempio, il modo corretto di rilanciare net.core.somaxconnsarebbe:

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

3

Il contenitore privilegiato sta ancora utilizzando il proprio spazio dei nomi di processo per /proc. Quello che puoi fare è montare il vero /procall'interno del contenitore:

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

Ho appena provato questo e non funziona.
allingeek,

Dal poco che so di docker; dovrebbe essere un'istanza autonoma, come una jail su FreeBSD, quindi può essere facilmente spostata, ridistribuita, ecc ... Non dovresti confondere il docklet con il sistema operativo host.
Zio olandese,

2
Esistono diversi casi validi per l'utilizzo di contenitori con privilegi e questo sembra il caso perfetto. Tutti i contenitori usano lo stesso kernel sottostante. I contenitori standard montano / proc in sola lettura.
allingeek,

@allingeek CAP_NET_ADMIN potrebbe davvero essere il bit mancante.
Ángel,

1
Provato con NET_ADMIN e non funziona ancora - docker run --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

Questo funziona per me con Docker 1.5.0:

docker run --privileged --net=host --rm ubuntu:latest /bin/sh -c \
   'echo 65535 > /proc/sys/net/core/somaxconn'   
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.