Κοντέινερ με δύο δίκτυα επιλέγει τη λάθος πύλη
Δύο συνδέσεις, μία προεπιλεγμένη διαδρομή και το λάθος δίκτυο κερδίζει πάντα. Καρφώστε την έξοδο με το Compose gw_priority και επιβεβαιώστε το μέσα από το κοντέινερ.
Το κοντέινερ σας εξακολουθεί να απαντά στη γέφυρα ελέγχου του, όμως κάθε εξερχόμενο πακέτο φεύγει από το macvlan του γραφείου. Τίποτα δεν απέτυχε. Δύο συνδέσεις παρέχουν η καθεμία μια πύλη και η μοναδική προεπιλεγμένη διαδρομή πήγε στο δίκτυο που δεν θέλατε, οπότε η υπηρεσία συνεχίζει να λειτουργεί ενώ η κίνησή της παίρνει μεγαλύτερη διαδρομή. Όταν κάποιος το προσέξει, το στοιχείο είναι ένας πίνακας δρομολόγησης και όχι ένα μήνυμα σφάλματος.
Η συνηθισμένη εξήγηση είναι ότι το Docker διάλεξε το δίκτυο κατά λάθος. Στην πράξη η παλιά απόφαση ακολουθούσε την αλφαβητική σειρά των ονομάτων των συνδεδεμένων δικτύων, κάτι που μετέτρεπε τη δρομολόγηση σε παρενέργεια μιας ετικέτας. Το gw_priority το αντικαθιστά με έναν αριθμό που επιλέγετε σκόπιμα, και η υιοθέτησή του παίρνει περίπου ένα λεπτό μόλις γραφτεί η διάταξη.
Γιατί η προεπιλεγμένη διαδρομή προσγειώνεται στο λάθος δίκτυο
Κάθε δίκτυο στο οποίο μπαίνει μια υπηρεσία μπορεί να προσφέρει τη δική του πύλη, και το κοντέινερ καταλήγει παρ' όλα αυτά με ακριβώς μία προεπιλεγμένη διαδρομή. Πριν από το Compose 2.33.1 η ισοπαλία λυνόταν με ταξινόμηση των ονομάτων των δικτύων, οπότε μια ετικέτα όπως control που έρχεται πριν από το office καθόριζε πού πάει η κίνηση. Τίποτα μέσα στο κοντέινερ δεν καταγράφει ότι η απόφαση ήταν αυθαίρετη, γι' αυτό περνά την αναθεώρηση κώδικα και εμφανίζεται αργότερα ως παράξενη διαδρομή. Το να βάλεις μια πολιτική στο αρχείο compose είναι ο μόνος τρόπος να γίνει η επιλογή ελεγχόμενη.
Δύο πράγματα αλλάζουν πραγματικά ποιο δίκτυο κερδίζει: οι τιμές gw_priority που ορίζετε και ποια δίκτυα είναι συνδεδεμένα. Προσθέστε ένα τρίτο δίκτυο και το σύνολο των υποψηφίων μεγαλώνει· αφαιρέστε το macvlan και δεν μένει τίποτα να ανταγωνιστεί τη γέφυρα. Καμία από τις δύο κινήσεις δεν εμφανίζεται στα αρχεία καταγραφής της εφαρμογής, γιατί μια λάθος προεπιλεγμένη διαδρομή σπάνια σπάει τη σύνδεση εντελώς. Απλώς κάνει τις απαντήσεις να φτάνουν από μια διεύθυνση που η άλλη πλευρά ίσως δεν περιμένει.
Καρφώστε την πύλη με το gw_priority
Το Compose εκθέτει το gw_priority σε κάθε σύνδεση υπηρεσίας-δικτύου από την έκδοση 2.33.1 και κερδίζει ο μεγαλύτερος αριθμός. Δεν υπάρχει κλειδί πύλης ανά υπηρεσία, οπότε η τιμή ανήκει στο μπλοκ networks της υπηρεσίας. Το παρακάτω παράδειγμα δίνει την προεπιλεγμένη διαδρομή στο control αφήνοντας το office προσβάσιμο για το άμεσα συνδεδεμένο LAN του.
services:
vpn:
networks:
control:
gw_priority: 1
office:
gw_priority: 0
networks:
control:
driver: bridge
ipam:
config:
- subnet: 172.30.50.0/24
office:
driver: macvlan
driver_opts:
parent: eno1.120
macvlan_mode: bridge
ipam:
config:
- subnet: 192.168.120.0/24
ip_range: 192.168.120.192/27
gateway: 192.168.120.1
Διαβάστε το μπλοκ ως δύο ξεχωριστά χειριστήρια: το gw_priority αποφασίζει την προεπιλεγμένη διαδρομή και η ενότητα ipam αποφασίζει τη διευθυνσιοδότηση. Αν αλλάξετε μόνο το subnet, η επιλογή εξόδου μένει ανέγγιχτη, και αυτός είναι ο συνηθέστερος τρόπος να εφαρμοστεί αυτή η διόρθωση μισή. Κρατήστε τις προτεραιότητες δίπλα στο δίκτυο που κυβερνούν, ώστε ο επόμενος αναγνώστης να μη χρειάζεται να κυνηγήσει την απόφαση.
Μη μπερδεύετε το gw_priority με την απλή ιδιότητα priority δίπλα του. Εκείνη ταξινομεί τη δημιουργία συνδέσεων και δεν λέει τίποτα για δρομολόγηση, άρα δεν μπορεί να επιλέξει προεπιλεγμένη πύλη και δεν διορθώνει ονόματα διασυνδέσεων. Αν κάποιος προτείνει να ανεβάσετε το priority για να κατευθύνετε την κίνηση, η πρόταση είναι λάθος ακόμη και όταν η σειρά που προκύπτει τυχαίνει να φαίνεται σωστή.
Επαληθεύστε ποιο δίκτυο μεταφέρει πραγματικά την προεπιλεγμένη διαδρομή
Ελέγξτε μέσα στο κοντέινερ που τρέχει, γιατί ο πίνακας δρομολόγησης του κεντρικού υπολογιστή περιγράφει τον υπολογιστή και όχι τον χώρο ονομάτων που χρησιμοποιεί η υπηρεσία. Τρέξτε πρώτα τον έλεγχο διαμόρφωσης ώστε ένα τυπογραφικό λάθος να αποτύχει πριν από επανεκκίνηση, και μετά διαβάστε τη διαδρομή που εγκατέστησε πραγματικά το κοντέινερ.
docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route
Ένα σωστό αποτέλεσμα ονομάζει τη συσκευή γέφυρας και το 172.30.50.1· ένα λάθος ονομάζει το 192.168.120.1 και τη συσκευή macvlan. Αν η εικόνα δεν περιέχει πακέτο iproute2, το αρχείο /proc αναφέρει πάλι την προεπιλεγμένη διαδρομή, με προορισμό 00000000 και τα byte της πύλης ανεστραμμένα. Συγκρίνετε τη στήλη διασύνδεσης με το docker inspect όταν τα ονόματα των συσκευών δεν είναι σαφή.
Το macvlan είναι φυσική θύρα, όχι κλώνος γέφυρας
Το macvlan δίνει στο κοντέινερ μια δεύτερη ταυτότητα στο καλώδιο, και ακριβώς αυτό κάνει να δουλεύει η πρόσβαση σε τοπικές συσκευές. Σημαίνει επίσης ότι η θύρα του μεταγωγέα και το hypervisor πρέπει να δεχτούν μια επιπλέον διεύθυνση MAC, και πολλά δίκτυα cloud το αρνούνται σιωπηλά. Δοκιμάστε ένα κοντέινερ πριν σχεδιάσετε στόλο, γιατί μια απορριφθείσα MAC συνήθως εμφανίζεται ως ζεύξη που είναι πάνω και δεν περνά τίποτα.
Η ρύθμιση macvlan_mode: bridge είναι λειτουργία του οδηγού macvlan, όχι η γέφυρα λογισμικού του Docker, και το passthru είναι ξεχωριστή εξειδικευμένη λειτουργία και όχι προεπιλογή. Το Linux επίσης εμποδίζει ένα κοντέινερ macvlan να φτάσει τον δικό του κεντρικό υπολογιστή μέσω του ίδιου γονέα, και γι' αυτό κρατάμε τη γέφυρα ελέγχου αντί να περιμένουμε μία σύνδεση να κάνει και τις δύο δουλειές.
Ονομάστε τον γονέα του VLAN πριν τον δει το Compose
Το Docker αντιμετωπίζει έναν γονέα με τελεία όπως το eno1.120 ως υπο-διασύνδεση 802.1Q και δημιουργεί το ίδιο τη συσκευή VLAN. Αυτή η ευκολία έχει όρια: το παράγωγο όνομα εξαρτάται από το όνομα της φυσικής διασύνδεσης, και τα μακριά ονόματα μπορούν να σπρώξουν το αποτέλεσμα πέρα από ό,τι περιμένουν τα γύρω εργαλεία. Το να δημιουργήσετε μια ονομασμένη διασύνδεση VLAN στη διαμόρφωση δικτύου του κεντρικού υπολογιστή και να δείξετε το parent εκεί κρατά και τα δύο άκρα προβλέψιμα.
Θυμηθείτε ότι το κλειδί κάτω από το networks είναι όνομα Compose, όχι συσκευή Linux. Η αναζήτηση στον υπολογιστή για διασύνδεση με όνομα office θα αποτύχει, γιατί ο πυρήνας βλέπει μόνο τη γονική διασύνδεση και το ζεύγος veth πίσω από το κοντέινερ.
Κάντε χώρο για το VPN από πάνω
Ένας πελάτης VPN συνδέεται αφού υπάρχουν αυτά τα δίκτυα, οπότε μπορεί να προσθέσει πιο συγκεκριμένες διαδρομές, κανόνες πολιτικής και φίλτρα ανεξάρτητα από το gw_priority. Σχεδιάστε τα απομακρυσμένα προθέματα απέναντι και στα δύο τοπικά subnet, μαζί με τις απαντήσεις που χρειάζεται η διαδρομή ελέγχου. Όταν ένα απομακρυσμένο πρόθεμα επικαλύπτει το LAN του γραφείου, διορθώστε το σχέδιο διευθύνσεων αντί να ξεριζώσετε ολόκληρο ιδιωτικό εύρος από το τούνελ.
Ελέγξτε ξανά διευθύνσεις, διαδρομές και τη διαδρομή της υπηρεσίας αφού ξεκινήσει το VPN και άλλη μία φορά αφού επανασυνδεθεί, γιατί στην επανασύνδεση χάνεται μια διαδρομή που προστέθηκε με το χέρι. Γράψτε τον αναμενόμενο πίνακα πριν από την πρώτη δοκιμή ώστε η σύγκριση μετά να είναι diff και όχι άσκηση μνήμης. Κρατήστε τη μόνιμη ιδιοκτησία του δικτύου στο Compose και αφήστε τη διαμόρφωση VPN να κατέχει μόνο τη δική της πολιτική.