network_mode: service:vpn i brakująca nazwa hosta db
Współdzielenie przestrzeni nazw VPN to wybór topologii. Albo db zachowuje własny adres i vpn dołącza do tej sieci, albo wszystko odpowiada na loopback.
Dodajesz network_mode: service:vpn do aplikacji, restartujesz stos, a aplikacja umiera, bo db nie jest już rozwiązywana. W pliku compose nic nie zostało zmienione, więc oczywistymi podejrzanymi są DNS i baza danych. Rzeczywista zmiana jest mniejsza i dziwniejsza: aplikacja przestała być członkiem sieci Compose, w której ta nazwa istnieje. Dopóki nie zdecydujesz, z której przestrzeni nazw baza ma odpowiadać, każda poprawka nazwy hosta jest zgadywaniem.
Dlaczego nazwa hosta db przestała się rozwiązywać
Usługa używająca network_mode nie ma własnego adresu w sieci Compose; pożycza przestrzeń nazw nazwanej usługi. Ta przestrzeń wnosi własne interfejsy, trasy, przestrzeń portów i resolver, i zastępuje przyłączenie aplikacji do sieci backend. Nazwa db nigdy nie była abstrakcyjna: żyła w tej sieci i była rozwiązywana przez jej wbudowany DNS. Usuń przyłączenie, a nazwa nie ma gdzie się rozwiązać.
Potwierdź to od wewnątrz kontenerów, a nie z hosta. Wyszukanie, które zawodzi w aplikacji, ale udaje się w kontenerze bazy danych, oznacza, że nazwa jest w porządku, a członkostwo nie. Ten wynik umieszcza też poprawkę w topologii compose, a nie w ustawieniach resolvera aplikacji.
Trzy pytania, zanim edytujesz plik
Odpowiedz na nie po kolei, bo każde zawęża topologię. Na co baza musi odpowiadać: na nazwę hosta, której używają inne kontenery, czy tylko na aplikację na loopbacku? Czy aplikacja ma publikować port do hosta, i która usługa miałaby go posiadać? Czy baza ma być osiągalna z hosta lub z innej maszyny, czy tylko od wewnątrz tunelu?
Jeśli baza potrzebuje własnej nazwy, a aplikacja nic nie publikuje, trzymaj je na osobnych przyłączeniach. Jeśli aplikacja musi publikować port i wszystko idzie przez tunel, umieść bazę w przestrzeni nazw VPN i użyj loopbacku. Mieszanie obu daje stos, który uruchamia się czysto i zawodzi przy połączeniu.
Zostaw bazę tam, gdzie jest
Mniejsza zmiana przyłącza właściciela przestrzeni nazw do sieci, która już zawiera bazę. Aplikacja dziedziczy to przyłączenie, bo dzieli stos vpn, a db rozwiązuje się dokładnie jak wcześniej.
services:
vpn:
networks:
- backend
app:
network_mode: service:vpn
db:
networks:
- backend
networks:
backend:Nie dodawaj networks także do aplikacji. Compose odrzuca tę właściwość razem z network_mode w tej samej usłudze, a błąd wskazuje plik, a nie parę. Jeśli klient VPN filtruje cel backend wewnątrz swojej przestrzeni nazw, dostosuj także jego obsługiwaną politykę sieci lokalnej; współdzielone przyłączenie daje ścieżkę, ale nie unieważnia tego filtra.
Przenieś bazę do przestrzeni nazw
Większa zmiana umieszcza bazę w tej samej przestrzeni nazw i kieruje aplikację na 127.0.0.1 z prawdziwym portem. Dwa procesy nie mogą oba związać tego samego adresu i portu tylko dlatego, że wystartowały w różnych kontenerach, więc baza, która nasłuchuje także na adresie wildcard, zderzy się ze wszystkim innym, co to robi. Sprawdź nasłuch przed przeniesieniem.
Opublikowane porty należą do usługi, która posiada przestrzeń nazw. Dodanie ports do aplikacji jest odrzucane razem z network_mode, a wymyślanie osobnego adresu aplikacji opisuje interfejs, który nie istnieje.
Gotowość, blokowanie i resolver
depends_on porządkuje uruchamianie kontenerów; to nie jest dowód, że tunel działa, i nie zatrzymuje ruchu, gdy tunel padnie. Traktuj osiągalność, gotowość tunelu i blokowanie awarii jako trzy osobne wymagania. Stos, który spełnia tylko pierwsze, przechodzi ręczny test w dobry dzień i przecieka w zły. Zapisz trzy odpowiedzi obok pliku compose, tam, gdzie spojrzy następna osoba.
Współdzielenie przestrzeni nazw oznacza też, że aplikacja dziedziczy resolver kontenera VPN, co pomaga, gdy tunel wymusza serwery DNS, a myli, gdy tego nie robi. Sprawdź, co przestrzeń nazw faktycznie zawiera, zamiast zakładać, że obowiązuje resolver hosta. Dokumentacja usług Compose opisuje network_mode, ports i zachowanie zależności w jednym miejscu, w tym dlaczego usługa network_mode nie ma własnego adresu.