VPN के पीछे बैठे Jenkins के सामने GitHub webhooks क्यों टाइम आउट होते हैं
GitHub webhooks अंदर की ओर भेजता है, इसलिए Jenkins की रक्षा करने वाला VPN उन्हें ठुकरा देता है। डिलीवरी को relay के ज़रिए बाहर भेजें, या webhook को पोलिंग करने वाले agent से बदलें।
डिलीवरी पेज टाइम आउट दिखाता है और Jenkins कुछ भी लॉग नहीं करता, जो ऐसे कनेक्शन की पहचान है जो कभी पहुँचा ही नहीं। GitHub अपने ही इन्फ्रास्ट्रक्चर से आपके कॉन्फ़िगर किए गए payload URL तक एक आउटबाउंड HTTP POST के रूप में webhook भेजता है। VPN ठीक इसी तरह के कनेक्शन को ठुकराकर Jenkins की रक्षा करता है। किसी भी तरफ़ कुछ टूटा नहीं है। समस्या अनुरोध की दिशा में है।
डिलीवरी असल में क्या करने की कोशिश करती है
GitHub payload URL में मौजूद होस्टनेम को रिज़ॉल्व करता है और सार्वजनिक इंटरनेट से उससे जुड़ता है। अगर वह URL किसी निजी पते की ओर इशारा करता है, या ऐसे नाम की ओर जो सिर्फ़ आपके नेटवर्क के अंदर रिज़ॉल्व होता है, तो कोई भी अनुरोध भेजे जाने से पहले ही कोशिश विफल हो जाती है। अगर वह ऐसे सार्वजनिक नाम की ओर इशारा करता है जिसे आपका एज गिरा देता है, तो कोशिश इसके बजाय टाइम आउट हो जाती है।
निदान के लिए यह अंतर मायने रखता है। DNS विफलता और फ़िल्टर किया गया पोर्ट दोनों ऐसे दिखते हैं जैसे Jenkins की तरफ़ कुछ हुआ ही न हो, और दोनों GitHub पर अलग कारण के साथ विफल डिलीवरी के रूप में दिखते हैं। URL बदलने से पहले वह कारण पढ़ें।
बाहर की ओर डायल करने वाला टनल श्रोता नहीं बनाता। लोग ठीक इसी हिस्से के अलग तरह से काम करने की उम्मीद करते हैं।
कनेक्शन की दिशा ठीक करने के तीन तरीके
हर हल बदलता है कि कनेक्शन कौन शुरू करता है, और सिर्फ़ तीन आकार हैं।
| Approach | Who initiates | What you give up |
|---|---|---|
| Relay service | An outbound client inside the network | A third party sees every payload |
| Reverse tunnel or ingress | The public edge, into a controlled listener | An inbound surface you must secure |
| Runner or polling | The agent, outbound to GitHub | Instant delivery, replaced by a schedule |
पोलिंग सबसे कम सुरुचिपूर्ण और चलाने में सबसे आसान है। relay बिना कोई पोर्ट खोले लगभग तुरंत फ़ीडबैक रखता है। runner आमतौर पर सही जवाब है जब payload की गोपनीयता तीसरे पक्ष को बाहर रखती है, क्योंकि काम ऐसी मशीन पर चल सकता है जो पहले से नेटवर्क के अंदर है।
जो आप चला सकते हैं उसके आधार पर चुनें, आधुनिक सुनने वाले के आधार पर नहीं।
smee के साथ डिलीवरी बाहर भेजें
relay सेवा पर एक चैनल बनाएँ और उसका URL रखें। नेटवर्क के अंदर, क्लाइंट इंस्टॉल करें और डिलीवरी को उस पथ पर भेजें जिसकी Jenkins उम्मीद करता है। रिपॉज़िटरी सेटिंग्स का payload URL चैनल का URL बन जाता है, कंटेंट टाइप application/json पर सेट रहता है।
sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080तीन ब्यौरे तय करते हैं कि यह काम करेगा या नहीं। पथ को GitHub इवेंट के लिए Jenkins की अपेक्षा से मेल खाना चाहिए, जो डिफ़ॉल्ट रूप से /github-webhook/ है। Jenkins को उस पोर्ट पर सुनना चाहिए जो आपने क्लाइंट को दिया है। और जॉब में कॉन्फ़िगर किया गया Jenkins URL उस पथ से सहमत होना चाहिए, वरना इवेंट पहुँचता है और फिर फेंक दिया जाता है।
अंत में स्लैश का मेल न होना 404 पैदा करता है जो डिलीवरी विफलता जैसा पढ़ा जाता है और वह नहीं है।
इसे ऐसे चलाना कि हफ़्ता निकल जाए
फ़ोरग्राउंड क्लाइंट टर्मिनल के साथ मर जाता है, और webhooks एक दिन चलते हैं फिर रुक जाते हैं। इसे Restart=always वाला unit दें, Jenkins उपयोगकर्ता के रूप में चलाएँ, और पहली असली डिलीवरी के बाद journal पढ़ें। यही आख़िरी कदम काम करते relay को कॉन्फ़िगर किए गए 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 से परखें। रीप्ले relay के संग्रहित payload का अभ्यास करता है, GitHub से आपके चैनल तक के रास्ते का नहीं, इसलिए यह तब भी पास हो सकता है जब लाइव डिलीवरी अब भी विफल हो।
unit रुकने पर चेतावनी दें। बंद relay अपनी बनावट से ही ख़ामोश होता है, और ख़ामोशी वही है जिसे आप पहले से डीबग कर रहे हैं।
relay क्या देख सकता है, और कब इसका उपयोग न करें
relay payload को समाप्त करता है, इसलिए वह रिपॉज़िटरी के नाम, commit डेटा और इवेंट जो कुछ भी ढोता है, सब देखता है। चैनल के URL को सार्वजनिक अंतिम बिंदु मानें। Jenkins का secret token कॉन्फ़िगर रखें ताकि जाली डिलीवरी ठुकराई जाए, और Jenkins जो token इस्तेमाल करता है उसकी सीमा ज़रूरी न्यूनतम तक रखें।
अगर payload की गोपनीयता इसे बाहर रखती है, तो स्वयं-होस्टेड runner या प्रमाणित रिवर्स टनल जवाब है।
relay अब इन्फ्रास्ट्रक्चर है, और वह उस build जितनी ही समीक्षा का हक़दार है जिसे वह ट्रिगर करता है। अगर चैनल लीक हो तो उसे रोटेट करें, और वह तारीख़ नोट करें जब आपने आख़िरी बार लाइव डिलीवरी जाँची थी। वह तारीख़ चैनल के URL के बगल में runbook में डालें। जिस relay की किसी ने साल भर समीक्षा नहीं की वह सार्वजनिक अंतिम बिंदु है जिसका कोई मालिक नहीं।