Saya memiliki wadah buruh pelabuhan menjalankan jenkins. Sebagai bagian dari proses pembangunan, saya perlu mengakses server web yang dijalankan secara lokal di mesin host. Apakah ada cara server web host (yang dapat dikonfigurasi untuk berjalan pada port) dapat terkena wadah jenkins?
EDIT: Saya menjalankan buruh pelabuhan secara native di mesin Linux.
MEMPERBARUI:
Selain jawaban @ larsks di bawah ini, untuk mendapatkan alamat IP Host IP dari mesin host, saya melakukan hal berikut:
ip addr show docker0 | grep -Po 'inet \K[\d.]+'
docker
docker-container
Tri Nguyen
sumber
sumber
curl: (7) Failed to connect to 172.17.1.78 port 7000: No route to host
Jawaban:
Saat menjalankan Docker secara native di Linux, Anda dapat mengakses layanan host menggunakan alamat IP
docker0
antarmuka. Dari dalam wadah, ini akan menjadi rute default Anda.Misalnya, di sistem saya:
Dan di dalam sebuah wadah:
Cukup mudah untuk mengekstrak alamat IP ini menggunakan skrip shell sederhana:
Anda mungkin perlu mengubah
iptables
aturan pada host Anda untuk mengizinkan koneksi dari wadah Docker. Sesuatu seperti ini akan melakukan trik:Ini akan memungkinkan akses ke setiap port di host dari wadah Docker. Perhatikan bahwa:
Aturan iptables dipesan, dan aturan ini mungkin atau tidak bisa melakukan hal yang benar tergantung pada aturan lain yang datang sebelumnya.
Anda hanya akan dapat mengakses layanan host yang (a) mendengarkan
INADDR_ANY
(alias 0,0.0.0) atau yang secara eksplisit mendengarkan padadocker0
antarmuka.sumber
docker.for.mac.localhost
sajalocalhost
atau127.0.0.1
. Ini dok .Untuk macOS dan Windows
Docker v 18.03 dan lebih tinggi (sejak 21 Maret 2018)
Gunakan alamat IP internal Anda atau sambungkan ke nama DNS khusus
host.docker.internal
yang akan menyelesaikan ke alamat IP internal yang digunakan oleh tuan rumah.Dukungan Linux tertunda https://github.com/docker/for-linux/issues/264
MacOS dengan versi Docker sebelumnya
Docker untuk Mac v 17.12 hingga v 18.02
Sama seperti di atas tetapi gunakan
docker.for.mac.host.internal
sebagai gantinya.Docker untuk Mac v 17.06 hingga v 17.11
Sama seperti di atas tetapi gunakan
docker.for.mac.localhost
sebagai gantinya.Docker untuk Mac 17.05 dan di bawah
Untuk mengakses mesin host dari wadah buruh pelabuhan Anda harus memasang alias IP ke antarmuka jaringan Anda. Anda dapat mengikat IP mana pun yang Anda inginkan, pastikan Anda tidak menggunakannya untuk hal lain.
sudo ifconfig lo0 alias 123.123.123.123/24
Kemudian pastikan bahwa server Anda mendengarkan IP yang disebutkan di atas atau
0.0.0.0
. Jika mendengarkan di localhost,127.0.0.1
itu tidak akan menerima koneksi.Kemudian arahkan saja buruh pelabuhan Anda ke IP ini dan Anda dapat mengakses mesin host!
Untuk menguji Anda dapat menjalankan sesuatu seperti
curl -X GET 123.123.123.123:3000
di dalam wadah.Alias akan mengatur ulang pada setiap reboot sehingga buat skrip start-up jika perlu.
Solusi dan dokumentasi lainnya di sini: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
sumber
docker.for.mac.localhost
yang akan menyelesaikan ke alamat IP internal yang digunakan oleh tuan rumah! ... Saya telah mengujinya dan itu benar-benar berfungsi! :)ip route show | awk '/default/ {print $3}'
satu IP dandocker.for.mac.localhost
yang lainnya.host.docker.internal
docs.docker.com/docker-for-mac/networking/…host.docker.internal
dalam wadah buruh pelabuhan dan config127.0.0.1 host.docker.internal
di host file yang.Gunakan
--net="host"
dalamdocker run
perintah Anda , makalocalhost
dalam wadah buruh pelabuhan Anda akan menunjuk ke host buruh pelabuhan Anda.sumber
network_mode: "host"
Solusi dengan docker-compose: Untuk mengakses layanan berbasis host, Anda dapat menggunakan
network_mode
parameter https://docs.docker.com/compose/compose-file/#network_modeEDIT 2020-04-27: direkomendasikan untuk digunakan hanya di lingkungan pengembangan lokal.
sumber
Saat ini cara termudah untuk melakukan ini di Mac dan Windows menggunakan host
host.docker.internal
, yang memutuskan untuk meng-host alamat IP mesin. Sayangnya itu belum berfungsi di linux (per April 2018).sumber
Saya membuat wadah buruh pelabuhan untuk melakukan hal itu https://github.com/qoomon/docker-host
Anda kemudian dapat menggunakan nama wadah dns untuk mengakses sistem host misalnya
curl http://dockerhost:9200
sumber
Kami menemukan bahwa solusi yang lebih sederhana untuk semua sampah jaringan ini adalah dengan menggunakan soket domain untuk layanan ini. Jika Anda tetap mencoba terhubung ke host, cukup pasang soket sebagai volume, dan Anda sedang menuju ke sana. Untuk postgresql, ini sesederhana:
Kemudian kami hanya mengatur koneksi database kami untuk menggunakan soket, bukan jaringan. Secara harfiah itu mudah.
sumber
Saya telah menjelajahi berbagai solusi dan saya menemukan ini solusi paling tidak hacky:
extra_hosts
arahan.Satu-satunya downside adalah jika Anda memiliki beberapa jaringan atau proyek melakukan ini, Anda harus memastikan bahwa rentang alamat IP mereka tidak bertentangan.
Berikut adalah contoh Tulis Docker:
Anda kemudian dapat mengakses port pada host dari dalam wadah menggunakan nama host "dockerhost".
sumber
Untuk sistem linux, Anda dapat - mulai dari versi utama
20.04
- sekarang juga berkomunikasi dengan host viahost.docker.internal
. Ini tidak akan berfungsi secara otomatis , tetapi Anda harus memberikan flag run berikut:Lihat
sumber
Anda dapat mengakses server web lokal yang berjalan di mesin host Anda dengan dua cara.
Pendekatan 1 dengan IP publik
Gunakan alamat IP publik mesin host untuk mengakses server web dalam wadah buruh pelabuhan Jenkins.
Pendekatan 2 dengan jaringan host
Gunakan "--net host" untuk menambahkan wadah buruh pelabuhan Jenkins di tumpukan jaringan host. Kontainer yang digunakan pada stack host memiliki seluruh akses ke antarmuka host. Anda dapat mengakses server web lokal dalam wadah buruh pelabuhan dengan alamat IP pribadi dari mesin host.
Mulai wadah dengan jaringan host
Eg: docker run --net host -it ubuntu
dan jalankanifconfig
untuk mendaftar semua alamat IP jaringan yang tersedia yang dapat dijangkau dari wadah buruh pelabuhan.Misalnya: Saya memulai server nginx di mesin host lokal saya dan saya dapat mengakses URL situs web nginx dari wadah buruh pelabuhan Ubuntu.
docker run --net host -it ubuntu
Mengakses server web Nginx (berjalan di mesin host lokal) dari wadah buruh pelabuhan Ubuntu dengan alamat IP jaringan pribadi.
sumber
Untuk
docker-compose
menggunakan jembatan jaringan untuk membuat jaringan pribadi antara kontainer, solusi yang diterima menggunakandocker0
tidak berfungsi karena antarmuka jalan keluar dari wadah tidakdocker0
tetapi sebaliknya itu adalah antarmuka yang dihasilkan secara acak, seperti:Sayangnya id acak itu tidak dapat diprediksi dan akan berubah setiap kali penulisan harus membuat ulang jaringan (mis. Pada host reboot). Solusi saya untuk ini adalah membuat jaringan pribadi di subnet yang dikenal dan mengkonfigurasi
iptables
untuk menerima rentang itu:Tulis cuplikan file:
Anda dapat mengubah subnet jika lingkungan Anda mengharuskannya. Saya secara sewenang-wenang memilih
192.168.32.0/20
dengan menggunakandocker network inspect
untuk melihat apa yang sedang dibuat secara default.Konfigurasikan
iptables
pada host untuk mengizinkan subnet pribadi sebagai sumber:Ini adalah aturan yang paling sederhana
iptables
. Anda mungkin ingin menambahkan batasan lain, misalnya dengan port tujuan. Jangan lupa untuk mempertahankan aturan iptables Anda saat Anda senang mereka sedang bekerja.Pendekatan ini memiliki keuntungan karena dapat diulang dan karena itu dapat diautomatisasi. Saya menggunakan
template
modul ansible untuk menyebarkan file penulisan saya dengan substitusi variabel dan kemudian menggunakan moduliptables
danshell
untuk mengkonfigurasi dan bertahan aturan firewall, masing-masing.sumber
iptables -A INPUT -i docker0 -j ACCEPT
, tetapi itu tidak membantu saya, sedangkan yangiptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
disarankan di sini menyelesaikan masalah saya.Ini adalah pertanyaan lama dan memiliki banyak jawaban, tetapi tidak ada yang cocok dengan konteks saya. Dalam kasus saya, wadah sangat ramping dan tidak mengandung alat jaringan yang diperlukan untuk mengekstrak alamat ip host dari dalam wadah.
Juga, dalam
--net="host"
pendekatan ini adalah pendekatan yang sangat kasar yang tidak berlaku ketika seseorang ingin memiliki konfigurasi jaringan yang terisolasi dengan beberapa wadah.Jadi, pendekatan saya adalah mengekstraksi alamat host di sisi host, dan kemudian meneruskannya ke wadah dengan
--add-host
parameter:atau, simpan alamat IP host dalam variabel lingkungan dan gunakan variabel nanti:
Dan kemudian
docker-host
ditambahkan ke file host penampung, dan Anda dapat menggunakannya dalam string koneksi database atau URL API.sumber
Ketika Anda memiliki dua gambar buruh pelabuhan "sudah" dibuat dan Anda ingin menempatkan dua wadah untuk berkomunikasi satu sama lain.
Untuk itu, Anda dapat dengan mudah menjalankan setiap wadah dengan --nama sendiri dan menggunakan bendera --link untuk mengaktifkan komunikasi di antara mereka. Anda tidak mendapatkan ini selama pembuatan buruh pelabuhan.
Ketika Anda berada dalam skenario seperti saya, dan itu adalah Anda
Itu rusak ketika Anda mencoba
dan Anda terjebak pada "curl / wget" tidak mengembalikan "rute ke host".
Alasannya adalah keamanan yang ditetapkan oleh buruh pelabuhan yang secara default melarang komunikasi dari wadah ke host atau kontainer lain yang berjalan di host Anda. Ini cukup mengejutkan bagi saya, saya harus mengatakan, Anda akan mengharapkan echosystem mesin docker yang berjalan pada mesin lokal tanpa cacat dapat saling mengakses tanpa terlalu banyak rintangan.
Penjelasan untuk ini dijelaskan secara rinci dalam dokumentasi berikut.
http://www.dedoimedo.com/computers/docker-networking.html
Dua solusi cepat diberikan yang membantu Anda bergerak dengan menurunkan keamanan jaringan.
Semoga informasi ini membantu Anda.
sumber
--link
sekarang sudah ditinggalkanBagi saya (Windows 10, Docker Engine v19.03.8) itu adalah campuran dari https://stackoverflow.com/a/43541732/7924573 dan https://stackoverflow.com/a/50866007/7924573 .
misalnya: LOGGER_URL = " http: //host.docker.internal: 8085 / log "
version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge
atau sebagai alternatif: Gunakan--net="bridge"
jika Anda tidak menggunakan docker-compose (mirip dengan https://stackoverflow.com/a/48806927/7924573 )Seperti yang ditunjukkan dalam jawaban sebelumnya: Ini hanya boleh digunakan di lingkungan pengembangan lokal .
Untuk informasi lebih lanjut baca: https://docs.docker.com/compose/compose-file/#network_mode dan https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds
sumber