API peribadi dibuka dalam pelayar desktop anda dan gagal dalam kontena pembangunan. Itu bukan percanggahan, dan jarang VPN itu sendiri penyebabnya. Permintaan pelayar dan permintaan yang gagal dibuat oleh proses yang berbeza, dengan resolver, proksi dan laluan yang berbeza, dan selalunya dari ruang nama rangkaian yang sama sekali berbeza. “Pada komputer riba saya” boleh bermaksud hos Windows, pengedaran WSL, mesin maya Docker Desktop dan kontena di dalam VM itu — empat konteks yang setiap satunya boleh menjawab nama hos yang sama secara berbeza. Ketahui yang mana digunakan oleh proses yang gagal sebelum anda menyentuh satu tetapan pun.

Cari proses sebelum menukar tetapan

Mulakan dengan enjin kontena, bukan klien VPN. Tanya konteks mana yang sedang dilalui baris perintah, dan sistem pengendalian apa yang menjalankan enjin itu, kerana kontena Linux yang diurus oleh VM desktop melalui laluan berbeza daripada yang diurus oleh daemon tempatan:

docker context ls
docker info --format '{{.OperatingSystem}} / {{.Name}}'
docker run --rm alpine ip route

Pada Windows, wsl -l -v memberitahu sama ada pengedaran berjalan di bawah WSL 2, yang meletakkannya di belakang suis mayanya sendiri. Butiran itu menentukan sama ada kontena berkongsi jadual penghalaan hos atau berada di belakang NAT yang memerlukan port dimajukan atau nama hos untuk sampai ke hos.

Kekalkan satu permintaan dan bandingkan

Pilih satu titik akhir tidak berbahaya pada hos peribadi dan gunakannya untuk setiap perbandingan: dari pelayar, dari terminal hos, dari pengedaran WSL dan dari dalam kontena. Catat empat perkara untuk setiap percubaan: alamat yang diselesaikan, sama ada proksi digunakan, kelas kegagalan dan masa yang berlalu. Carian nama, pembentukan sambungan, pengesahan TLS dan status HTTP ialah empat masalah berbeza, dan mencampurkannya menjadi “tidak berfungsi” membazirkan satu pagi.

Jalankan perbandingan di dalam kontena yang gagal, dengan had masa supaya tembok api senyap tidak menahan terminal selama minit. Kontena baharu menghasilkan semula konteks rangkaian enjin, tetapi bukan ruang nama, pemboleh ubah proksi atau resolver kontena aplikasi, jadi docker exec ke dalam kontena sebenar ialah ujian yang muktamad, dan kontena sampingan hanyalah cara untuk mengasingkan sama ada perbezaan itu pada enjin atau pada kontena:

docker exec -it app /bin/sh -c "getent hosts api.internal; curl -v --max-time 8 https://api.internal/ 2>&1 | tail -20"
docker run --rm --network container:app curlimages/curl:latest -sv --max-time 8 https://api.internal/ 2>&1 | tail -20

Imej asas alpine membawa busybox dan tiada curl, dan itulah jenis butiran yang membuat blok diagnostik yang disalin gagal: pilih imej yang mempunyai klien, atau tambahkannya dalam larian yang sama. Perbandingan dengan tapak awam yang tidak berkaitan tidak mengasingkan apa-apa. Jika https://example.com berfungsi dari kontena, anda hanya belajar bahawa kontena mempunyai akses internet, dan tiada apa tentang sama ada ia mencapai alamat peribadi melalui terowong. Begitu juga, membuka terminal baharu hanya membuktikan terminal baharu itu berfungsi, bukan bahawa ia berkongsi runtime dengan aplikasi yang gagal.

Docker Desktop boleh berfungsi dengan VPN

Dokumentasi Docker sendiri tentang VPN dan kesambungan hos menggambarkannya sebagai persediaan yang disokong, dan ringkasan jujurnya ialah ia berfungsi dan bukan rosak secara automatik. Jangan anggap VM desktop memintas terowong hos sebagai perkara reka bentuk; dalam banyak persediaan trafik mengikut terowong hos dengan betul, dan itulah sebabnya mitos “Docker mengabaikan VPN” menghasilkan nasihat yang yakin dan salah.

Yang masih penting ialah backend yang digunakan, dasar split-tunnel klien dan konfigurasi resolver yang diterima VM. Klien VPN yang memasang laluan tetapi bukan DNS, atau yang menolak pelayan DNS yang tidak dapat dicapai VM, menghasilkan kegagalan carian nama di dalam kontena sementara hos berfungsi kerana hos mempunyai resolver tambahan atau jawapan yang dicache. Itu masalah resolver yang memakai kostum kontena. Ia bertahan pada setiap sambungan semula VPN yang anda cuba, kerana terowong sudah membawa trafik yang anda minta.

Pertindihan alamat dan MTU ialah kegagalan berbeza

Dua kegagalan wajar didiagnosis sendiri kerana ia sering disalah anggap sebagai dasar akses. Yang pertama ialah pertindihan alamat: jika VPN menolak julat yang berlanggar dengan subrangkaian jambatan lalai rangkaian kontena, laluan kontena untuk julat itu menunjuk ke jambatan tempatan dan tidak pernah sampai ke terowong. Periksa subrangkaian sebenar daripada meneka:

docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
ip route get 10.20.30.40

Yang kedua ialah masalah MTU. Jika sambungan terbentuk dan TLS selesai tetapi respons yang lebih besar tersekat, anda mempunyai masalah saiz paket, bukan masalah kebenaran, dan menggantikan rekod DNS tidak akan pernah membaikinya. Uji dengan permintaan kecil dan besar sebelum menukar apa-apa, dan catat kedua-dua hasil.

Penyelesaian untuk pertindihan ialah subrangkaian kontena lain atau laluan terhad, dipilih oleh pemilik pelan alamat. Penyelesaian untuk tersekat MTU ialah mengepit atau mengurangkan MTU terowong atau antara muka kepada nilai yang bertahan di laluan, digunakan pada lapisan yang anda kawal.

Konfigurasi proksi adalah per proses, bukan per mesin

Di dalam kontena, localhost menamakan konteks rangkaian kontena itu sendiri, jadi proksi yang berjalan pada hos tidak dapat dicapai di sana dengan nama itu. Docker Desktop menyediakan host.docker.internal untuk akses hos, dan pada Linux anda menambahnya secara eksplisit dengan --add-host=host.docker.internal:host-gateway. Walau apa pun, nama itu memberi anda laluan ke hos; ia tidak mencipta perkhidmatan proksi atau memberi anda kuasa untuk menggunakannya.

Gunakan alamat dan port proksi yang disediakan untuk persekitaran sebenar, dan periksa siapa yang membacanya. Pemboleh ubah yang dieksport dalam shell interaktif tidak mengkonfigurasi setiap sambungan editor, pelayan bahasa, alat binaan dan daemon latar belakang secara automatik. Yang penting ialah proses yang membuat permintaan yang gagal, jadi periksa persekitarannya dan bukan persekitaran terminal anda.

Akhir sekali, biarkan pembetulan menjelaskan dirinya sendiri. Penyelesaian yang berguna menamakan sempadan yang salah, tetapan yang mengubahnya dan set proses yang kini terjejas. Memulakan semula VPN, editor dan enjin secara berturutan mungkin mengubah simptom, tetapi tidak meninggalkan apa-apa yang boleh digunakan oleh orang seterusnya.

Artikel berkaitan