Docker: δρομολογήστε ένα κοντέινερ μέσω VPN και κρατήστε ένα άλλο απευθείας
Δώστε στο τούνελ το δικό του κοντέινερ, αφήστε μόνο τις υπηρεσίες που το χρειάζονται να μοιράζονται αυτόν τον χώρο ονομάτων και μετά υπολογίστε τι ακολουθεί τον ιδιοκτήτη: θύρες, localhost, DNS.
Ένας ξενιστής, δύο φόρτοι εργασίας και μια απαίτηση που τους χωρίζει: ένας πελάτης λήψης που πρέπει να βγαίνει από εμπορικό VPN και ένα περιβάλλον διαχείρισης που πρέπει να συνεχίσει να χρησιμοποιεί τη σύνδεση του ξενιστή. Η εγκατάσταση του πελάτη VPN στον ξενιστή αποτυγχάνει αμέσως την απαίτηση, γιατί τότε και οι δύο φόρτοι μοιράζονται μία έξοδο. Το μοτίβο που πραγματικά λειτουργεί είναι να μεταφέρετε το τούνελ στο δικό του κοντέινερ και να αφήσετε μόνο τους φόρτους που το χρειάζονται να ενταχθούν στον χώρο ονομάτων δικτύου αυτού του κοντέινερ. Όλα τα άλλα κρατούν τη συνηθισμένη διαδρομή του Docker, και οι λεπτομέρειες που ακολουθούν είναι συνέπειες του ποιος κατέχει τον χώρο ονομάτων.
Γιατί ένας κοινός χώρος ονομάτων αλλάζει τους κανόνες
Ένα κοντέινερ που εντάσσεται στον χώρο ονομάτων ενός άλλου δεν αποκτά δική του στοίβα δικτύου. Βλέπει τις ίδιες διεπαφές, τον ίδιο πίνακα δρομολόγησης και το ίδιο loopback με το κοντέινερ στο οποίο εντάχθηκε, και γι' αυτό ακριβώς το μοτίβο είναι χρήσιμο: ο φόρτος επιλύει και συνδέεται κανονικά, και το τούνελ από κάτω συλλαμβάνει την κίνηση χωρίς να το ξέρει η εφαρμογή. Το κόστος είναι ότι κάθε δικτυακή ρύθμιση έχει πλέον έναν ιδιοκτήτη, και το κοντέινερ που εντάσσεται δεν είναι αυτός.
Ο κανόνας ιδιοκτησίας απαντά στις περισσότερες ερωτήσεις ρύθμισης πριν καν τεθούν. Αν μια ρύθμιση ζει στη στοίβα δικτύου, ανήκει στο πλευρικό κοντέινερ. Αν περιγράφει τη διεργασία, μένει με τον φόρτο.
Το loopback είναι το μέρος που εκπλήσσει τον κόσμο. Μέσα στο κοντέινερ που εντάσσεται, το localhost επιλύεται στο loopback του πλευρικού κοντέινερ, όχι σε ένα δικό του ιδιωτικό, οπότε μια υπηρεσία που δεσμεύεται στη 127.0.0.1 περιμένοντας απομόνωση μοιράζεται τώρα αυτή τη διεύθυνση με το κοντέινερ του τούνελ.
Δημοσιεύστε θύρες στο κοντέινερ που κατέχει τον χώρο ονομάτων
Η αντιστοίχιση θυρών ανήκει στον ιδιοκτήτη του χώρου ονομάτων ακόμη και όταν η διεργασία ακρόασης τρέχει στο άλλο κοντέινερ. Δηλώστε την αντιστοίχιση στο πλευρικό κοντέινερ και αφήστε τον φόρτο να κρατήσει ανέπαφη τη δική του ρύθμιση διεργασίας. Μια αντιστοίχιση στην υπηρεσία που εντάσσεται δεν μπορεί να τεθεί σε ισχύ, είτε ο μηχανισμός την απορρίπτει είτε την αγνοεί σιωπηλά ανάλογα με το πώς ξεκινά το κοντέινερ, και γι' αυτό μια διεπαφή που ήταν προσβάσιμη πριν από λίγο εξαφανίζεται μόλις εφαρμοστεί το μοτίβο.
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"]Διαβάστε αυτό το μπλοκ ως τρεις αποφάσεις και όχι ως τρεις υπηρεσίες. Το πλευρικό κοντέινερ κατέχει το τούνελ και τη δημοσιευμένη θύρα· ο πελάτης που εντάσσεται δεν δηλώνει καθόλου δίκτυο· ο άμεσος πελάτης κρατά δική του αντιστοίχιση στο προεπιλεγμένο δίκτυο. Η δυνατότητα NET_ADMIN είναι αυτό που επιτρέπει στο πλευρικό κοντέινερ να δημιουργεί διεπαφές και να αλλάζει διαδρομές, και είναι ο λόγος που αυτό το κοντέινερ χρειάζεται περισσότερα προνόμια από τους φόρτους που εξυπηρετεί.
Η υπηρεσία που μένει άμεση κρατά το δικό της δίκτυο
Ο φόρτος που δεν πρέπει να περάσει από το τούνελ κρατά την προεπιλεγμένη γέφυρα ή δικό του δίκτυο ορισμένο από τον χρήστη, με δική του δημοσιευμένη θύρα και δική του έξοδο. Είναι δελεαστικό να το συνδέσετε στο δίκτυο του πλευρικού κοντέινερ ώστε τα δύο κοντέινερ να μιλούν με όνομα, αλλά αυτό το ένα βήμα μεταφέρει σιωπηλά την κίνησή του στο τούνελ. Αν πρέπει να φτάσουν το ένα το άλλο, φτιάξτε ξεχωριστό δίκτυο ορισμένο από τον χρήστη, συνδέστε και τα δύο σε αυτό και αφήστε το πλευρικό κοντέινερ ως τη μόνη διαδρομή προς τα έξω.
Κρατήστε τις δύο ερωτήσεις χωριστά: ποια κοντέινερ μπορούν να φτάσουν το ένα το άλλο και ποιο βγαίνει από πού. Το να τις συγχωνεύσετε είναι ο πιο συνηθισμένος τρόπος με τον οποίο αυτό το σχέδιο γίνεται ξανά VPN για ολόκληρο τον ξενιστή.
Ένας πίνακας αστοχιών για την πρώτη ώρα
Οι περισσότερες πρώτες απόπειρες αποτυγχάνουν με έναν από τέσσερις τρόπους, και ο καθένας έχει διαφορετική αιτία. Ελέγξτε τους με αυτή τη σειρά, γιατί οι δύο πρώτοι εξηγούν σχεδόν κάθε αναφορά.
| Symptom | Likely cause |
|---|---|
| Web UI unreachable after the change | Port mapping declared on the joining container instead of the sidecar |
| Both containers show the provider's exit address | The direct service was attached to the sidecar network |
| Internal names stop resolving | Resolver settings live on the host, not in the shared namespace |
| Health check fails but the app works | The check probes localhost, which now means the sidecar |
Η τέταρτη γραμμή είναι αυτή που οι άνθρωποι διαγιγνώσκουν λανθασμένα ως σφάλμα εφαρμογής. Ένας έλεγχος γραμμένος απέναντι στο δικό του loopback του φόρτου τώρα δοκιμάζει το κοντέινερ του τούνελ, οπότε είτε αποτυγχάνει είτε αναφέρει εντελώς λάθος υπηρεσία.
Όταν ένα μόνο όνομα ξενιστή χρειάζεται το τούνελ
Μερικές φορές ένα πλήρες τούνελ είναι υπερβολικό: ένα εσωτερικό όνομα πρέπει να περάσει από εταιρικό VPN ενώ μια τοπική υποδοχή ή σύνδεση οθόνης συνεχίζει να λειτουργεί. Ένα πλήρες τούνελ μέσα στο κοντέινερ σπάει αυτή τη διαδρομή και οτιδήποτε απευθύνεται στον ξενιστή, οπότε δρομολογήστε μόνο το πρόθεμα που το χρειάζεται. Ένα περίβλημα διαχωρισμένης δρομολόγησης γύρω από τον πελάτη το κάνει αυτό, στέλνοντας το ονομασμένο όνομα ξενιστή μέσα από το τούνελ και αφήνοντας την προηγούμενη διαδρομή ανέπαφη για όλα τα άλλα.
Επιλέξτε το όταν χρειάζεται να φτάσετε μόνο μία υπηρεσία και δεν προσπαθείτε να μετακινήσετε όλη την κίνηση του κοντέινερ. Είναι διαφορετικό εργαλείο από το πλευρικό κοντέινερ και απαντά σε διαφορετική ερώτηση.
Επαληθεύστε και μετά κάντε το να αντέχει σε επανεκκίνηση
Ρωτήστε κάθε κοντέινερ από ποια διεύθυνση φαίνεται να έρχεται. Το ένα μέσα στο τούνελ θα πρέπει να εκτυπώνει τη διεύθυνση του παρόχου και το άμεσο την έξοδο του ξενιστή. Πανομοιότυπες απαντήσεις σημαίνουν ότι η άμεση υπηρεσία κληρονόμησε λάθος χώρο ονομάτων ή ότι ένα VPN σε επίπεδο ξενιστή εξακολουθεί να συλλαμβάνει τα πάντα, και αυτές οι δύο διορθώσεις είναι διαφορετικές. Τρέξτε τον έλεγχο ξανά μετά από κάθε αλλαγή στο compose, γιατί ένα αντιγραμμένο μπλοκ υπηρεσίας αρκεί για να επαναφέρει το πρόβλημα.
Τρία πράγματα τείνουν να χαλάνε αργότερα. Το DNS ακολουθεί τον ιδιοκτήτη του χώρου ονομάτων, οπότε οι ρυθμίσεις του μεταφραστή και του τομέα αναζήτησης ανήκουν στο πλευρικό κοντέινερ και όχι στον ξενιστή. Ένα VPN με προώθηση θυρών αλλάζει τη θύρα ακρόασής του κατά την επανασύνδεση, οπότε η προωθημένη θύρα του παρόχου και η θύρα ακρόασης στην πλευρά του κοντέινερ πρέπει να ξαναγραφτούν στη ρύθμιση του πελάτη ή στην αντιστοίχιση θυρών, συνήθως από έναν μικρό ενημερωτή που διαβάζει το API του παρόχου. Και κάθε έλεγχος γραμμένος απέναντι στο localhost τώρα ρωτά το κοντέινερ του τούνελ και όχι τον φόρτο.
Γράψτε το μοτίβο, συμπεριλαμβάνοντας ποιο κοντέινερ κατέχει τον χώρο ονομάτων και ποιες θύρες του ανήκουν. Ο επόμενος άνθρωπος θα προσθέσει μια υπηρεσία, θα αντιγράψει το λάθος μπλοκ και θα αναπαραγάγει την πρώτη αστοχία αυτού του άρθρου.