Apa yang benar-benar dilakukan opsi --net = host dalam perintah Docker?

90

Saya sedikit pemula di Docker. Saya tidak dapat menemukan deskripsi yang jelas tentang apa yang dilakukan opsi ini dalam perintah docker run secara mendalam dan agak bingung tentang hal itu.

Bisakah kita menggunakannya untuk mengakses aplikasi yang berjalan di kontainer buruh pelabuhan tanpa menentukan port? Sebagai contoh jika saya menjalankan aplikasi web yang disebarkan melalui gambar buruh pelabuhan di port 8080 dengan menggunakan opsi -p 8080:8080di perintah jalankan buruh pelabuhan, saya tahu saya harus mengaksesnya di port 8080 di wadah Docker ip / theWebAppName. Tetapi saya tidak dapat benar-benar memikirkan cara --net=hostkerja opsi.

Ravindu Fernando
sumber

Jawaban:

127

Setelah instalasi buruh pelabuhan Anda memiliki 3 jaringan secara default:

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f3be8b1ef7ce        bridge              bridge              local
fbff927877c1        host                host                local
023bb5940080        none                null                local

Saya mencoba untuk tetap sederhana ini. Jadi jika Anda memulai container secara default, container akan dibuat di dalam jaringan bridge (docker0).

$ docker run -d jenkins
1498e581cdba        jenkins             "/bin/tini -- /usr..."   3 minutes ago       Up 3 minutes        8080/tcp, 50000/tcp   friendly_bell

Di dockerfile dari jenkins port 8080dan 50000diekspos. Porta tersebut dibuka untuk kontainer di jaringan jembatannya. Jadi semua yang ada di dalam jaringan jembatan itu dapat mengakses kontainer di pelabuhan 8080dan 50000. Segala sesuatu di jaringan jembatan berada dalam jangkauan pribadi "Subnet": "172.17.0.0/16",Jika Anda ingin mengaksesnya dari luar, Anda harus memetakan port dengan -p 8080:8080. Ini akan memetakan port penampung Anda ke port server Anda yang sebenarnya (jaringan host). Jadi mengakses server Anda di 8080akan mengarahkan ke jaringan jembatan Anda di port 8080.

Sekarang Anda juga memiliki jaringan host Anda. Yang tidak memasukkan wadah ke jaringan. Jadi jika Anda memulai penampung di jaringan host, itu akan terlihat seperti ini (ini yang pertama):

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
1efd834949b2        jenkins             "/bin/tini -- /usr..."   6 minutes ago       Up 6 minutes                              eloquent_panini
1498e581cdba        jenkins             "/bin/tini -- /usr..."   10 minutes ago      Up 10 minutes       8080/tcp, 50000/tcp   friendly_bell

Perbedaannya ada pada portnya. Penampung Anda sekarang berada di dalam jaringan host Anda. Jadi jika Anda membuka port 8080pada host Anda, Anda akan segera mengakses kontainer.

$ sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT

Saya telah membuka port 8080di firewall saya dan saat saya mengakses server saya di port, 8080saya mengakses jenkins saya. Menurut saya blog ini juga berguna untuk memahaminya dengan lebih baik.

