Strona dostawy pokazuje przekroczenie czasu, a Jenkins nic nie rejestruje, co jest sygnaturą połączenia, które nigdy nie dotarło. GitHub wysyła webhook jako wychodzący HTTP POST z własnej infrastruktury na skonfigurowany payload URL. VPN chroni Jenkinsa, odrzucając dokładnie taki rodzaj połączenia. Po żadnej stronie nic nie jest zepsute. Problemem jest kierunek żądania.

Czego dostawa faktycznie próbuje

GitHub rozwiązuje nazwę hosta w payload URL i łączy się z nią z publicznego internetu. Jeśli ten URL wskazuje na adres prywatny lub na nazwę, która rozwiązuje się tylko w Twojej sieci, próba kończy się niepowodzeniem, zanim zostanie wysłane jakiekolwiek żądanie. Jeśli wskazuje na publiczną nazwę, którą odrzuca Twoja krawędź, próba zamiast tego przekracza czas.

Ta różnica ma znaczenie dla diagnozy. Awaria DNS i filtrowany port wyglądają tak, jakby po stronie Jenkinsa nic się nie stało, i oba pojawiają się w GitHubie jako nieudana dostawa z innym dołączonym powodem. Przeczytaj ten powód, zanim zmienisz URL.

Tunel, który wybiera połączenie na zewnątrz, nie tworzy nasłuchu. Właśnie tej części ludzie oczekują, że będzie działać inaczej.

Trzy sposoby naprawienia kierunku połączenia

Każde rozwiązanie zmienia to, kto inicjuje połączenie, i istnieją tylko trzy kształty.

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

Odpytowanie jest najmniej eleganckie i najłatwiejsze w utrzymaniu. Relay utrzymuje niemal natychmiastową informację zwrotną bez otwierania portu. Runner jest zwykle właściwą odpowiedzią, gdy poufność payloadu wyklucza stronę trzecią, ponieważ zadanie może działać na maszynie, która już znajduje się w sieci.

Wybieraj według tego, czym potrafisz zarządzać, a nie według tego, co brzmi nowocześnie.

Przekaż dostawę na zewnątrz za pomocą smee

Utwórz kanał w usłudze relay i zachowaj jego URL. W sieci zainstaluj klienta i przekazuj dostawy na ścieżkę, której oczekuje Jenkins. Payload URL w ustawieniach repozytorium staje się URL-em kanału, a typ treści jest ustawiony na application/json.

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

Trzy szczegóły decydują, czy to zadziała. Ścieżka musi odpowiadać temu, czego Jenkins oczekuje dla zdarzeń GitHub, czyli domyślnie /github-webhook/. Jenkins musi nasłuchiwać na porcie, który dałeś klientowi. A skonfigurowany w zadaniu Jenkins URL musi zgadzać się z tą ścieżką, inaczej zdarzenie dotrze i zostanie odrzucone.

Niezgodność końcowego ukośnika daje 404, który czyta się jak nieudana dostawa, ale nią nie jest.

Uruchamianie tak, aby przetrwało tydzień

Klient na pierwszym planie umiera wraz z terminalem, a webhooki działają dzień, po czym się zatrzymują. Daj mu unit z Restart=always, uruchom jako użytkownik Jenkins i przeczytaj journal po pierwszej rzeczywistej dostawie. Właśnie ten ostatni krok odróżnia działający relay od skonfigurowanego.

[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

Testuj prawdziwym push, a nie przyciskiem odtwarzania. Odtwarzanie ćwiczy zapisany payload relay, a nie ścieżkę z GitHuba do Twojego kanału, więc może przejść, podczas gdy dostawa na żywo nadal zawodzi.

Alarmuj, gdy unit się zatrzyma. Relay, który leży, jest cichy z konstrukcji, a cisza jest dokładnie tym, co już debugujesz.

Co relay może zobaczyć i kiedy go nie używać

Relay kończy payload, więc widzi nazwy repozytoriów, dane commitów i wszystko inne, co niesie zdarzenie. Traktuj URL kanału jako publiczny punkt końcowy. Utrzymuj skonfigurowany tajny token Jenkinsa, aby fałszywe dostawy były odrzucane, i ogranicz token używany przez Jenkinsa do niezbędnego minimum.

Jeśli poufność payloadu to wyklucza, hostowany samodzielnie runner lub uwierzytelniony tunel odwrotny jest odpowiedzią.

Relay jest teraz infrastrukturą i zasługuje na taki sam przegląd jak build, który uruchamia. Obróć kanał, jeśli wycieknie, i zapisz datę ostatniego zweryfikowania dostawy na żywo. Umieść tę datę w runbooku obok URL-a kanału. Relay, którego nikt nie przejrzał przez rok, to publiczny punkt końcowy, którego nikt nie posiada.

Powiązane artykuły