Mengapa kontainer Docker tidak dapat menjangkau host di balik VPN
Kontainer jembatan punya ruang nama sendiri, jadi terowongan host tidak terlihat olehnya. Bandingkan jaringan host, perangkat tun, dan macvlan sebelum mengubah DNS.
Kontainer yang tidak dapat menjangkau apa pun di balik VPN perusahaan biasanya hidup di ruang nama jaringan yang berbeda dari terowongan. Rute, server DNS, dan tanda firewall klien host milik tumpukan host; kontainer jaringan jembatan punya tumpukannya sendiri. Fakta tunggal ini menjelaskan sebagian besar laporan yang sampai ke tim platform, dan juga alasan mengapa «VPN-nya rusak» dan «Docker melewati VPN» bisa sama-sama salah pada saat yang sama. Dua penyiapan yang sangat berbeda bersembunyi di balik satu gejala, jadi tentukan mana yang Anda miliki sebelum mengubah pengaturan.
Cari tahu ruang nama siapa yang memiliki terowongan
Di Docker Desktop untuk macOS atau Windows, kontainer berjalan di dalam mesin virtual Linux. Klien VPN yang dipasang di desktop membuat terowongan di sistem operasi desktop, dan mesin virtual tidak pernah melihatnya. Tidak ada konfigurasi kontainer yang memperbaikinya, karena antarmuka yang dibutuhkan kontainer sama sekali tidak ada di ruang nama jaringannya.
Di host Linux terowongan hidup di ruang nama host, dan kontainer jembatan biasanya mencapainya melalui tabel perutean host dengan NAT sumber diterapkan saat keluar. Ketika jalur itu gagal, penyebabnya biasanya kebijakan penerusan, penyaringan jalur balik, atau subnet yang tumpang tindih alih-alih rute yang hilang. Pastikan di dunia mana Anda berada sebelum membaca lebih jauh:
docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5
Perbedaan antara kedua tabel perutean itu adalah seluruh masalah dalam satu layar. Jika tampilan host memuat antarmuka terowongan dan tampilan jembatan tidak, Anda melihat isolasi ruang nama, dan segala hal lain adalah pilihan tentang cara melintasinya.
Jaringan host adalah uji, bukan desain
Menjalankan kontainer dengan jaringan host, yang didokumentasikan Docker sebagai berbagi ruang nama jaringan host, membuatnya mewarisi antarmuka terowongan dan rutenya secara langsung. Jika permintaan yang sama kemudian berhasil, teori rute terkonfirmasi dan kegagalannya adalah isolasi ruang nama, bukan kredensial, DNS, atau aturan akses.
docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health
Pertahankan sebagai diagnostik. Jaringan host melepaskan publikasi port dan sebagian besar isolasi yang Anda inginkan dari kontainer, dan di Docker Desktop «host» berarti mesin virtual, bukan desktop, jadi keberhasilan atau kegagalan di sana dapat menyesatkan Anda jika lupa host mana yang Anda tuju.
Perangkat tun dan hak istimewa yang menyertainya
Klien VPN di dalam kontainer memerlukan perangkat terowongan dan izin untuk mengonfigurasinya. Pintasan umumnya adalah --privileged, yang memberikan setiap perangkat dan melonggarkan kebijakan keamanan di seluruh kontainer. Itu jauh lebih banyak daripada yang dibutuhkan tugas ini, dan sulit dibenarkan dalam tinjauan.
sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client
Bentuk yang lebih sempit memetakan satu simpul perangkat dan hanya menambahkan kemampuan administrasi jaringan. Muat modul di host terlebih dahulu agar simpul itu ada. Jika kontainer mulai dan klien melaporkan tidak dapat membuka perangkat terowongan, periksa pemetaan sebelum mencurigai profil, karena kesalahan itu biasanya literal.
Desain ini juga berarti klien berjalan per kontainer. Itu jawaban yang tepat ketika setiap beban kerja memerlukan terowongannya sendiri, dan jawaban yang salah ketika Anda hanya ingin terowongan host terlihat, yang mungkin diasumsikan tim platform sedang Anda lakukan.
NAT jembatan mengubah sumber yang dilihat VPN
Dengan jembatan bawaan, lalu lintas keluar kontainer diterjemahkan ke alamat host. Karena itu di balik VPN pihak perusahaan melihat alamat terowongan host, bukan alamat kontainer, aturan akses per sumber berperilaku seolah host yang mengirim permintaan, dan dua kontainer menjadi tak terbedakan bagi server VPN.
macvlan atau ipvlan memberi kontainer alamat LAN sebagai gantinya, yang membantu penemuan di LAN dan membuat kontainer tampak sebagai mitra di segmen. Ini juga sepenuhnya melewati terowongan host, jadi kontainer semacam itu tidak akan menjangkau prefiks khusus-VPN kecuali VPN juga dapat dijangkau dari LAN tersebut.
Kedua bentuk sah; keduanya menjawab persyaratan yang berbeda. Jika persyaratannya «kontainer ini harus menjangkau layanan khusus-VPN», Anda memilih antara merutekan melalui host dan mengakhiri terowongan di dalam kontainer. Tuliskan pilihan itu sebelum penerapan, bukan setelah permintaan gagal pertama. Apa pun yang Anda pilih, catat alamat sumber yang akan dilihat ujung jauh, karena itulah yang akan ditampilkan aturan akses dan lognya. Desain yang tidak dapat menyebutkan alamat itu belum selesai.
DNS mengikuti daemon, bukan terowongan
Kontainer mendapatkan konfigurasi resolver-nya saat mulai, disalin dari daemon atau dari image. Alamat yang didorong VPN setelah terhubung datang terlambat untuk salinan itu, dan alamat itu didorong ke resolver host, bukan ke dalam kontainer.
Tetapkan resolver secara eksplisit untuk layanan, atau arahkan ke resolver internal yang dapat dijangkau melalui terowongan. Kontainer yang menyelesaikan nama privat ke alamat publik biasanya memakai resolver publik, bukan menderita rute rusak, dan perbaikannya ada di berkas compose atau konfigurasi daemon.
Penalaran yang sama berlaku untuk pertanyaan alamat keluar. Jika setiap kontainer harus muncul dari alamat VPN yang berbeda, satu terowongan host tidak dapat menyediakannya karena NAT meruntuhkan semuanya menjadi satu sumber. Bentuk yang layak adalah klien di ruang nama setiap kontainer atau sidecar yang memiliki terowongan dan berbagi tumpukannya, dan keduanya mengubah cara aplikasi dialamatkan.
Daftar periksa sebelum menutup tiket: kenali ruang nama yang memiliki terowongan, buktikan jalur dengan jaringan host, petakan hanya perangkat tun yang diperlukan, ingat alamat sumber setelah NAT, tetapkan resolver secara eksplisit, dan perlakukan alamat keluar per kontainer sebagai keputusan arsitektur, bukan bendera.