Konteynerlər ofis LAN-ında cavab verir, sonra şirkət VPN-i qoşulan anda cavab verməyi dayandırır. Konteynerdə heç nə dəyişməyib: yenidən başlatma yoxdur, obraz yenilənməsi yoxdur, konfiqurasiya düzəlişi yoxdur. Dəyişən hostun marşrut cədvəlidir: tunelin əlavə etdiyi marşrut indi Docker-in verdiyi ünvanı əhatə edir. Alt şəbəkəni düzəltməzdən və ya VPN istisnası istəməzdən əvvəl hər iki ünvan planını yan-yana qoyun, çünki düzəlişlər çox fərqli vaxt tələb edir.

Konfiqurasiyanı dəyişməzdən əvvəl marşrutu oxuyun

Docker-in həqiqətən qurduğu şəbəkə ilə başlayın. IPAM bloku ünvan planıdır, alt şəbəkə isə vacib olan sətirdir:

docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]

Compose hər yeni layihəyə defolt olaraq /16 ayırır, yəni iki xidmət 65,536 ünvandan ibarət diapazonun içində otura bilər. Bu genişlik toqquşmaların tez-tez olmasının səbəbidir: təsadüfi seçilmiş /16 tuneldən keçdiyiniz saytı udmaq üçün kifayət qədər böyükdür və tunel qalxana qədər heç kim bunu hiss etmir.

Sonra bir konteyner ünvanı üçün marşrut seçimini müqayisə edin: bir dəfə tunel bağlı, bir dəfə açıq:

ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1

İki cavab forması fərqli yerlərə aparır. Çıxış tun0, wg0 və ya başqa tunel qurğusunun adını çəkirsə, VPN prefiksi körpü marşrutundan ən azı eyni dərəcədə dəqiqdir və paket konteynerə heç vaxt çatmır. Əgər çıxış hələ də körpünü göstərirsə, host konteynerə çata bilir və sizin nasazlığınız filtrləmə, DNS və ya yalnız bir istiqamətdə uğursuz olan geri yoludur.

Niyə /16 toqquşması asan baş verir

Docker körpü şəbəkələrini özəl hovuzlardan götürür, defolt hovuz isə 172.16.0.0/12 blokundan /16 dilimləri ilə çıxır. Korporativ şəbəkələr çox vaxt eyni özəl məkandan istifadə edir və uzaqdan giriş VPN-i bu prefiksləri qoşulan hər klientə ötürür. Hər iki tərəf 172.18.0.0/16-a sahib olduğuna inandıqda, bir marşrut cədvəli iki zidd iddia daşıyır.

Qalibi prefiksin uzunluğu müəyyən edir, marşrutların görünmə sırası deyil. 10.0.0.0/8 ötürən tunel 172.18.0.0/16, /8 daha az dəqiq olduğu üçün, körpü marşrutunu üstələmir. Tunel 172.18.0.0/16, yaxud onun içindəki 172.18.5.0/24 alt şəbəkəsini ötürən tunel isə üstələyir. Buna görə bir noutbuk ofis şəbəkəsində işləyir, otel Wi-Fi-da isə eyni VPN ilə uğursuz olur: klient fərqli prefikslər alır.

Eyni cədvəl digər istiqaməti də idarə edir. 10.8.4.20 ünvanında daxili hosta ehtiyac duyan konteyner paketi öz körpü şlüzuna göndərir, host da onu tunelə yönləndirir. Bu yol adətən işləyir, çünki NAT-ı host yerinə yetirir, lakin korporativ tərəf yalnız noutbukun VPN ünvanını qəbul etdikdə və ya tərs yol filtrləməsi asimmetrik cavabı atdıqda uğursuz olur.

Üç düzəlişi müqayisə edin

Yalnız üç çıxış yolu var və onlar kimin təsdiq verməli olduğuna və birini tətbiq edərkən nəyin pozulduğuna görə fərqlənir.

RepairWho owns itWhat it costs
Renumber the container networkYouRecreates the network, restarts services, invalidates literal addresses in configs and scripts
Exclude your range from the tunnelNetwork teamChanges what every laptop sees, needs a change request and a client profile update
Reach the service through a published portYou and the clientOne port only, no direct container-to-container routing across the tunnel

Yenidən nömrələmə bilet olmadan bitirə biləcəyiniz yeganə düzəlişdir, buna görə əksər yazılar orada dayanır. Gənc layihədə ucuz, miqrasiya aləti və ya saxlanılmış qoşulma sətri hərfi ünvana işarə etdikdən sonra isə bahalıdır. O istinadları YAML-ı düzəltməzdən əvvəl sayın, sonra deyil.

