Η σελίδα παράδοσης δείχνει λήξη χρόνου και το Jenkins δεν καταγράφει τίποτα, που είναι το σημάδι μιας σύνδεσης που δεν έφτασε ποτέ. Το GitHub στέλνει ένα webhook ως εξερχόμενο HTTP POST από τη δική του υποδομή προς το payload URL που ρυθμίσατε. Ένα VPN προστατεύει το Jenkins απορρίπτοντας ακριβώς αυτό το είδος σύνδεσης. Τίποτα δεν είναι χαλασμένο σε καμία πλευρά. Το πρόβλημα είναι η κατεύθυνση του αιτήματος.

Τι επιχειρεί στην πραγματικότητα η παράδοση

Το GitHub επιλύει το όνομα κεντρικού υπολογιστή στο payload URL και συνδέεται σε αυτό από το δημόσιο διαδίκτυο. Αν αυτό το URL δείχνει σε ιδιωτική διεύθυνση ή σε όνομα που επιλύεται μόνο μέσα στο δίκτυό σας, η προσπάθεια αποτυγχάνει πριν γίνει οποιοδήποτε αίτημα. Αν δείχνει σε δημόσιο όνομα που το άκρο σας απορρίπτει, η προσπάθεια λήγει αντ’ αυτού.

Η διάκριση έχει σημασία για τη διάγνωση. Μια αποτυχία DNS και μια φιλτραρισμένη θύρα μοιάζουν και οι δύο σαν να μην συνέβη τίποτα στην πλευρά του Jenkins, και και οι δύο εμφανίζονται στο GitHub ως αποτυχημένη παράδοση με διαφορετικό λόγο συνημμένο. Διαβάστε αυτόν τον λόγο πριν αλλάξετε το URL.

Ένα τούνελ που καλεί προς τα έξω δεν δημιουργεί ακροατή. Αυτό είναι το κομμάτι που ο κόσμος περιμένει να λειτουργεί διαφορετικά.

Τρεις τρόποι να διορθώσετε την κατεύθυνση της σύνδεσης

Κάθε λύση αλλάζει ποιος ξεκινά τη σύνδεση, και υπάρχουν μόνο τρεις μορφές.

ApproachWho initiatesWhat you give up
Relay serviceAn outbound client inside the networkA third party sees every payload
Reverse tunnel or ingressThe public edge, into a controlled listenerAn inbound surface you must secure
Runner or pollingThe agent, outbound to GitHubInstant delivery, replaced by a schedule

Η ερώτηση είναι η λιγότερο κομψή και η ευκολότερη στη λειτουργία. Ένα relay κρατά σχεδόν άμεση ανάδραση χωρίς να ανοίγει θύρα. Ένας runner είναι συνήθως η σωστή απάντηση όταν η εμπιστευτικότητα του payload αποκλείει τρίτο μέρος, γιατί η εργασία μπορεί να τρέξει σε μηχάνημα που βρίσκεται ήδη μέσα στο δίκτυο.

Διαλέξτε με βάση τι μπορείτε να λειτουργήσετε, όχι με βάση τι ακούγεται μοντέρνο.

Προωθήστε μια παράδοση προς τα έξω με το smee

Δημιουργήστε ένα κανάλι στην υπηρεσία relay και κρατήστε το URL του. Μέσα στο δίκτυο, εγκαταστήστε τον client και προωθήστε τις παραδόσεις στη διαδρομή που περιμένει το Jenkins. Το payload URL στις ρυθμίσεις του repository γίνεται το URL του καναλιού, με τον τύπο περιεχομένου να ορίζεται σε application/json.

sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080

Τρεις λεπτομέρειες κρίνουν αν δουλεύει. Η διαδρομή πρέπει να ταιριάζει με αυτό που περιμένει το Jenkins για τα συμβάντα GitHub, που από προεπιλογή είναι /github-webhook/. Το Jenkins πρέπει να ακούει στη θύρα που δώσατε στον client. Και το Jenkins URL που έχει ρυθμιστεί στην εργασία πρέπει να συμφωνεί με αυτή τη διαδρομή, αλλιώς το συμβάν φτάνει και μετά πετιέται.

Μια ασυμφωνία στην τελική κάθετο παράγει ένα 404 που διαβάζεται ως αποτυχημένη παράδοση και δεν είναι.

Εκτέλεση ώστε να αντέξει την εβδομάδα

Ένας client στο προσκήνιο πεθαίνει μαζί με το τερματικό, και τα webhooks δουλεύουν μια μέρα και μετά σταματούν. Δώστε του ένα unit με Restart=always, τρέξτε το ως χρήστης Jenkins και διαβάστε το journal μετά την πρώτη πραγματική παράδοση. Ακριβώς αυτό το τελευταίο βήμα ξεχωρίζει ένα relay που δουλεύει από ένα ρυθμισμένο.

[Unit]
Description=smee webhook relay
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=2
User=jenkins
ExecStart=/usr/bin/smee -u CHANNEL_URL --path /github-webhook/ --port 8080

[Install]
WantedBy=multi-user.target

Δοκιμάστε με πραγματικό push αντί για κουμπί επανάληψης. Η επανάληψη ασκεί το αποθηκευμένο payload του relay, όχι τη διαδρομή από το GitHub στο κανάλι σας, οπότε μπορεί να περάσει ενώ η ζωντανή παράδοση ακόμη αποτυγχάνει.

Ειδοποιήστε όταν σταματήσει το unit. Ένα relay που είναι κάτω είναι σιωπηλό εκ κατασκευής, και η σιωπή είναι ακριβώς αυτό που ήδη εντοπίζετε.

Τι μπορεί να δει το relay και πότε να μην το χρησιμοποιήσετε

Ένα relay τερματίζει το payload, οπότε βλέπει ονόματα repository, δεδομένα commit και ό,τι άλλο μεταφέρει το συμβάν. Αντιμετωπίστε το URL του καναλιού ως δημόσιο τελικό σημείο. Κρατήστε το μυστικό token του Jenkins ρυθμισμένο ώστε να απορρίπτονται πλαστές παραδόσεις, και περιορίστε το token που χρησιμοποιεί το Jenkins στο ελάχιστο που χρειάζεται.

Αν η εμπιστευτικότητα του payload το αποκλείει, ένας self-hosted runner ή ένα πιστοποιημένο αντίστροφο τούνελ είναι η απάντηση.

Ένα relay είναι πλέον υποδομή και αξίζει την ίδια αναθεώρηση με το build που ενεργοποιεί. Αλλάξτε το κανάλι αν διαρρεύσει, και σημειώστε την ημερομηνία που επαληθεύσατε τελευταία φορά μια ζωντανή παράδοση. Βάλτε αυτή την ημερομηνία στο runbook δίπλα στο URL του καναλιού. Ένα relay που δεν το εξέτασε κανείς για ένα χρόνο είναι ένα δημόσιο τελικό σημείο που δεν ανήκει σε κανέναν.

Σχετικά άρθρα