Jūsu deploy solis iekaras iekšējā hostname, kamēr tā pati komanda no klēpjdatora atbild acumirklī, un klienta build abās mašīnās ir identisks. Job darbojas GitHub hostētā runner: virtuālajā mašīnā, kas izveidota tieši šim vienam job GitHub mākonī, bez maršruta uz jūsu privāto adrešu telpu, bez resolver ieraksta iekšējai zonai un bez sertifikāta, ko pieņemtu privātais endpoint. Šim ierobežojumam atbilst tikai divi risinājumi, un nevienu no tiem nevar ieslēgt vēlāk, nepārbūvējot workflow. Izvēlieties pirms pirmās YAML rindas, jo pārcelšanās vēlāk izmaksā vairāk nekā pirmais mēģinājums.

Izvēle ir starp runner, kas novietots tur, kur tīkls jau beidzas, un tuneli, kas pastāv tieši vienu job. Abi jau gadiem nes produkcijas deploy, un tie sabrūk dažādos veidos.

Kur īsti atrodas robeža

Viss, ko instalējat klēpjdatorā, apstājas klēpjdatorā, un viss, ko instalējat job laikā, pazūd kopā ar runner. Nav pastāvīgas tīkla vārdu telpas, pie kuras klients paliktu piesaistīts starp palaidēm, tāpēc katra palaide sākas tajā pašā nesasniedzamajā stāvoklī. Azure dokumentē šo robežu Microsoft hostētajiem aģentiem: VPN un ExpressRoute savienojumi uz privātiem tīkliem tur netiek atbalstīti, un GitHub hostētie runner nes tādu pašu ierobežojuma formu, nevis atsevišķu mehānismu. Lasiet to kā produkta īpašību, nevis defektu, kas jāapiet.

Neviens repozitorija iestatījums to neatbrīvo. Job etiķete nosaka, kura pule paņems darbu, un hostēta etiķete nozīmē mašīnu ārpus jūsu perimetra visā palaidē.

Tāpēc privātajai sasniedzamībai jānāk no kaut kā, kas pieder jums. Runner, kas novietots tur, kur tīkls jau beidzas, vai tunelis, kas dzīvo vienu job. Pārējais raksts ir par apzinātu samaksu par vienu no šiem, nevis rēķina atrašanu produkcijā.

Izlemiet pēc palaižu biežuma, nevis pēc ieraduma

Izmantojiet savu runner VPC vai biroja tīklā, kad deploy ienāk vairākas reizes dienā, kad job aizskar vairāk nekā vienu privāto portu vai kad platformas komanda jau atbild par ielāpiem un akreditācijas datu rotāciju. Job uz tās mašīnas atrisina un maršrutē kā jebkurš cits host aiz ugunsmūra. Tīkla darbs notiek vienreiz, instalācijas laikā, nevis katrā palaidē.

Veidojiet tuneli job iekšpusē, kad piekļuve ir reta un jūs nevēlaties ilgmūžīgu aģentu, kas tur akreditācijas datus jūsu tīklā. Job uz dažām minūtēm kļūst par savu tīkla klientu un neko neatstāj aiz sevis, kas bieži ir visa jēga.

Novērtējiet tuneļa izmaksas pirms tā izvēles. Katra palaide maksā par profila izveidi, klienta palaišanu, gatavību un demontāžu. Tunelis, kas paceļas, bet nekad netiek pārbaudīts, rada deploy, kas sabrūk pusceļā un atstāj privāto stāvokli tādā formā, kādu neviens nebija plānojis. Atkārtotais mēģinājums pēc tam reti ir tīrs, un otrais neveiksmes gadījums parasti tiek uzvelts klienta versijai.

Rakstīt profilu tā, lai solis nevarētu pārtraukties

Turiet profilus un akreditācijas datus ārpus repozitorija un materializējiet tos no secret tajā solī, kuram tie nepieciešami. Secība nosaka, vai job izdzīvos: fails, kas izveidots zem sudo, pieder root, un soļa neprivileģētā shell vairs nevar tajā rakstīt.