Tuneldən istisna, toqquşma şirkətinizin həqiqətən sahib olduğu diapazonda olduqda ən təmiz cavabdır. Həm də ən yavaşıdır və klient profilini dəyişə bilməyən podratçı üçün faydasızdır. Yayımlanmış port və ya kiçik tərs proksi mübahisədən qaçır: klient tunelin artıq düzgün yönləndirdiyi ünvanla danışır və yalnız həmin port əlçatan olmalıdır.

Diapazonu qəsdən sabitləyin

Tək layihə üçün alt şəbəkəni compose faylında elan edin ki, layihə ortaq hovuzdan çəkməyi dayandırsın:

networks:
  default:
    ipam:
      config:
        - subnet: 10.201.7.0/24

Bu diapazonu axtarış zamanı tapdığınız nümunədən deyil, komandanızın saxladığı reyestrdən götürün. Onu VPN-in ötürdüyü prefikslərlə, insanların işlədiyi ev LAN-ları ilə və eyni hostdakı digər konteyner şəbəkələri ilə tutuşdurun. Sonra yenidən yaratmağı planlaşdırın, çünki mövcud şəbəkə köhnə alt şəbəkəsini saxlayır: docker compose down, sonra up -d. docker network rm son nöqtələr qoşulmuş halda imtina edir və fayldakı hər hansı ipv4_address qeydi yeni diapazonun içində olmalıdır.

Docker-in özü yaratdığı şəbəkələr üçün /etc/docker/daemon.json-də demon hovuzu təyin edin:

{
  "default-address-pools": [
    { "base": "10.201.0.0/16", "size": 24 },
    { "base": "10.202.0.0/16", "size": 24 }
  ]
}

Hovuz demon yenidən başladıqdan sonra yaradılan şəbəkələrə aiddir, artıq mövcud olan körpülər isə ünvanlarını saxlayır. Bu rahatdır və unutmaq asandır, ona görə köhnə layihəni kimsə şəbəkəsini yenidən yaradana qədər hələ də toqquşan hesab edin. Docker-in mühərrik şəbəkə sənədləri ayırma qaydalarını təsvir edir, əgər hovuzu baxışda müdafiə etməli olsanız.

Linux körpüsü və Docker Desktop fərqli uğursuz olur

Linux hostunda konteynerlər host adlar fəzasındakı körpülərdə oturur. Hər şeyi bir cədvəl həll edir, ona görə yuxarıdakı müqayisə bütün mənzərədir: körpü marşrutunu oxuyun, tunel marşrutunu oxuyun və real konteyner ünvanı üçün hansının qalib gəldiyini görün.

Docker Desktop konteynerləri öz NAT-ı olan VM-in arxasına qoyur. Hostun konteyner ünvanına heç bir marşrutu yoxdur; xidmətə yayımlanmış port vasitəsilə çatır, adətən 127.0.0.1-a bağlanır. Buna görə VPN klienti heç bir alt şəbəkə toqquşması olmadan xidməti poza bilər: ya VM-in daxili diapazonu üçün marşrut quraraq, ya da tunel qoşulmuş halda loopback trafikini bloklayaraq. Əgər hostda ip route get konteyner ünvanı üçün marşrut olmadığını bildirirsə, bu gözləniləndir, nasazlıq deyil.

Praktik nəticə ilk olaraq hara baxdığınızdır. Linuxda marşrut cədvəlindən başlayın. Desktopda yayımlanmış portdan və VPN klientinin firewall qaydalarından başlayın, sonra VM-in daxili alt şəbəkəsinin tunelin ötürdüyü nə iləsə toqquşub-toqquşmadığını yoxlayın.

Tunel açıq halda yoxlayın

Düzəldi deməzdən əvvəl VPN-i iki dəfə yenidən qoşun, çünki qoşulanda marşrutları ötürən və ayrılarkən geri götürən profil ilk cəhddən sonra doğru görünə bilər. Sonra klientin həqiqətən icra etdiyi yoxlamaları işə salın:

  1. ip route get hostdan, konteynerin real ünvanı ilə.
  2. Xidmətin özünün sağlam olduğunu sübut etmək üçün başqa konteynerdən sorğu.
  3. curl -sv http://127.0.0.1:8080/ tunel açıq halda klientdən, sonra traceroute -n LAN-dakı maşından konteyner ünvanına.
  4. sysctl net.ipv4.conf.all.rp_filter əgər sorğu hosta çatır, cavab isə yox olursa.

Nəhayət, seçilmiş diapazonu onu seçmək üçün istifadə etdiyiniz eyni reyestrə yazın: tarixlə və ona sahib olan layihə ilə. Növbəti toqquşma heç kimin sənədləşdirmədiyi layihədən gələcək və yeganə müdafiə diapazonun təsadüfi çəkilməsi deyil, qəsdən qorunmasıdır.

Əlaqəli məqalələr