Контейнерлер кеңсе LAN-ында жауап береді, содан кейін компания VPN-і қосылған сәтте жауап беруді тоқтатады. Контейнерде ештеңе өзгерген жоқ: қайта іске қосу жоқ, бейнені жаңарту жоқ, конфигурацияны өңдеу жоқ. Өзгерген нәрсе — хосттың маршруттау кестесі, онда туннель қосқан маршрут енді Docker берген мекенжайды қамтиды. Ішкі желіні өңдеуден немесе VPN-нен ерекшелеу сұрауынан бұрын екі мекенжай жоспарын қатар қойыңыз, өйткені түзетулер әртүрлі уақытты талап етеді.

Конфигурацияны өзгертуден бұрын маршрутты оқыңыз

Docker шын мәнінде құрған желіден бастаңыз. IPAM блогы — мекенжай жоспары, ал ішкі желі — маңызды жол:

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

Compose әдепкі бойынша әр жаңа жобаға /16 бөледі, сондықтан екі қызмет 65,536 мекенжай диапазонында орналаса алады. Дәл осы ен қабаттасуды жиі етеді: кездейсоқ таңдалған /16 туннель арқылы қол жеткізетін сайтты жұтып қоюға жеткілікті, және туннель көтерілгенше ешкім байқамайды.

Содан кейін бір контейнер мекенжайы үшін маршрут таңдауын салыстырыңыз — бір рет туннель өшірулі, бір рет қосулы:

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

Жауаптың екі түрі әртүрлі жерге апарады. Егер шығыста tun0, wg0 немесе басқа туннель құрылғысы көрсетілсе, VPN префиксі көпір маршрутынан кемінде соншалықты нақты және пакет контейнерге ешқашан жетпейді. Егер ол әлі де көпірді атаса, хост контейнерге жете алады, ал сіздің ақауыңыз — сүзу, DNS немесе тек бір бағытта сәтсіз болатын қайтару жолы.

Неге /16 қақтығысы оңай орын алады

Docker көпір желілерін жеке пулдардан алады, ал әдепкі пул 172.16.0.0/12 блогынан /16 тілімдерімен шығады. Корпоративтік желілер жиі сол жеке кеңістікті пайдаланады, ал қашықтан қатынау VPN-і бұл префикстерді қосылған әр клиентке жібереді. Екі жақ та 172.18.0.0/16 иемденеді деп сенсе, бір маршруттау кестесінде екі қарама-қайшы талап тұрады.

Жеңімпазды маршруттардың кезектілігі емес, префикс ұзындығы анықтайды. Туннель 10.0.0.0/8 жіберсе, ол 172.18.0.0/16 көпір маршрутынан басым түспейді, өйткені /8 нақтырақ емес. Туннель 172.18.0.0/16, немесе 172.18.5.0/24 ішіндегісін жіберсе, басым түседі. Сондықтан бір ноутбук кеңсе желісінде жұмыс істеп, қонақүй Wi-Fi-інде сол VPN-мен істемейді: клиент әртүрлі префикстер алады.

Сол кесте қарама-қарсы бағытты да басқарады. 10.8.4.20 мекенжайындағы ішкі хост қажет контейнер пакетті өзінің көпір шлюзіне жібереді, содан кейін хост оны туннельге маршруттайды. Бұл жол әдетте жұмыс істейді, өйткені NAT-ты хост орындайды, бірақ корпоративтік жақ тек ноутбуктің VPN мекенжайын қабылдағанда немесе кері жол сүзгісі асимметриялық жауапты тастағанда істемейді.

Үш түзетуді салыстырыңыз

Тек үш шығар жол бар, олар кімнің мақұлдауы қажет екенімен және қолданған кезде не бұзылатынымен ерекшеленеді.

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

Қайта нөмірлеу — билетсіз аяқтай алатын жалғыз түзету, сондықтан көптеген жазбалар осымен тоқтайды. Жас жобада ол арзан, ал миграция құралы немесе сақталған қосылым жолы нақты мекенжайға сілтесе — қымбат. YAML-ды өңдеуден бұрын сол сілтемелерді санаңыз, кейін емес.