- name: Bring up OpenVPN
  run: |
    umask 077
    profile="$RUNNER_TEMP/client.ovpn"
    printf '%s\n' "$VPN_PROFILE" > "$profile"
    : > "$RUNNER_TEMP/openvpn.log"
    printf '%s\n' "$VPN_CREDENTIALS" > "$RUNNER_TEMP/credentials.txt"
    sudo openvpn --daemon openvpn-job \
      --config "$profile" \
      --auth-user-pass "$RUNNER_TEMP/credentials.txt" \
      --writepid "$RUNNER_TEMP/openvpn.pid" \
      --log "$RUNNER_TEMP/openvpn.log"

Abas šī bloka detaļas ir paredzētas nākamajiem soļiem. Ar umask 077 profils nonāk 0600 režīmā runner lietotāja īpašumā, sudo to joprojām var lasīt, un klients raksta savu žurnālu failā, kas runner jau pieder, tāpēc gatavības cilpa var lasīt šo žurnālu bez otra sudo. --writepid reģistrē PID, uz kuru mērķēs demontāža.

Profils, kas autentificējas ar klienta sertifikātu, prasa tā atslēgu, kas ierakstīta tādā pašā veidā, un static-challenge profilam vajadzīgs atbilstošs auth režīms. Profiliem, kas stumj DNS opcijas, Ubuntu un Debian vajadzīgs openvpn-systemd-resolved, jo stumšana vien pati par sevi bāzes attēlā neko nemaina.

Gatavība ir zonde, nevis pauze

Fiksēts sleep iztur tieši līdz brīdim, kad koncentrators palēninās, un tad deploy solis darbojas pirms maršruta pastāvēšanas. Kļūda pēc tam parādās deploy rīka iekšpusē kā timeout pret privāto host, kas neko nepasaka par tuneli.

- name: Await private endpoint
  run: |
    for attempt in $(seq 1 30); do
      if getent hosts private.example.internal > /dev/null && \
         timeout 3 bash -c 'exec 3<>/dev/tcp/private.example.internal/8443' 2>/dev/null; then
        echo "endpoint answered after $attempt attempts"
        exit 0
      fi
      sleep 2
    done
    grep -Ei 'error|verify|auth' "$RUNNER_TEMP/openvpn.log" | tail -40
    exit 1

Cilpa vēro divas lietas, jo jebkura no tām var būt salauztā puse. getent hosts pierāda, ka stumtais resolver atbild par šo vārdu, un socket atvēršanās pierāda, ka kaut kas klausās portā, ko izmantos deploy; profilam tikai ar maršrutu vajadzīga burtiskā adrese un izdzēsta getent rinda.

Kad cilpa beidzas, žurnāls ir vienīgais, kas atdala trīs dažādas kļūmes: noraidītu sertifikātu, nepareizu auth režīmu un maršrutu, kas tā arī neatnāca. Filtrēšana pirms tail notur šo izvadi gana īsu, lai to varētu nolasīt, kamēr job vēl sabrūk. Lasiet pirmo kļūdu, nevis pēdējo rindu, jo klients, kas nevar autentificēties, atkārtojas, līdz cilpa padodas. ip -4 route show dev tun0 atbild uz vienkāršāku jautājumu, vai maršruts vispār tika stumts, un tajā pašā cilpā tas maksā vienu rindu.

Demontāža un artefakta jautājums

Noslēdziet job ar soli, ko aizsargā if: always() un kas izpilda sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" un neko citu. Koplietotā paša runner nekad nenogaliniet pēc procesa nosaukuma: citam job var būt klients ar to pašu bināro failu un līdzīgiem argumentiem. Tad kļūme krīt uz to job, kas darbojās otrais, un tā žurnāls norāda uz workflow, kas neko nav izdarījis nepareizi.

Aizsardzība ir svarīga, jo neveiksmīgs deploy tomēr atstāj dzīvu tuneli. Bez always() tīrīšanas solis tiek izlaists tieši tad, kad tas ir vajadzīgs, un nākamā palaide sākas pret jau savienotu klientu.

Pirms pieņemt jebkuru no risinājumiem paliek viens jautājums: vai build posmam vispār vajadzīgs privāts maršruts? Deployment aģents, kas jau sēž tīklā, var izvilkt apstiprinātu artefaktu, un tas tur parastos buildus tālu no privātā ceļa. Mazāk job, kas tur tuneli, nozīmē mazāk vietu, kur vecs maršruts var paslēpties.

Saistītie raksti