VPN üzerinden Docker container'a ulaşılamıyor mu? Subnet'leri karşılaştırın
Docker, VPN'in de sahiplendiği bir subnet verir. İki adres planını karşılaştırın, sonra yeniden bağlanmaya dayanan bir onarım seçin.
Container'lar ofis LAN'ında yanıt verir, sonra şirket VPN'i bağlandığı anda yanıt vermeyi keser. Container'da hiçbir şey değişmedi: yeniden başlatma yok, imaj güncellemesi yok, yapılandırma düzenlemesi yok. Değişen, ana makinenin yönlendirme tablosudur; tünelin eklediği bir rota artık Docker'ın verdiği adresi kapsıyor. Bir subnet'i düzenlemeden veya VPN istisnası istemeden önce iki adres planını yan yana koyun, çünkü onarımlar çok farklı miktarda zaman alır.
Yapılandırmayı değiştirmeden önce rotayı okuyun
Docker'ın gerçekten kurduğu ağdan başlayın. IPAM bloğu adres planıdır ve subnet önemli olan satırdır:
docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]Compose varsayılan olarak her yeni projeye /16 ayırır, böylece iki hizmet 65,536 adreslik bir aralığa sığabilir. Bu genişlik, çakışmaların yaygın olmasının nedenidir: rastgele seçilmiş bir /16, tünel üzerinden ulaştığınız bir siteyi yutacak kadar büyüktür ve tünel açılana kadar kimse fark etmez.
Sonra bir container adresi için rota seçimini karşılaştırın: bir kez tünel kapalıyken, bir kez açıkken:
ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1İki yanıt biçimi farklı yerlere götürür. Çıktı tun0, wg0 veya başka bir tünel aygıtı adlandırıyorsa, VPN öneki köprü rotası kadar en az onun kadar belirgindir ve paket container'a asla ulaşmaz. Hâlâ köprüyü adlandırıyorsa, ana makine container'a ulaşabilir ve sizin hatanız filtreleme, DNS veya yalnızca tek yönde başarısız olan bir dönüş yoludur.
/16 çakışması neden kolay yakalanır
Docker köprü ağlarını özel havuzlardan alır ve varsayılan havuz 172.16.0.0/12 bloğundan /16 dilimleri hâlinde gelir. Kurumsal ağlar sıklıkla aynı özel alanı kullanır ve uzaktan erişim VPN'i bu önekleri bağlanan her istemciye iter. İki taraf da 172.18.0.0/16 adresini kendisinin sandığında, tek bir yönlendirme tablosunda iki çelişkili iddia bulunur.
Kazananı önek uzunluğu belirler, rotaların sırası değil. 10.0.0.0/8 iten bir tünel, 172.18.0.0/16 köprü rotasını yenmez, çünkü /8 daha az belirgindir. 172.18.0.0/16 veya içindeki 172.18.5.0/24 adresini iten tünel yener. Bu yüzden bir dizüstü bilgisayar ofis ağında çalışır ve aynı VPN ile otel Wi-Fi'sinde başarısız olur: istemci farklı önekler alır.
Aynı tablo ters yönü de yönetir. 10.8.4.20 adresindeki bir iç ana makineye ihtiyaç duyan container, paketi köprü geçidine gönderir ve ana makine onu tünele yönlendirir. Bu yol genellikle çalışır çünkü NAT'ı ana makine yapar, ancak kurumsal taraf yalnızca dizüstü bilgisayarın VPN adresini kabul ettiğinde veya ters yol filtrelemesi asimetrik yanıtı düşürdüğünde başarısız olur.
Üç onarımı karşılaştırın
Yalnızca üç çıkış yolu vardır ve bunlar kimin onaylaması gerektiği ve birini uygularken neyin bozulduğu bakımından farklıdır.
| Repair | Who owns it | What it costs |
|---|---|---|
| Renumber the container network | You | Recreates the network, restarts services, invalidates literal addresses in configs and scripts |
| Exclude your range from the tunnel | Network team | Changes what every laptop sees, needs a change request and a client profile update |
| Reach the service through a published port | You and the client | One port only, no direct container-to-container routing across the tunnel |
Yeniden numaralandırma, bilet olmadan tamamlayabileceğiniz tek onarımdır, bu yüzden yazıların çoğu orada durur. Genç bir projede ucuzdur ve bir geçiş aracı veya kayıtlı bağlantı dizesi gerçek bir adrese işaret etmeye başladığında pahalı olur. Bu referansları YAML'i düzenlemeden önce sayın, sonra değil.
Çakışma şirketinizin gerçekten sahip olduğu bir aralıktaysa, tünelden istisna en temiz yanıttır. Aynı zamanda en yavaşıdır ve istemci profilini değiştiremeyen bir yüklenici için işe yaramaz. Yayımlanmış bir port veya küçük bir ters vekil sunucu bu tartışmayı önler: istemci, tünelin zaten doğru yönlendirdiği bir adresle konuşur ve yalnızca o portun erişilebilir olması gerekir.
Bir aralığı bilerek sabitleyin
Tek bir proje için, proje ortak havuzdan çekmeyi bıraksın diye compose dosyasında subnet'i bildirin:
networks:
default:
ipam:
config:
- subnet: 10.201.7.0/24Bu aralığı, ararken bulduğunuz bir örnekten değil, ekibinizin tuttuğu kayıttan alın. VPN'in ittiği öneklerle, insanların çalıştığı ev LAN'larıyla ve aynı ana makinedeki diğer container ağlarıyla karşılaştırın. Sonra yeniden oluşturmayı planlayın, çünkü mevcut bir ağ eski subnet'ini korur: docker compose down, sonra up -d. Uç noktalar bağlıyken docker network rm reddeder ve dosyadaki herhangi bir ipv4_address girdisi yeni aralığın içine düşmelidir.
Docker'ın kendi oluşturduğu ağlar için /etc/docker/daemon.json içinde bir daemon havuzu ayarlayın:
{
"default-address-pools": [
{ "base": "10.201.0.0/16", "size": 24 },
{ "base": "10.202.0.0/16", "size": 24 }
]
}Havuz, daemon yeniden başladıktan sonra oluşturulan ağlar için geçerlidir ve zaten var olan köprüler adreslerini korur. Bu kullanışlıdır ve unutulması kolaydır, bu yüzden biri ağını yeniden oluşturana kadar eski bir projeyi hâlâ çakışıyor sayın. Docker'ın motor ağ belgeleri bir incelemede havuzu savunmanız gerekirse ayırma kurallarını açıklar.
Linux köprüsü ve Docker Desktop farklı biçimde başarısız olur
Bir Linux ana makinesinde container'lar ana makinenin ad alanındaki köprülerde oturur. Her şeye tek bir tablo karar verir, bu yüzden yukarıdaki karşılaştırma tüm hikâyedir: köprü rotasını okuyun, tünel rotasını okuyun ve gerçek bir container adresi için hangisinin kazandığına bakın.
Docker Desktop container'ları kendi NAT'ı olan bir VM'in arkasına koyar. Ana makinenin container adresine hiçbir rotası yoktur; hizmete yayımlanmış bir port üzerinden ulaşır, genellikle 127.0.0.1 adresine bağlıdır. Bu nedenle bir VPN istemcisi, herhangi bir subnet çakışması olmadan hizmeti bozabilir: ya VM'in iç aralığı için bir rota kurarak ya da tünel bağlıyken loopback trafiğini engelleyerek. Ana makinede ip route get container adresi için rota olmadığını bildiriyorsa bu beklenen bir durumdur, hata değil.
Pratik sonuç, ilk olarak nereye baktığınızdır. Linux'ta yönlendirme tablosuyla başlayın. Desktop'ta yayımlanmış portla ve VPN istemcisinin güvenlik duvarı kurallarıyla başlayın, sonra VM'in iç subnet'inin tünelin ittiği bir şeyle çakışıp çakışmadığını kontrol edin.
Tünel açıkken doğrulayın
Düzeldi demeden önce VPN'e iki kez yeniden bağlanın, çünkü bağlanırken rotaları iten ve bağlantı kesilince geri çeken bir profil ilk denemeden sonra doğru görünebilir. Sonra istemcinin gerçekte yaptığı kontrolleri çalıştırın:
- Container'ın gerçek adresini kullanarak ana makineden
ip route get. - Hizmetin kendisinin sağlıklı olduğunu kanıtlamak için başka bir container'dan bir istek.
- Tünel açıkken istemciden
curl -sv http://127.0.0.1:8080/, sonra LAN'deki bir makineden container adresinetraceroute -n. - İstek ana makineye ulaşıp yanıt kaybolursa
sysctl net.ipv4.conf.all.rp_filter.
Son olarak seçilen aralığı, onu seçmek için kullandığınız aynı kayda tarih ve ona sahip projeyle birlikte yazın. Bir sonraki çakışma kimsenin belgelemediği bir projeden gelecek ve tek savunma, aralığın rastgele çekilmek yerine bilerek ayrılmış olmasıdır.