GitHub Actions-ek ez du zure VPN-ra iristen: runner propioa edo tunela
Ostatutako runner bat zure sarearen kanpoko VM berri bat da. Jarri runner bat sare horren barruan, edo egin tunel bat job-etik eta itxaron benetako ibilbide baten.
Zure deploy urratsa barneko hostname batean zintzilik geratzen da, komando berak zure ordenagailutik berehala erantzuten duen bitartean, eta bi makinetako client build-a berbera da. Job-a GitHub-ek ostatatutako runner batean exekutatzen da: job horretarako berariaz GitHub-en hodeian sortutako makina birtuala, zure helbide-espazio pribaturako ibilbiderik gabe, barne-eremurako resolver erregistrorik gabe eta endpoint pribatuak onartuko lukeen ziurtagiririk gabe. Muga horretara bi diseinu baino ez dira egokitzen, eta ez dago horietako bat ere geroago pizterik workflow-a berreraiki gabe. Aukeratu horien artean lehen YAML lerroa baino lehen, geroago migratzeak lehen saiakera baino gehiago balio duelako.
Aukera sareak jada uzten duen tokian jarritako runner baten eta job bakar bat bizi den tunel baten artean dago. Biek urteak daramatzate produkzioko deploy-ak eramaten, eta modu ezberdinetan huts egiten dute.
Non dago muga benetan
Ordenagailuan instalatutako guztia ordenagailuan gelditzen da, eta job batean instalatutakoa runner-arekin batera desagertzen da. Ez dago client-a exekuzioen artean lotuta egon daitekeen sare-namespace iraunkorrik, beraz exekuzio bakoitza egoera iristezin beretik hasten da. Azure-k muga hori dokumentatzen du Microsoft-ek ostatatutako agententzat: sare pribatuetarako VPN eta ExpressRoute estekak ez dira onartzen han, eta GitHub-ek ostatatutako runner-ek murrizketa-forma bera daramate, mekanismo bereizi bat izan beharrean. Irakurri hau produktuaren ezaugarri gisa, saihestu beharreko akats gisa baino.
Repositorioko ezarpen batek ere ez du hori lasaitzen. Job-aren etiketak erabakitzen du zein pool-ek hartzen duen lana, eta ostatatutako etiketa batek zure perimetroaren kanpoko makina esan nahi du exekuzio osoan.
Beraz, irisgarritasun pribatuak zurea den zerbaitetik etorri behar du. Sareak jada uzten duen tokian jarritako runner bat, edo job bakarra bizi duen tunel bat. Artikuluaren gainerakoa horietako bat nahita ordaintzeari buruzkoa da, produkzioan faktura aurkitzearen ordez.
Erabaki exekuzio-maiztasunaren arabera, ohiturarekin ez
Erabili runner propioa VPC edo bulegoko sarearen barruan, deploy-ak egunean hainbat aldiz iristen direnean, job-ak portu pribatu bat baino gehiago ukitzen duenean, edo plataforma-taldeak jada adabakiak eta kredentzialen errotazioa bere gain hartzen duenean. Makina horretako job-ak firewall atzeko beste edozein host-ek bezala ebazten eta bideratzen du. Sare-lana behin egiten da, instalazioan, ez exekuzio bakoitzean.
Eraiki tunela job-aren barruan, sarbidea noizean behin gertatzen denean eta zure sarera kredentzial bat eusten duen agente luze bat nahi ez duzunean. Job-a minutu batzuetan bere sare-client bihurtzen da eta ez du ezer uzten, eta hori izaten da askotan helburu osoa.
Kalkulatu tunelaren kostua aukeratu aurretik. Exekuzio bakoitzak profilea gauzatzea, client-a abiaraztea, prestutasuna eta desmuntatzea ordaintzen ditu. Igo baina inoiz egiaztatzen ez den tunel batek erdibidean huts egiten duen deploy bat sortzen du, eta inork aurreikusi ez zuen forman uzten du egoera pribatua. Ondorengo berriz saiatzeak gutxitan dira garbiak, eta bigarren hutsa client bertsioari leporatzen zaio normalean.
Profila urratsa eten ezin dadin idaztea
Eduki profileak eta kredentzialak repositoriotik kanpo, eta gauzatu them secret-etatik behar dituen urratsean. Ordenak erabakitzen du job-a bizirik ateratzen den: sudo pean sortutako fitxategia root-ena da, eta urratsaren pribilegiorik gabeko shell-ak ezin du jada bertan idatzi.
- 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"Bloke horretako bi xehetasunak ondorengo urratsetarako dira. umask 077 erabilita profila 0600 moduan iristen da eta runner erabiltzailearena da, sudo-k oraindik irakur dezake, eta client-ak bere log-a runner-ak dagoeneko duen fitxategi batean idazten du, beraz prestutasun begiztak log hori bigarren sudorik gabe irakur dezake. eta --writepid erregistratzen du desmuntatzeak seinalatuko duen PID-a erregistratzen du.
Client ziurtagiriarekin autentifikatzen den profile batek bere gakoa modu berean idatzita behar du, eta static-challenge profile batek bat datorren auth modua behar du. DNS aukerak push egiten dituzten profileek openvpn-systemd-resolved behar dute Ubuntu eta Debian-en, push-ak berak ez baitu ezer aldatzen oinarrizko irudian.
Prestutasuna zunda bat da, ez pausoa
Sleep finko batek kontzentratzailea moteldu arte bakarrik eusten du, eta orduan deploy urratsa ibilbidea existitu baino lehenago exekutatzen da. Hutsak gero deploy tresnaren barruan agertzen dira host pribatuaren aurkako timeout gisa, eta horrek ez du tunelari buruz ezer esaten.
- 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 1Begiztak bi gauza behatzen ditu, horietako edozein izan baitaiteke erdibitu hautsia. getent hosts frogatzen du push egindako resolver-ak izen horretarako erantzuten duela frogatzen du, eta socket-a irekitzeak deploy-ak erabiliko duen portuan zerbait entzuten ari dela frogatzen du; ibilbidea soilik duen profile batek helbide literalak eta ezabatutako getent lerroa behar ditu.
Begizta amaitzean, log-a da hiru matxura ezberdin bereizten dituen gauza bakarra: ukatu gabeko ziurtagiria, auth modu okerra eta inoiz iritsi ez zen ibilbidea. Tail aurretik iragazteak irteera hori irakurtzeko adina labur uzten du job-a huts egiten ari den bitartean. Irakurri lehen errorea eta ez azken lerroa, autentifikatu ezin duen client-ak bere burua errepikatzen baitu begiztak amore eman arte. ip -4 route show dev tun0 erantzuten dio ibilbidea push egin zen ala ez galdetzen duen galdera simpleagoari erantzuten dio, eta begizta berean lerro bat besterik ez du balio.
Desmuntatzea eta artifact-aren galdera
Itxi job-a if: always() babestutako eta sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" besterik exekutatzen ez duen urrats batekin. Partekatutako runner propioan inoiz ez ezabatu prozesuaren izenaz: beste job batek binary bera eta antzeko argumentuak dituen client bat izan dezake. Hutsa orduan bigarren exekutatu zen job-era erortzen da, eta haren log-ak ezer gaizki egin ez zuen workflow batera seinalatzen du.
Babesa garrantzitsua da, huts egin duen deploy batek tunel bizia uzten duelako. always() gabe garbiketa urratsa behar denean bertan saltatzen da, eta hurrengo exekuzioa jada konektatuta dagoen client baten aurka hasten da.
Galdera bat geratzen da bi diseinuetako bat onartu aurretik: build faseak benetan behar al du ibilbide pribaturik? Sarean jada eserita dagoen deployment agente batek onartutako artifact bat lor dezake, eta horrek build arruntak bide pribatutik urrun edukitzen ditu. Tunela eusten duten job gutxiago esan nahi du ibilbide zaharkitu bat ezkutatu daitekeen toki gutxiago.