Kurumsal VPN'in arkasındaki hiçbir şeye ulaşamayan bir konteyner genellikle tünelden farklı bir ağ ad alanında yaşar. Ana makine istemcisinin rotaları, DNS sunucuları ve güvenlik duvarı işaretleri ana makinenin yığınına aittir; köprü ağındaki konteynerin kendi yığını vardır. Bu tek gerçek, platform ekibine ulaşan raporların çoğunu açıklar ve «VPN bozuk» ile «Docker VPN'i atlıyor» ifadelerinin aynı anda yanlış olabilmesinin nedeni de budur. Tek bir belirtinin arkasında iki çok farklı yapılandırma gizlenir, bu nedenle herhangi bir ayarı değiştirmeden önce hangisine sahip olduğunuzu belirleyin.

Tünelin hangi ad alanına ait olduğunu bulun

macOS veya Windows için Docker Desktop'ta konteynerler bir Linux sanal makinesinin içinde çalışır. Masaüstüne kurulan VPN istemcisi masaüstü işletim sisteminde bir tünel oluşturur ve sanal makine bunu asla görmez. Hiçbir konteyner yapılandırması bunu düzeltemez, çünkü konteynerin ihtiyaç duyacağı arayüz onun ağ ad alanında hiç yoktur.

Bir Linux ana makinesinde tünel ana makinenin ad alanında yaşar ve köprü konteynerleri ona genellikle çıkışta kaynak NAT uygulanan ana makinenin yönlendirme tablosu üzerinden ulaşır. Bu yol başarısız olduğunda neden genellikle eksik bir rota değil, yönlendirme politikası, ters yol filtrelemesi veya çakışan bir alt ağdır. Daha fazla okumadan önce iki dünyadan hangisinde olduğunuzu doğrulayın:

docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5

Bu iki yönlendirme tablosu arasındaki fark, tek ekranda tüm sorundur. Ana makinenin görünümü tünel arayüzünü içeriyorsa ve köprünün görünümü içermiyorsa, ad alanı yalıtımına bakıyorsunuz ve geri kalan her şey onu nasıl aşacağınıza dair bir seçimdir.

Ana makine ağı bir testtir, tasarım değil

Bir konteyneri ana makine ağıyla çalıştırmak, ki Docker bunu ana makinenin ağ ad alanını paylaşma olarak belgeler, onun tünel arayüzünü ve rotalarını doğrudan miras almasını sağlar. Aynı istek ardından başarılı olursa rota teorisi doğrulanır ve hata ad alanı yalıtımıdır, kimlik bilgileri, DNS veya bir erişim kuralı değil.

docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health

Bunu teşhis olarak tutun. Ana makine ağı bağlantı noktası yayınlamayı ve bir konteynerden istediğiniz yalıtımın çoğunu bırakır ve Docker Desktop'ta «host» masaüstü değil sanal makine anlamına gelir, bu nedenle hangi ana makineye hitap ettiğinizi unutursanız oradaki başarı veya başarısızlık sizi yanıltabilir.

Bir tun aygıtı ve beraberinde gelen ayrıcalıklar

Konteyner içindeki VPN istemcisi bir tünel aygıtına ve onu yapılandırma iznine ihtiyaç duyar. Yaygın kısayol --privileged olup her aygıtı verir ve güvenlik politikasını tüm konteynerde gevşetir. Bu, bu işin gerektirdiğinden çok daha fazladır ve bir incelemede gerekçelendirmek zordur.

sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client

Daha dar biçim tek aygıt düğümünü eşler ve yalnızca ağ yönetimi yeteneğini ekler. Düğümün var olması için önce modülü ana makineye yükleyin. Konteyner başlar ve istemci tünel aygıtını açamadığını bildirirse, profilden şüphelenmeden önce eşlemeyi kontrol edin, çünkü bu hata genellikle harfidir.

Bu tasarım ayrıca istemcinin her konteyner için çalıştığı anlamına gelir. Her iş yükünün kendi tüneli gerektiğinde bu doğru yanıttır ve yalnızca ana makinenin tünelinin görünmesini istediğinizde yanlış yanıttır; platform ekibi büyük olasılıkla bunu yaptığınızı varsaymıştır.

Köprü NAT'ı VPN'in gördüğü kaynağı değiştirir

Varsayılan köprüde konteynerin giden trafiği ana makinenin adresine çevrilir. Bu nedenle VPN'in arkasında kurumsal taraf konteynerin değil ana makinenin tünel adresini görür, kaynağa göre erişim kuralları isteği ana makine göndermiş gibi davranır ve iki konteyner VPN sunucusu için ayırt edilemez hale gelir.

macvlan veya ipvlan bunun yerine konteynere bir LAN adresi verir; bu LAN keşfine yardımcı olur ve konteyneri segmentte eşit bir üye gibi gösterir. Ayrıca ana makinenin tünelini tamamen atlar, bu nedenle böyle bir konteyner yalnızca-VPN öneklerine ulaşmaz, VPN o LAN'dan da erişilebilir değilse.

Her iki biçim de meşrudur; farklı gereksinimlere yanıt verirler. Gereksinim «bu konteyner yalnızca-VPN bir hizmete ulaşmalı» ise, ana makine üzerinden yönlendirme ile tüneli konteyner içinde sonlandırma arasında seçim yaparsınız. Bu seçimi dağıtımdan önce yazın, ilk başarısız istekten sonra değil. Neyi seçerseniz seçin, uzak ucun göreceği kaynak adresini kaydedin, çünkü erişim kuralları ve günlükleri tam olarak onu gösterecektir. Bu adresi belirtemeyen bir tasarım bitmiş değildir.

DNS, tüneli değil daemon'u izler

Bir konteyner çözümleyici yapılandırmasını başlangıçta alır, daemon'dan veya imajdan kopyalanır. VPN bağlandıktan sonra ittiği adresler bu kopya için çok geç gelir ve konteynerin içine değil ana makinenin çözümleyicisine itilir.

Çözümleyiciyi hizmet için açıkça ayarlayın veya tünel üzerinden erişilebilen bir iç çözümleyiciye yönlendirin. Özel bir adı genel bir adrese çözen konteyner genellikle genel bir çözümleyici kullanır, bozuk bir rotadan muzdarip değildir ve düzeltme compose dosyasına veya daemon yapılandırmasına aittir.

Aynı mantık çıkış adresi sorunu için de geçerlidir. Her konteyner farklı bir VPN adresinden görünmek zorundaysa, tek bir ana makine tüneli bunu sağlayamaz çünkü NAT onları tek bir kaynağa indirger. Uygulanabilir biçimler, her konteynerin ad alanında bir istemci veya tünele sahip olan ve yığınını paylaşan bir sidecar biçimidir ve her ikisi de uygulamanın nasıl adreslendiğini değiştirir.

Bileti kapatmadan önce kontrol listesi: tünele sahip ad alanını belirleyin, yolu ana makine ağıyla kanıtlayın, yalnızca gereken tun aygıtını eşleyin, NAT sonrası kaynak adresini hatırlayın, çözümleyiciyi açıkça ayarlayın ve konteyner başına çıkış adreslerini bayrak değil mimari karar olarak ele alın.

İlgili makaleler