Un host, două încărcături de lucru și o cerință care le separă: un client de descărcare care trebuie să iasă printr-un VPN comercial și o interfață de administrare care trebuie să folosească în continuare conexiunea hostului. Instalarea clientului VPN pe host încalcă imediat cerința, pentru că atunci ambele încărcături partajează o singură ieșire. Modelul care funcționează cu adevărat este să mutați tunelul în propriul container și să lăsați doar încărcăturile care au nevoie de el să se alăture spațiului de nume de rețea al acelui container. Tot restul păstrează calea obișnuită Docker, iar detaliile care urmează sunt consecințe ale cine deține spațiul de nume.

De ce un spațiu de nume partajat schimbă regulile

Un container care se alătură spațiului de nume al altuia nu primește propria stivă de rețea. El vede aceleași interfețe, același tabel de rutare și același loopback ca containerul căruia i s-a alăturat, și exact de aceea modelul este util: încărcătura rezolvă și se conectează normal, iar tunelul de dedesubt captează traficul fără ca aplicația să știe. Costul este că fiecare setare de rețea are acum un singur proprietar, iar containerul care se alătură nu este acela.

Această regulă de proprietate răspunde la majoritatea întrebărilor de configurare înainte de a fi puse. Dacă o setare trăiește în stiva de rețea, ea aparține containerului lateral. Dacă descrie procesul, rămâne la încărcătură.

Loopback este partea care surprinde oamenii. În interiorul containerului care se alătură, localhost se rezolvă la loopback-ul containerului lateral, nu la unul privat propriu, așa că un serviciu care se leagă la 127.0.0.1 așteptând izolare partajează acum acea adresă cu containerul tunelului.

Publicați porturile pe containerul care deține spațiul de nume

Maparea porturilor aparține proprietarului spațiului de nume, chiar și atunci când procesul care ascultă rulează în celălalt container. Declarați maparea pe containerul lateral și lăsați încărcătura să își păstreze configurația de proces neatinsă. O mapare pe serviciul care se alătură nu poate intra în vigoare, fie că motorul o respinge, fie că o ignoră în tăcere în funcție de modul în care este pornit containerul, și de aceea o interfață care era accesibilă acum o clipă dispare de îndată ce modelul este aplicat.

services:
  gluetun:
    image: qmcgaw/gluetun
    cap_add: [NET_ADMIN]
    ports: ["8080:8080"]
  client-vpn:
    image: example/client
    network_mode: "service:gluetun"
  client-direct:
    image: example/client
    ports: ["8081:8080"]

Citiți acel bloc ca trei decizii, nu ca trei servicii. Containerul lateral deține tunelul și portul publicat; clientul care se alătură nu declară nici o rețea; clientul direct își păstrează propria mapare pe rețeaua implicită. Capacitatea NET_ADMIN este ceea ce îi permite containerului lateral să creeze interfețe și să modifice rute, și este motivul pentru care acest container are nevoie de mai multe privilegii decât încărcăturile pe care le servește.

Serviciul care rămâne direct își păstrează propria rețea

Încărcătura care nu trebuie să treacă prin tunel păstrează puntea implicită sau o rețea definită de utilizator proprie, cu propriul port publicat și propria ieșire. Este tentant să o conectați la rețeaua containerului lateral ca cele două containere să poată vorbi pe nume, dar acel singur pas mută în tăcere traficul ei în tunel. Dacă trebuie să se atingă reciproc, construiți o rețea separată definită de utilizator, conectați ambele la ea și lăsați containerul lateral singura cale spre exterior.

Țineți cele două întrebări separate: ce containere se pot atinge și care iese pe unde. Fuzionarea lor este cea mai obișnuită cale prin care acest design redevină un VPN pentru întregul host.

O matrice de defecțiuni pentru prima oră

Majoritatea primelor încercări eșuează într-unul din patru moduri, iar fiecare are o cauză diferită. Verificați-le în această ordine, pentru că primele două explică aproape fiecare raport.

SymptomLikely cause
Web UI unreachable after the changePort mapping declared on the joining container instead of the sidecar
Both containers show the provider's exit addressThe direct service was attached to the sidecar network
Internal names stop resolvingResolver settings live on the host, not in the shared namespace
Health check fails but the app worksThe check probes localhost, which now means the sidecar

Al patrulea rând este cel pe care oamenii îl diagnostichează greșit ca o eroare a aplicației. O sondă scrisă împotriva loopback-ului propriu al încărcăturii testează acum containerul tunelului, așa că fie eșuează, fie raportează un serviciu complet greșit.

Când un singur nume de host are nevoie de tunel

Uneori un tunel complet este prea mult: un nume intern trebuie să treacă printr-un VPN corporativ în timp ce un socket local sau o conexiune de afișare continuă să funcționeze. Un tunel complet în container rupe acea cale și tot ce este adresat hostului, așa că rutați doar prefixul care are nevoie. Un înveliș de rutare divizată în jurul clientului face asta, trimițând hostul numit prin tunel și lăsând ruta anterioară neatinsă pentru restul.

Alegeți asta când trebuie să atingeți un singur serviciu și nu încercați să mutați tot traficul containerului. Este un instrument diferit de containerul lateral și răspunde la o altă întrebare.

Verificați, apoi faceți-l să supraviețuiască unei reporniri

Întrebați fiecare container din ce adresă pare să vină. Cel din tunel ar trebui să afișeze adresa furnizorului, iar cel direct ieșirea hostului. Răspunsurile identice înseamnă că serviciul direct a moștenit spațiul de nume greșit sau că un VPN la nivel de host capturează încă tot, iar cele două corecții sunt diferite. Rulați din nou verificarea după fiecare modificare a compose, pentru că un singur bloc de serviciu copiat este suficient pentru a readuce problema.

Trei lucruri tind să se strice mai târziu. DNS urmează proprietarul spațiului de nume, așa că setările de resolver și de domeniu de căutare aparțin containerului lateral, nu hostului. Un VPN cu redirecționare de porturi își schimbă portul de ascultare la reconectare, așa că portul redirecționat al furnizorului și portul de ascultare din partea containerului trebuie rescrise în configurația clientului sau în maparea porturilor, de obicei printr-un mic actualizator care citește API-ul furnizorului. Și orice sondă scrisă împotriva localhost întreabă acum containerul tunelului, nu încărcătura.

Scrieți modelul, inclusiv care container deține spațiul de nume și ce porturi îi aparțin. Următoarea persoană va adăuga un serviciu, va copia blocul greșit și va reproduce prima defecțiune din acest articol.

Articole similare