Ви додаєте network_mode: service:vpn до застосунку, перезапускаєте стек, і застосунок помирає, бо db більше не розв’язується. У файлі compose нічого не перейменовано, тому очевидні підозрювані — DNS і база даних. Справжня зміна менша й дивніша: застосунок перестав бути учасником мережі Compose, де існує це ім’я. Поки ви не вирішите, з якого простору імен має відповідати база даних, кожне виправлення імені хоста — здогад.

Чому ім’я хоста db перестало розв’язуватися

Служба, що використовує network_mode, не має власної адреси в мережі Compose; вона позичає простір імен названої служби. Цей простір приносить свої інтерфейси, маршрути, простір портів і резолвер, і він замінює підключення застосунку до мережі backend. Ім’я db ніколи не було абстрактним: воно жило в цій мережі й розв’язувалося через її вбудований DNS. Приберіть підключення, і імені ніде розв’язуватися.

Підтвердьте це зсередини контейнерів, а не з хоста. Пошук, що не вдається в застосунку, але вдається в контейнері бази даних, означає, що ім’я гаразд, а членство — ні. Цей результат також поміщає виправлення в топологію compose, а не в налаштування резолвера застосунку.

Три питання перед редагуванням файлу

Відповідайте по порядку, бо кожне звужує топологію. На що має відповідати база даних: на ім’я хоста, яке використовують інші контейнери, чи лише на застосунок на loopback? Чи має застосунок публікувати порт на хост, і яка служба володіла б ним? Чи має база даних бути доступною з хоста або з іншої машини, чи лише зсередини тунелю?

Якщо базі даних потрібне власне ім’я, а застосунок нічого не публікує, тримайте їх на окремих підключеннях. Якщо застосунок має публікувати порт і все йде через тунель, помістіть базу даних у простір імен VPN і використовуйте loopback. Змішування обох дає стек, який чисто запускається і падає під час підключення.

Залиште базу даних там, де вона є

Менша зміна підключає власника простору імен до мережі, яка вже містить базу даних. Застосунок успадковує це підключення, бо ділить стек vpn, і db розв’язується точно як раніше.

services:
  vpn:
    networks:
      - backend
  app:
    network_mode: service:vpn
  db:
    networks:
      - backend
networks:
  backend:

Не додавайте networks і до застосунку. Compose відхиляє цю властивість разом з network_mode у тій самій службі, і помилка вказує на файл, а не на пару. Якщо клієнт VPN фільтрує призначення backend у своєму просторі імен, налаштуйте і його підтримувану політику локальної мережі; спільне підключення пропонує шлях, але не скасовує цей фільтр.

Перемістіть базу даних у простір імен

Більша зміна поміщає базу даних у той самий простір імен і скеровує застосунок на 127.0.0.1 із справжнім портом. Два процеси не можуть обидва зайняти ту саму адресу й порт лише тому, що запустилися в різних контейнерах, тож база даних, яка також слухає на wildcard-адресі, зіткнеться з усім іншим, що це робить. Перевірте слухача перед переміщенням.

Опубліковані порти належать службі, яка володіє простором імен. Додавання ports до застосунку відхиляється разом з network_mode, а вигадування окремої адреси застосунку описує інтерфейс, якого немає.

Готовність, блокування і резолвер

depends_on упорядковує запуск контейнерів; це не доказ, що тунель працює, і він не зупиняє трафік, коли тунель падає. Розглядайте доступність, готовність тунелю й блокування відмов як три окремі вимоги. Стек, що задовольняє лише першу, проходить ручний тест у добрий день і тече в поганий. Запишіть три відповіді поряд із файлом compose, там, куди подивиться наступна людина.

Спільний простір імен також означає, що застосунок успадковує резолвер контейнера VPN, що допомагає, коли тунель нав’язує DNS-сервери, і заплутує, коли не робить цього. Перевірте, що простір імен насправді містить, замість припускати, що резолвер хоста застосовний. Довідник служб Compose документує network_mode, ports і поведінку залежностей в одному місці, включно з тим, чому служба network_mode не має власної адреси.

Схожі статті