lvthillo.dll
sumber
4
Apakah mungkin untuk menambahkan opsi --net=hostdi dalam Dockerfile?
AnirbanDebath
6
@AnirbanDebnath Saya tidak berpikir itu mungkin untuk memasukkannya ke dalam dockerfile tapi karena buruh pelabuhan v17 Anda dapat menggunakannya sebagai parameter untuk buruh pelabuhan membangun Anda: docker build --network=host. Jaringan host yang ditentukan untuk build buruh pelabuhan hanya untuk mendownload paket yang diperlukan untuk membuat image. Saat Anda ingin menjalankan container di jaringan host, Anda masih perlu menentukan opsi --network = host.
lvthillo
Ya @AnirbanDebnath, itu diizinkan di Dockerfile. misalnya Dalam v3 - network_mode: "host"(ref - docs.docker.com/compose/compose-file/#network_mode )
Mohnish
Itu adalah file Docker-Compose yang menjelaskan cara menjalankan container. Bukan Dockerfile. Tapi memang, ada kemungkinan dan melakukan hal yang sama dengan docker run --network = host
lvthillo
27

The --net=hostopsi digunakan untuk membuat program-program dalam Docker wadah terlihat seperti mereka berjalan pada host itu sendiri, dari perspektif jaringan. Hal ini memungkinkan akses jaringan kontainer yang lebih besar daripada biasanya.

Biasanya Anda harus meneruskan port dari mesin host ke dalam sebuah wadah, tetapi ketika kontainer berbagi jaringan host, aktivitas jaringan apa pun terjadi secara langsung di mesin host - sama seperti jika program berjalan secara lokal di host, bukan di dalam a wadah.

Meskipun ini berarti Anda tidak lagi harus mengekspos port dan memetakannya ke port kontainer, itu berarti Anda harus mengedit Dockerfiles Anda untuk menyesuaikan port yang didengarkan oleh setiap kontainer, untuk menghindari konflik karena Anda tidak dapat memiliki dua kontainer yang beroperasi di tempat yang sama. port host. Namun, alasan sebenarnya untuk opsi ini adalah untuk menjalankan aplikasi yang memerlukan akses jaringan yang sulit diteruskan ke container di level port.

Misalnya, jika Anda ingin menjalankan server DHCP maka Anda harus dapat mendengarkan lalu lintas siaran di jaringan, dan mengekstrak alamat MAC dari paket. Informasi ini hilang selama proses penerusan port, jadi satu-satunya cara untuk menjalankan server DHCP di dalam Docker adalah dengan menjalankan container sebagai --net=host.

Secara umum, --net=hostini hanya diperlukan ketika Anda menjalankan program dengan kebutuhan jaringan yang sangat spesifik dan tidak biasa.

Terakhir, dari perspektif keamanan, kontainer Docker dapat mendengarkan di banyak port, meskipun mereka hanya mengiklankan (mengekspos) satu port. Biasanya ini baik-baik saja karena Anda hanya meneruskan satu port yang diharapkan, namun jika Anda menggunakannya --net=hostmaka Anda akan mendapatkan semua port penampung yang mendengarkan pada host, bahkan yang tidak terdaftar di Dockerfile. Ini berarti Anda perlu memeriksa wadah dengan cermat (terutama jika itu bukan milik Anda, misalnya yang resmi yang disediakan oleh proyek perangkat lunak) untuk memastikan Anda tidak secara tidak sengaja mengekspos layanan tambahan pada mesin.

Malvineous
sumber
Apa yang akan menjadi perilaku jika beberapa kontainer dimulai dengan opsi '--net = host'? Apakah permintaan akan diteruskan ke penampung acak?
pengguna482594
@ user482594: Mereka semua akan berbagi tumpukan jaringan yang sama, sama seperti Anda menjalankan semua program di dalam wadah yang sama. misalnya jika Anda menjalankan dua server web, Anda harus memastikan mereka mendengarkan pada port yang berbeda jika tidak, penampung kedua akan mendapatkan kesalahan bahwa port tersebut sedang digunakan oleh yang pertama. Lalu lintas yang masuk akan diteruskan ke kontainer mana pun yang mendengarkannya (secara teknis semua --net=hostkontainer akan melihat lalu lintas, tetapi tentu saja hanya satu program dalam satu waktu yang dapat mendengarkan pada port tertentu tidak peduli di kontainer mana Anda menjalankannya, dalam pengaturan ini ).
Malvineous
1
  1. Anda dapat membuat jaringan baru Anda sendiri seperti --net = "anyname"
  2. ini dilakukan untuk mengisolasi layanan dari penampung yang berbeda.
  3. misalkan layanan yang sama berjalan di penampung yang berbeda, tetapi pemetaan port tetap sama, penampung pertama dimulai dengan baik, tetapi layanan yang sama dari penampung kedua akan gagal. jadi untuk menghindarinya, ubah pemetaan port atau buat jaringan.
Abhishek DK
sumber
1
Terima kasih telah menyebutkan "2. ini dilakukan untuk mengisolasi layanan (jaringan) dari wadah yang berbeda". Saya benar-benar melihat nilai menggunakan konfigurasi jaringan buruh pelabuhan lainnya (selain host) jika ada kemungkinan menjalankan beberapa kontainer pada host yang sama. Dalam kasus lain (di mana isolasi jaringan tidak diperlukan), saya lebih suka --net=host.
CᴴᴀZ