Туннельден ерекшелеу — қабаттасу компания шынымен иемденетін диапазонда болса, ең таза жауап. Ол сонымен бірге ең баяу, және клиент профилін өзгерте алмайтын мердігер үшін пайдасыз. Жарияланған порт немесе шағын кері прокси дауды болдырмайды: клиент туннель дұрыс маршруттайтын мекенжаймен сөйлеседі, тек сол порт қолжетімді болуы керек.

Диапазонды әдейі бекітіңіз

Бір жоба үшін ішкі желіні compose файлында жариялаңыз, сонда жоба ортақ пулдан алуды тоқтатады:

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

Бұл диапазонды іздеу кезінде тапқан мысалдан емес, командаңыз ұстайтын тіркелімнен алыңыз. Оны VPN жіберетін префикстермен, адамдар жұмыс істейтін үй LAN-дарымен және сол хосттағы басқа контейнер желілерімен салыстырыңыз. Содан кейін қайта құруды жоспарлаңыз, өйткені бар желі ескі ішкі желісін сақтайды: docker compose down, содан кейін up -d. docker network rm шеткі нүктелер тіркелген кезде бас тартады, және кез келген ipv4_address жазбасы файлда жаңа диапазонның ішінде болуы керек.

Docker өзі жасайтын желілер үшін демон пулын /etc/docker/daemon.json:

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

Пул демон қайта іске қосылғаннан кейін жасалған желілерге қолданылады, ал бұрыннан бар көпірлер өз мекенжайларын сақтайды. Бұл ыңғайлы және ұмытуға оңай, сондықтан ескі жобаны біреу желісін қайта жасағанша қабаттасқан деп есептеңіз. Docker-дің қозғалтқыш желісінің құжаттамасы бөлу ережелерін сипаттайды, егер пулды шолуда қорғау қажет болса.

Linux көпірі мен Docker Desktop әртүрлі сәтсіз болады

Linux хостта контейнерлер хост namespace-індегі көпірлерде отырады. Бәрін бір кесте шешеді, сондықтан жоғарыдағы салыстыру — толық әңгіме: көпір маршрутын оқыңыз, туннель маршрутын оқыңыз және нақты контейнер мекенжайы үшін қайсысы басым екенін көріңіз.

Docker Desktop контейнерлерді өз NAT-ы бар VM артына қояды. Хосттың контейнер мекенжайына маршруты мүлде жоқ; ол қызметке жарияланған порт арқылы жетеді, ол әдетте 127.0.0.1 мекенжайына байланыстырылады. VPN клиенті қызметті ішкі желі қабаттасуынсыз-ақ бұза алады: не VM-нің ішкі диапазонына маршрут орнатып, не туннель қосулы кезде loopback трафигін блоктап. Егер ip route get хостта контейнер мекенжайы үшін маршрутты хабарламаса, бұл күтілетін жағдай, ақау емес.

Практикалық салдары — алдымен қайда қарайтыныңыз. Linux-те маршруттау кестесінен бастаңыз. Desktop-та жарияланған порт пен VPN клиентінің firewall ережелерінен бастаңыз, содан кейін VM-нің ішкі желісі туннель жіберетін нәрсемен қабаттаса ма, соны тексеріңіз.

Туннель қосулы кезде тексеріңіз

Түзетілді деп айтпас бұрын VPN-ді екі рет қайта қосыңыз, өйткені қосылғанда маршруттарды жіберіп, ажырағанда кері қайтаратын профиль бірінші әрекеттен кейін дұрыс көрінуі мүмкін. Содан кейін клиент шын мәнінде орындайтын тексерулерді іске қосыңыз:

  1. ip route get хосттан, контейнердің нақты мекенжайын пайдаланып.
  2. Басқа контейнерден сұрау — қызметтің өзі сау екенін дәлелдеу үшін.
  3. curl -sv http://127.0.0.1:8080/ туннель қосулы кезде клиенттен, содан кейін traceroute -n LAN-дағы машинадан контейнер мекенжайына.
  4. sysctl net.ipv4.conf.all.rp_filter егер сұрау хостқа жетіп, жауап жоғалса.

Соңында таңдалған диапазонды оны таңдау үшін пайдаланған тіркелімге күнімен және оны иемденетін жобамен бірге жазыңыз. Келесі қабаттасу ешкім құжаттамаған жобадан шығады, ал жалғыз қорғаныс — диапазон кездейсоқ емес, әдейі бөлінген болуы.

Қатысты мақалалар