GitHub Actions haifikii VPN yako: runner yako mwenyewe au handaki
Runner inayopangishwa ni VM mpya nje ya mtandao wako. Ama weka runner ndani ya mtandao huo, au tengeneza handaki kutoka kwa job na usubiri njia halisi.
Hatua yako ya deploy inaning'inia kwenye hostname ya ndani wakati amri hiyo hiyo inajibu papo hapo kutoka kwa laptop yako, na client build kwenye mashine zote mbili ni sawa. Job inaendeshwa kwenye runner inayopangishwa na GitHub: mashine pepe iliyoundwa kwa ajili ya job hiyo moja ndani ya wingu la GitHub, bila njia ya kuingia kwenye nafasi yako ya anwani za kibinafsi, bila resolver entry ya eneo la ndani na bila cheti ambacho endpoint ya kibinafsi itakubali. Ni miundo miwili tu inayofaa kizuizi hicho, na hakuna hata mmoja unaoweza kuwashwa baadaye bila kujenga upya workflow. Chagua kati yao kabla ya mstari wa kwanza wa YAML, kwa sababu kuhamia baadaye kunagharimu zaidi kuliko jaribio la kwanza.
Chaguo ni kati ya runner iliyowekwa pale mtandao unapoishia tayari na handaki inayoishi job moja tu. Zote mbili zimebeba deploy za uzalishaji kwa miaka, na zinashindwa kwa namna tofauti.
Mpaka upo wapi kwa kweli
Kila kitu unachoweka kwenye laptop kinaishia kwenye laptop, na kila kitu unachoweka wakati wa job kinatoweka pamoja na runner. Hakuna namespace ya mtandao ya kudumu ambayo client anaweza kushikamana nayo kati ya uendeshaji, kwa hiyo kila uendeshaji unaanza katika hali ile ile isiyofikiwa. Azure inaandika mpaka huu kwa agents zinazopangishwa na Microsoft, ambapo viungo vya VPN na ExpressRoute kuingia kwenye mitandao ya kibinafsi havijaungwa mkono, na runners zinazopangishwa na GitHub zinabeba aina hiyo hiyo ya kizuizi badala ya utaratibu tofauti. Soma hii kama sifa ya bidhaa, si kasoro ya kuepukwa.
Hakuna mpangilio wa repository unaolegeza hili. Lebo ya job huamua ni pool gani itachukua kazi, na lebo iliyopangishwa inamaanisha mashine nje ya mzingo wako kwa uendeshaji wote.
Kwa hiyo ufikivu wa kibinafsi lazima utokane na kitu unachomiliki. Runner iliyowekwa pale mtandao unapoishia tayari, au handaki inayoishi job moja. Sehemu iliyobaki ya makala inahusu kulipia kimoja wapo kwa makusudi badala ya kugundua bili kwenye uzalishaji.
Amua kwa mzunguko wa uendeshaji, si kwa mazoea
Tumia runner yako mwenyewe ndani ya VPC au mtandao wa ofisi wakati deploy zinafika mara kadhaa kwa siku, wakati job inagusa zaidi ya port moja ya kibinafsi, au wakati timu ya jukwaa tayari inashughulikia patching na mzunguko wa vitambulisho. Job kwenye mashine hiyo hutatua na kupitisha njia kama host nyingine yoyote nyuma ya firewall. Kazi ya mtandao hufanyika mara moja, wakati wa usakinishaji, si kwa kila uendeshaji.
Jenga handaki ndani ya job wakati ufikivu ni wa mara kwa mara na hutaki agent ya maisha marefu inayoshikilia kitambulisho kuingia kwenye mtandao wako. Job inakuwa client wake wa mtandao kwa dakika chache na haiachi kitu, ambayo mara nyingi ndiyo lengo lote.
Kadiria gharama ya handaki kabla ya kuichagua. Kila uendeshaji hulipa kwa uundaji wa profile, kuanzisha client, utayari na uvunjaji. Handaki inayoinuka lakini haithibitishwi kamwe huzalisha deploy inayoshindwa katikati na kuacha hali ya kibinafsi katika umbo ambalo hakuna aliyepanga. Jaribio la mara ya pili baada ya hapo mara chache huwa safi, na kushindwa kwa pili kwa kawaida huwekwa kwenye toleo la client.
Kuandika profile ili hatua isiweze kukatizwa
Weka profiles na vitambulisho nje ya repository na uzitengeneze kutoka secret katika hatua inayohitaji. Mpangilio huamua kama job itaendelea kuishi: faili iliyoundwa chini ya sudo ni mali ya root, na shell ya hatua isiyo na ruhusa haiwezi kuandika ndani yake.
- 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"Maelezo yote mawili katika block hiyo ni kwa ajili ya hatua zijazo. Kwa umask 077 profile inatua katika modi 0600 na ni mali ya mtumiaji wa runner, sudo bado inaweza kuisoma, na client huandika log yake kwenye faili ambayo runner tayari inamiliki, kwa hiyo mzunguko wa utayari unaweza kusoma log hiyo bila sudo ya pili. --writepid hunakili PID ambayo uvunjaji utailenga.
Profile inayojithibitisha kwa cheti cha client inahitaji ufunguo wake kuandikwa kwa namna hiyo hiyo, na profile ya static-challenge inahitaji modi ya auth inayolingana. Profiles zinazosukuma chaguo za DNS zinahitaji openvpn-systemd-resolved kwenye Ubuntu na Debian, kwa sababu kusukuma peke yake hakubadilishi kitu kwenye taswira ya msingi.
Utayari ni uchunguzi, si mapumziko
Sleep isiyobadilika hudumu hadi pale concentrator inapopungua kasi, na kisha hatua ya deploy inaendeshwa kabla njia haijakuwepo. Kushindwa huja baadaye ndani ya chombo cha deploy kama timeout kwa host ya kibinafsi, jambo ambalo halisemi kitu kuhusu handaki.
- 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 1Mzunguko huangalia mambo mawili kwa sababu yoyote yao inaweza kuwa nusu iliyovunjika. getent hosts huthibitisha kwamba resolver iliyosukumwa inajibu kwa jina hilo, na kufunguliwa kwa socket huthibitisha kwamba kuna kitu kinasikiliza kwenye port ambayo deploy itatumia; profile yenye njia pekee inahitaji anwani halisi na mstari wa getent kufutwa.
Mzunguko unapoisha muda, log ndiyo kitu pekee kinachotenganisha hitilafu tatu tofauti: cheti kilichokataliwa, modi ya auth isiyo sahihi na njia ambayo haikufika kamwe. Kuchuja kabla ya tail huweka matokeo hayo mafupi vya kutosha kusomwa wakati job bado inashindwa. Soma hitilafu ya kwanza badala ya mstari wa mwisho, kwa sababu client isiyoweza kujithibitisha hujirudia hadi mzunguko ukate tamaa. ip -4 route show dev tun0 hujibu swali rahisi zaidi la kama njia ilisukumwa kabisa, na inagharimu mstari mmoja ndani ya mzunguko huo huo.
Uvunjaji na swali la artifact
Funga job kwa hatua inayolindwa na if: always() na inayotekeleza sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" na hakuna kingine. Kwenye runner yako mwenyewe inayoshirikiwa kamwe usiue kwa jina la mchakato: job nyingine inaweza kumiliki client yenye binary sawa na hoja zinazofanana. Kushindwa huja kwa job iliyoendeshwa ya pili, na log yake inaelekeza kwenye workflow ambayo haikufanya kosa.
Ulinzi ni muhimu kwa sababu deploy iliyoshindwa bado huacha handaki hai. Bila always() hatua ya usafishaji hurukwa wakati hasa inahitajika, na uendeshaji unaofuata unaanza dhidi ya client ambayo tayari imeunganishwa.
Swali moja linabaki kabla ya kupitisha mojawapo ya miundo: je, hatua ya build inahitaji njia ya kibinafsi kabisa? Agent ya deployment ambayo tayari imekaa ndani ya mtandao inaweza kuvuta artifact iliyoidhinishwa, na hilo huiweka build za kawaida mbali na njia ya kibinafsi. Jobs chache zinazoshikilia handaki humaanisha sehemu chache ambapo njia ya zamani inaweza kujificha.