Γιατί τα κοντέινερ του Docker αγνοούν τον resolver DNS του VPN
Ένα κοντέινερ αντιγράφει τον resolver του κεντρικού υπολογιστή όταν ξεκινά, οπότε ένα VPN που ξαναγράφει το DNS αργότερα μένει αόρατο μέσα του. Περάστε τον resolver ρητά.
Το VPN είναι ενεργό, το πρόγραμμα περιήγησης φτάνει σε εσωτερικούς ιστότοπους, και το κοντέινερ εξακολουθεί να μην μπορεί να επιλύσει τα ίδια ονόματα. Μια εγκατάσταση πακέτου πεθαίνει με σφάλμα επίλυσης ονόματος όπως EAI_AGAIN, ή μια εφαρμογή δεν βρίσκει έναν κεντρικό υπολογιστή βάσης δεδομένων που το μηχάνημα φιλοξενίας επιλύει χωρίς κανένα παράπονο. Το κοντέινερ δεν χρησιμοποιεί τον resolver που εγκατέστησε το VPN. Το Docker αντέγραψε τη διαμόρφωση resolver του κεντρικού υπολογιστή όταν δημιουργήθηκε το κοντέινερ, και τίποτα δεν την αντέγραψε ξανά μετά.
Δύο όψεις του resolver σε ένα μηχάνημα
Στο Linux, το Docker δίνει σε κάθε κοντέινερ ένα αντίγραφο της διαμόρφωσης resolver του κεντρικού υπολογιστή τη στιγμή της δημιουργίας, φιλτράρει τις διευθύνσεις loopback και εκτελεί έναν ενσωματωμένο διακομιστή DNS στη 127.0.0.11 που προωθεί τα ερωτήματα προς τα έξω. Ένας πελάτης VPN που ξαναγράφει το /etc/resolv.conf αφού ξεκινήσει το κοντέινερ δεν αλλάζει τίποτα μέσα του. Η επανεκκίνηση του κοντέινερ βοηθά μόνο αν ο resolver του κεντρικού υπολογιστή είναι τυχαία σωστός εκείνη τη στιγμή.
Το Docker Desktop σε macOS ή Windows προσθέτει ένα επίπεδο, επειδή ο δαίμονας ζει σε εικονική μηχανή. Ο resolver VPN του κεντρικού υπολογιστή μπορεί να μην είναι ποτέ ορατός σε αυτή τη VM, οπότε η επανεκκίνηση δεν αλλάζει απολύτως τίποτα. Συγκρίνετε τις δύο όψεις πριν επιλέξετε λύση: docker exec mycontainer cat /etc/resolv.conf δίπλα στη λίστα resolver του κεντρικού υπολογιστή.
Ένα κοντέινερ που απαριθμεί δημόσιο resolver ενώ ο κεντρικός υπολογιστής απαριθμεί εσωτερικό θα επιλύει δημόσια ονόματα και θα αποτυγχάνει στα εσωτερικά. Αυτή η διάσπαση είναι η υπογραφή αυτού του προβλήματος.
Επιλογή A: πέρασμα του resolver της σήραγγας ανά κοντέινερ
Το Docker δέχεται ρυθμίσεις DNS ανά κοντέινερ, και αυτή είναι η μικρότερη αλλαγή που λειτουργεί. Διαβάστε πρώτα τις διευθύνσεις resolver του VPN: scutil --dns σε macOS, resolvectl status ή την έξοδο κατάστασης του ίδιου του πελάτη σε Linux. Στη συνέχεια ξεκινήστε το κοντέινερ με αυτές, για παράδειγμα docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. Στο Compose η ίδια ρύθμιση είναι μια λίστα κάτω από την υπηρεσία, όπου ζει στον έλεγχο εκδόσεων αντί στο ιστορικό κελύφους κάποιου.
Ένας πίνακας dns στο /etc/docker/daemon.json ισχύει για κάθε νέο κοντέινερ, κάτι που ακούγεται τακτικότερο και δεν είναι. Ισχύει επίσης όταν η σήραγγα είναι ανενεργή, και τότε ένας resolver προσβάσιμος μόνο μέσω του VPN χαλάει τα συνηθισμένα τραβήγματα εικόνων. Οι ρυθμίσεις ανά κοντέινερ αιτιολογούνται και αναιρούνται ευκολότερα.
Επιλογή B: το κοντέινερ να μοιράζεται το δίκτυο του κεντρικού υπολογιστή
Η δικτύωση κεντρικού υπολογιστή παρακάμπτει εντελώς το αντίγραφο, επειδή το κοντέινερ χρησιμοποιεί τον resolver του κεντρικού υπολογιστή και τη σήραγγά του. Αφαιρεί επίσης την απομόνωση δικτύου που πιθανότατα θέλατε, και δεν συμπεριφέρεται το ίδιο κάτω από το Docker Desktop. Στο Linux είναι η πραγματιστική επιλογή για ένα εργαλείο μιας χρήσης που πρέπει να επιλύει εσωτερικά ονόματα.
Για τις κατασκευές δεν ισχύει καμία από τις δύο επιλογές, αφού τα βήματα κατασκευής δεν κληρονομούν σημαίες χρόνου εκτέλεσης. Κατασκευάστε με δικτύωση κεντρικού υπολογιστή όπου το επιτρέπει η πλατφόρμα, ή κρατήστε την εγκατάσταση εξαρτήσεων σε ένα στάδιο που δεν χρειάζεται τη σήραγγα.
Τι δεν διορθώνει καμία από τις δύο επιλογές
Μια διεύθυνση DNS είναι άχρηστη αν το κοντέινερ δεν έχει διαδρομή προς αυτήν. Ο resolver του VPN κάθεται συνήθως μέσα στον χώρο διευθύνσεων της σήραγγας, οπότε το κοντέινερ χρειάζεται διαδρομή προς αυτό το πρόθεμα. Η προεπιλεγμένη γέφυρα του Docker δρομολογεί συνήθως προς τα έξω μέσω του κεντρικού υπολογιστή, και αυτό αρκεί όταν ο κεντρικός υπολογιστής έχει τη διαδρομή της σήραγγας και η προώθηση είναι ενεργοποιημένη. Προσαρμοσμένα δίκτυα γέφυρας με δικές τους δεξαμενές διευθύνσεων μπορεί να συγκρουστούν με το υποδίκτυο του VPN, και τότε τα ερωτήματα πηγαίνουν εντελώς αλλού.
Ελέγξτε το υποδίκτυο του δικτύου Docker απέναντι στο υποδίκτυο του VPN πριν αποσφαλματώσετε τον ίδιο τον resolver. Η επικάλυψη παράγει μια αποτυχία που μοιάζει ακριβώς με χαλασμένο διακομιστή DNS.
Επαλήθευση μέσα στο κοντέινερ
Δοκιμάστε με getent hosts db.internal μέσα στο κοντέινερ αντί με πρόγραμμα περιήγησης ή περιβάλλον εκτέλεσης γλώσσας, επειδή εκείνα εφαρμόζουν τη δική τους πολιτική DNS και τη δική τους προσωρινή μνήμη. Αν το getent επιλύσει το όνομα και η εφαρμογή εξακολουθεί να αποτυγχάνει, ο resolver είναι τώρα σωστός και το υπόλοιπο πρόβλημα είναι σε επίπεδο εφαρμογής. Αν δεν το επιλύσει, το βήμα DNS δεν έχει ολοκληρωθεί.
Δημιουργήστε ξανά το κοντέινερ αφού αλλάξετε τις ρυθμίσεις DNS του. Η επεξεργασία του /etc/resolv.conf μέσα σε ένα κοντέινερ που εκτελείται εξαφανίζεται μαζί του και κρύβει το πρόβλημα διαμόρφωσης για ακριβώς όσο χρόνο χρειάζεται κάποιος για να το επανεκκινήσει.