Tuning Kernel dengan Wadah Docker Privileged

10

Saya sedang membangun sebuah wadah untuk menyempurnakan pengaturan kernel untuk load balancer. Saya lebih suka menyebarkan perubahan itu ke host di gambar menggunakan wadah istimewa tunggal. Sebagai contoh:

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

Dalam menguji perubahan berlaku tetapi hanya untuk wadah itu. Saya mendapat kesan bahwa dengan perubahan wadah sepenuhnya istimewa ke / proc benar-benar akan mengubah OS yang mendasarinya.

$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

Apakah ini cara kerja kontainer istimewa?

Apakah saya hanya melakukan sesuatu yang konyol?

Apa cara terbaik untuk membuat perubahan yang langgeng?

Informasi versi:

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

Contoh perintah dengan mount / 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
allingeek
sumber
Apakah saya perlu melakukan sesuatu yang konyol seperti mount / proc sebagai volume?
allingeek
Mencoba pemasangan / proc: / proc tanpa hasil. Panggilan selanjutnya ke sysctl -a mengembalikan nilai aslinya.
allingeek
Sepertinya sekarang ini berfungsi pada Docker 18.09
Jairo Andres Velasco Romero

Jawaban:

8

Pengaturan khusus ini berada di bawah pengaruh namespace jaringan yang digunakan oleh buruh pelabuhan.

Sebagai aturan umum /procmemang mengubah pengaturan yang relevan untuk seluruh sistem, secara teknis Anda mengubah pengaturan /proc/netyang mengembalikan hasil berdasarkan basis namespace jaringan.

Catatan yang /proc/netsebenarnya adalah symlink /proc/self/netkarena benar-benar mencerminkan pengaturan namespace tempat Anda melakukan pekerjaan.

Matthew Ife
sumber
Jadi, jika saya membuat perubahan ini dalam wadah dengan / proc mount dan --net host, saya bisa membuat perubahan pada host. Tetapi jika saya memahami jawaban Anda, kontainer berikutnya akan mempertahankan nilai-nilai lama (bootstrap dari pengaturan tetap host) di namespace-nya sendiri. Saya perlu menjalankan wadah itu dengan sesuatu seperti CAP_NET_ADMIN untuk membuat perubahan yang sama saat runtime dalam wadah penyeimbang muatan. Kedengarannya benar?
allingeek
Ya, menjalankan dengan CAP_NET_ADMIN seharusnya tidak menimbulkan masalah di mana Anda telah membuat ruang nama untuk itu.
Matthew Ife
Matthew_Ife Bukan masalah dalam hal ini bahwa kontainer diharapkan istimewa. Menurut saya, CAP_NET_ADMIN dapat memungkinkan melarikan diri dari kurungan buruh pelabuhan (setidaknya wadah dapat mengkonfigurasi ulang antarmuka untuk meniru wadah lain)
Ángel
@Angel Itu akan tergantung pada tautan apa yang dipasang di dalam docker. Secara umum orang harus meletakkan penegakan lalu lintas di namespace induk. Tidak mungkin untuk mengganti ruang nama ke tempat lain karena Anda memerlukan CAP_SYS_ADMIN untuk itu.
Matthew Ife
SO menggunakan --net = host akan bekerja?
Jairo Andres Velasco Romero
7

Docker 1.12+ memiliki dukungan asli untuk mengubah nilai sysctl di dalam kontainer. Berikut adalah kutipan dari dokumentasi :

Konfigurasikan parameter kernel namespace (sysctls) saat runtime

--Sysctl menetapkan parameter kernel namespace (sysctls) dalam wadah. Misalnya, untuk mengaktifkan penerusan IP di namespace jaringan wadah, jalankan perintah ini:

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

Menggunakan contoh Anda, cara yang benar untuk meningkatkan net.core.somaxconnadalah:

docker run ... --sysctl net.core.somaxconn=65535 ...
hyperknot
sumber
3

Wadah istimewa masih menggunakan proses namespace sendiri untuk /proc. Yang dapat Anda lakukan adalah memasang yang asli /procdi dalam wadah:

docker run --rm --privileged -v /proc:/host-proc ubuntu:latest \
  'echo 65535 > /host-proc/sys/net/core/somaxconn'
Malaikat
sumber
Baru saja mencoba ini dan itu tidak berhasil.
allingeek
Dari sedikit yang saya tahu tentang buruh pelabuhan; itu seharusnya menjadi contoh mandiri, seperti penjara di FreeBSD, sehingga dapat dengan mudah dipindahkan, dipindahtugaskan, dll ... Anda tidak boleh mencampur docklet dengan OS host.
DutchUncle
2
Ada beberapa kasus yang valid untuk menggunakan wadah --privileged dan ini sepertinya kasus yang sempurna. Semua kontainer menggunakan kernel dasar yang sama. Kontainer standar mount / proc sebagai hanya baca.
allingeek
@allingeek CAP_NET_ADMIN mungkin memang bit yang hilang.
Ángel
1
Mencoba dengan NET_ADMIN dan masih tidak berfungsi - buruh pelabuhan --cap-tambahkan 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

Ini bekerja untuk saya dengan Docker 1.5.0:

docker run --privileged --net=host --rm ubuntu:latest /bin/sh -c \
   'echo 65535 > /proc/sys/net/core/somaxconn'   
Charles Offenbacher
sumber