Το Dev Container δεν φτάνει σε host μόνο μέσω VPN: πού να κοιτάξετε
Το πρόγραμμα περιήγησης και το container έχουν διαφορετικά περιβάλλοντα resolver, proxy και διαδρομών. Βρείτε ποιο χρησιμοποιεί η διεργασία που αποτυγχάνει πριν αλλάξετε οποιαδήποτε ρύθμιση VPN.
Το ιδιωτικό API ανοίγει στο πρόγραμμα περιήγησης του υπολογιστή σας και αποτυγχάνει μέσα στο container ανάπτυξης. Αυτό δεν είναι αντίφαση και σπάνια φταίει το ίδιο το VPN. Το αίτημα του προγράμματος περιήγησης και το αίτημα που αποτυγχάνει τα έκαναν διαφορετικές διεργασίες, με διαφορετικούς resolvers, proxies και διαδρομές, και συχνά από εντελώς διαφορετικούς χώρους ονομάτων δικτύου. Το «στο laptop μου» μπορεί να σημαίνει τον host Windows, μια διανομή WSL, την εικονική μηχανή Docker Desktop και ένα container μέσα σε αυτή τη VM — τέσσερα περιβάλλοντα που το καθένα μπορεί να απαντήσει διαφορετικά στο ίδιο όνομα host. Βρείτε ποιο χρησιμοποιεί η διεργασία που αποτυγχάνει πριν αγγίξετε μία και μόνη ρύθμιση.
Εντοπίστε τη διεργασία πριν αλλάξετε ρύθμιση
Ξεκινήστε από τη μηχανή container, όχι από τον πελάτη VPN. Ρωτήστε σε ποιο περιβάλλον μιλά η γραμμή εντολών και σε ποιο λειτουργικό σύστημα τρέχει αυτή η μηχανή, γιατί ένα container Linux που το διαχειρίζεται εικονική μηχανή επιφάνειας εργασίας ακολουθεί διαφορετική διαδρομή από ένα που το διαχειρίζεται τοπικός δαίμονας:
docker context ls
docker info --format '{{.OperatingSystem}} / {{.Name}}'
docker run --rm alpine ip route
Στα Windows, το wsl -l -v σας λέει αν η διανομή τρέχει κάτω από WSL 2, κάτι που τη βάζει πίσω από τον δικό της εικονικό διακόπτη. Αυτή η λεπτομέρεια αποφασίζει αν το container μοιράζεται τον πίνακα δρομολόγησης του host ή κάθεται πίσω από ένα NAT που χρειάζεται προωθημένη θύρα ή όνομα host για να φτάσει τον host.
Κρατήστε ένα αίτημα σταθερό και συγκρίνετε
Διαλέξτε ένα ακίνδυνο endpoint στον ιδιωτικό host και χρησιμοποιήστε το σε κάθε σύγκριση: από το πρόγραμμα περιήγησης, από τερματικό του host, από τη διανομή WSL και από μέσα από το container. Καταγράψτε τέσσερα πράγματα για κάθε απόπειρα: τη διεύθυνση που επιλύθηκε, αν χρησιμοποιήθηκε proxy, την κατηγορία αποτυχίας και τον χρόνο που πέρασε. Η αναζήτηση ονόματος, η σύναψη σύνδεσης, η επικύρωση TLS και μια κατάσταση HTTP είναι τέσσερα διαφορετικά προβλήματα, και το να τα ανακατεύετε σε «δεν δουλεύει» σπαταλά ένα πρωινό.
Εκτελέστε τη σύγκριση μέσα στο container που αποτυγχάνει, με timeout ώστε ένα σιωπηλό firewall να μην κρατά το τερματικό για λεπτά. Ένα καινούργιο container αναπαράγει το περιβάλλον δικτύου της μηχανής, αλλά όχι τον χώρο ονομάτων, τις μεταβλητές proxy ή τον resolver του container της εφαρμογής, γι' αυτό το docker exec στο πραγματικό container είναι η έγκυρη δοκιμή, και ένα sidecar είναι μόνο τρόπος να απομονώσετε αν η διαφορά είναι στη μηχανή ή στο container:
docker exec -it app /bin/sh -c "getent hosts api.internal; curl -v --max-time 8 https://api.internal/ 2>&1 | tail -20"
docker run --rm --network container:app curlimages/curl:latest -sv --max-time 8 https://api.internal/ 2>&1 | tail -20
Η βασική εικόνα alpine φέρει busybox και καθόλου curl, και αυτή ακριβώς είναι η λεπτομέρεια που κάνει ένα αντιγραμμένο διαγνωστικό μπλοκ να αποτυγχάνει: διαλέξτε εικόνα με τον πελάτη ή προσθέστε τον στην ίδια εκτέλεση. Η σύγκριση με άσχετους δημόσιους ιστότοπους δεν απομονώνει τίποτα. Αν το https://example.com δουλεύει από το container, μάθατε ότι το container έχει πρόσβαση στο διαδίκτυο και τίποτα για το αν φτάνει μια ιδιωτική διεύθυνση μέσα από τη σήραγγα. Ομοίως, το άνοιγμα νέου τερματικού αποδεικνύει μόνο ότι το νέο τερματικό δουλεύει, όχι ότι μοιράζεται περιβάλλον εκτέλεσης με την εφαρμογή που απέτυχε.
Το Docker Desktop μπορεί να δουλέψει με VPN
Η ίδια η τεκμηρίωση του Docker για VPN και συνδεσιμότητα host το περιγράφει ως υποστηριζόμενη ρύθμιση, και η ειλικρινής σύνοψη είναι ότι δουλεύει αντί να είναι αυτόματα χαλασμένο. Μην υποθέσετε ότι η VM επιφάνειας εργασίας παρακάμπτει τη σήραγγα του host εξ ορισμού· σε πολλές εγκαταστάσεις η κίνηση ακολουθεί σωστά τη σήραγγα του host, και γι' αυτό ο μύθος «το Docker αγνοεί το VPN» παράγει σίγουρες και λάθος συμβουλές.
Αυτό που μετράει ακόμα είναι το backend που χρησιμοποιείται, η πολιτική split tunnel του πελάτη και η διαμόρφωση resolver που έλαβε η VM. Ένας πελάτης VPN που εγκαθιστά διαδρομές αλλά όχι DNS, ή που σπρώχνει διακομιστή DNS που η VM δεν μπορεί να φτάσει, παράγει αποτυχία αναζήτησης ονόματος μέσα στο container ενώ ο host δουλεύει επειδή έχει επιπλέον resolver ή απάντηση στην κρυφή μνήμη. Είναι πρόβλημα resolver με κοστούμι container. Επιβιώνει σε κάθε επανασύνδεση VPN που δοκιμάζετε, γιατί η σήραγγα ήδη μεταφέρει την κίνηση που της ζητήσατε.
Οι επικαλύψεις διευθύνσεων και το MTU είναι διαφορετικές αστοχίες
Δύο αστοχίες αξίζουν δική τους διάγνωση γιατί συχνά μπερδεύονται με πολιτική πρόσβασης. Η πρώτη είναι επικάλυψη διευθύνσεων: αν το VPN σπρώχνει εύρος που συγκρούεται με το προεπιλεγμένο subnet γέφυρας ενός δικτύου container, η διαδρομή του container για αυτό το εύρος δείχνει στην τοπική γέφυρα και δεν φτάνει ποτέ τη σήραγγα. Επιθεωρήστε τα πραγματικά subnets αντί να μαντεύετε:
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
ip route get 10.20.30.40
Η δεύτερη είναι πρόβλημα MTU. Αν η σύνδεση εγκαθίσταται και το TLS ολοκληρώνεται αλλά οι μεγαλύτερες απαντήσεις κολλούν, έχετε πρόβλημα μεγέθους πακέτου, όχι εξουσιοδότησης, και η αντικατάσταση εγγραφών DNS δεν θα το διορθώσει ποτέ. Δοκιμάστε με μικρό αίτημα και με μεγάλο πριν αλλάξετε οτιδήποτε, και καταγράψτε και τα δύο αποτελέσματα.
Η λύση για μια επικάλυψη είναι διαφορετικό subnet container ή περιορισμένη διαδρομή, επιλεγμένη από όποιον κατέχει το σχέδιο διευθύνσεων. Η λύση για κόλλημα MTU είναι σύσφιγξη ή μείωση του MTU της σήραγγας ή της διεπαφής σε τιμή που επιβιώνει στη διαδρομή, εφαρμοσμένη στο επίπεδο που ελέγχετε.
Η διαμόρφωση proxy είναι ανά διεργασία, όχι ανά μηχάνημα
Μέσα σε ένα container, το localhost ονομάζει το δικό του περιβάλλον δικτύου, άρα ένα proxy που τρέχει στον host δεν είναι προσβάσιμο εκεί με αυτό το όνομα. Το Docker Desktop παρέχει το host.docker.internal για πρόσβαση στον host, και στο Linux το προσθέτετε ρητά με το --add-host=host.docker.internal:host-gateway. Όπως και να έχει, αυτό το όνομα σας δίνει διαδρομή προς τον host· δεν δημιουργεί υπηρεσία proxy ούτε σας εξουσιοδοτεί να χρησιμοποιήσετε μία.
Χρησιμοποιήστε τη διεύθυνση και τη θύρα proxy που δίνονται για το πραγματικό περιβάλλον και ελέγξτε ποιος τις διαβάζει. Μεταβλητές που εξάγονται σε διαδραστικό shell δεν διαμορφώνουν αυτόματα κάθε επέκταση editor, διακομιστή γλώσσας, εργαλείο build και δαίμονα παρασκηνίου. Αυτό που μετράει είναι η διεργασία που έκανε το αίτημα που απέτυχε, οπότε επιθεωρήστε το περιβάλλον της και όχι του τερματικού σας.
Τέλος, κάντε τη διόρθωση να εξηγεί τον εαυτό της. Μια χρήσιμη λύση ονομάζει το όριο που ήταν λάθος, τη ρύθμιση που το άλλαξε και το σύνολο διεργασιών που επηρεάζει τώρα. Η επανεκκίνηση VPN, editor και μηχανής με τη σειρά μπορεί να αλλάξει το σύμπτωμα, αλλά δεν αφήνει τίποτα που να μπορεί να χρησιμοποιήσει ο επόμενος.