GitHub Actions તમારા VPN સુધી પહોંચતું નથી: તમારું runner કે ટનલ
હોસ્ટ કરેલું runner તમારા નેટવર્કની બહારનું નવું VM છે. કાં તો એ નેટવર્કમાં runner મૂકો, અથવા jobમાંથી ટનલ બનાવો અને સાચા રૂટની રાહ જુઓ.
તમારું deploy પગલું કોઈ આંતરિક hostname પર અટકી જાય છે, જ્યારે એ જ આદેશ તમારા લેપટોપથી તરત જવાબ આપે છે, અને બંને મશીન પર client build એકસરખું છે. job GitHub-હોસ્ટ કરેલા runner પર ચાલી રહ્યું છે: એ જ એક job માટે GitHubના ક્લાઉડમાં બનાવેલી વર્ચ્યુઅલ મશીન, તમારી ખાનગી સરનામા જગ્યામાં કોઈ રૂટ નથી, આંતરિક ઝોન માટે કોઈ resolver નોંધ નથી અને ખાનગી endpoint સ્વીકારશે એવું કોઈ પ્રમાણપત્ર નથી. આ મર્યાદામાં ફક્ત બે રચનાઓ બંધ બેસે છે, અને workflow ફરી ન બનાવ્યા વગર એમાંની એક પણ પછી ચાલુ કરી શકાતી નથી. YAMLની પહેલી લાઇન પહેલાં એમાંથી પસંદ કરો, કારણ કે પછીનું સ્થળાંતર પહેલા પ્રયાસ કરતાં વધુ ખર્ચાળ પડે છે.
પસંદગી એ runner વચ્ચે છે જે ત્યાં મૂકાય છે જ્યાં નેટવર્ક પહેલેથી પૂરું થાય છે, અને એ ટનલ વચ્ચે જે એક job જેટલી ટકે છે. બંને વર્ષોથી production deploy ઉપાડે છે, અને જુદી જુદી રીતે નિષ્ફળ જાય છે.
સીમા ખરેખર ક્યાં છે
તમે લેપટોપ પર જે કંઈ ઇન્સ્ટોલ કરો છો તે લેપટોપ પર જ અટકે છે, અને job દરમિયાન જે ઇન્સ્ટોલ કરો છો તે runner સાથે અદૃશ્ય થાય છે. client રન વચ્ચે જોડાયેલો રહી શકે એવું કોઈ કાયમી નેટવર્ક namespace નથી, એટલે દરેક રન એ જ અગમ્ય સ્થિતિથી શરૂ થાય છે. Azure આ સીમા Microsoft-હોસ્ટ કરેલા agents માટે નોંધે છે, જ્યાં ખાનગી નેટવર્કમાં VPN અને ExpressRoute જોડાણો સમર્થિત નથી, અને GitHub-હોસ્ટ કરેલા runners એ જ પ્રકારની મર્યાદા ઉપાડે છે, અલગ કોઈ પદ્ધતિ નહીં. આને ઉત્પાદનનો ગુણ તરીકે વાંચો, ટાળવાના દોષ તરીકે નહીં.
repositoryનું કોઈ સેટિંગ આને ઢીલું કરતું નથી. jobનું લેબલ નક્કી કરે છે કયો pool કામ લેશે, અને હોસ્ટ કરેલું લેબલ એટલે આખા રન માટે તમારા પરિઘની બહારનું મશીન.
ખાનગી પહોંચ એટલે તમારી માલિકીની કોઈ વસ્તુમાંથી આવવી જોઈએ. runner ત્યાં મૂકેલો જ્યાં નેટવર્ક પહેલેથી પૂરું થાય છે, અથવા ટનલ જે એક job જીવે છે. બાકીનો લેખ આ બેમાંથી એક માટે જાણી જોઈને ચૂકવવા વિશે છે, productionમાં બિલ મળવાને બદલે.
રનની આવૃત્તિ પ્રમાણે નક્કી કરો, ઓળખ પ્રમાણે નહીં
જ્યારે deploy દિવસમાં ઘણી વાર આવે, જ્યારે job એક કરતાં વધુ ખાનગી પોર્ટને સ્પર્શે, અથવા જ્યારે પ્લેટફોર્મ ટીમ પહેલેથી patching અને credential rotation સંભાળે, ત્યારે VPC કે ઓફિસ નેટવર્કમાં પોતાનું runner વાપરો. એ મશીન પર job બીજા કોઈ પણ hostની જેમ firewall પાછળ resolve અને route કરે છે. નેટવર્કનું કામ એક વાર, ઇન્સ્ટોલ વખતે થાય છે, દરેક રનમાં નહીં.
જ્યારે પ્રવેશ ક્યારેક જ હોય અને તમે તમારા નેટવર્કમાં credential રાખતું લાંબુ જીવતું agent ન ઇચ્છો, ત્યારે ટનલ jobની અંદર બનાવો. job થોડી મિનિટ માટે પોતાનું નેટવર્ક client બને છે અને પાછળ કંઈ રાખતું નથી, જે ઘણી વાર આખો હેતુ હોય છે.
ટનલ પસંદ કરતા પહેલાં તેનો ખર્ચ અંદાજો. દરેક રન profile બનાવવા, client શરૂ કરવા, તૈયારી અને તોડી પાડવાની કિંમત આપે છે. જે ટનલ ઉપડે છે પણ કદી ચકાસાતી નથી, તે એવું deploy બનાવે છે જે અડધે રસ્તે નિષ્ફળ જાય અને ખાનગી સ્થિતિ એવા આકારમાં છોડે જેની કોઈએ યોજના નહોતી કરી. પછીનો ફરી પ્રયાસ ભાગ્યે જ સ્વચ્છ હોય છે, અને બીજી નિષ્ફળતા સામાન્ય રીતે client આવૃત્તિ પર ઢોળાય છે.
profile એવી રીતે લખવું કે પગલું અટકી ન શકે
profiles અને credentials repositoryની બહાર રાખો અને જે stepને તેની જરૂર હોય ત્યાં જ secretsમાંથી તે બનાવો. ક્રમ નક્કી કરે છે કે job ટકશે કે નહીં: sudo હેઠળ બનેલી ફાઇલ rootની હોય છે, અને stepનો વિશેષાધિકાર વગરનો shell પછી તેમાં લખી શકતો નથી.
- 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"એ બ્લોકની બંને વિગતો પછીના પગલાં માટે છે. umask 077 સાથે profile 0600 મોડમાં runner વપરાશકર્તાની માલિકીમાં આવે છે, sudo હજી વાંચી શકે છે, અને client પોતાનો log એવી ફાઇલમાં લખે છે જેનો માલિક runner પહેલેથી છે, એટલે તૈયારીનો લૂપ બીજા sudo વગર એ log વાંચી શકે છે. --writepid એ PID નોંધે છે જેને તોડી પાડવું નિશાન બનાવશે.
client પ્રમાણપત્રથી પ્રમાણિત થતી profileને તેની કી એ જ રીતે લખાયેલી જોઈએ, અને static-challenge profileને મેળ ખાતો auth મોડ જોઈએ. DNS વિકલ્પો push કરતી profilesને Ubuntu અને Debian પર openvpn-systemd-resolved જોઈએ, કારણ કે એકલું push બેઝ ઇમેજ પર કંઈ બદલતું નથી.
તૈયારી એ તપાસ છે, વિરામ નહીં
નિશ્ચિત sleep ત્યાં સુધી જ ટકે છે જ્યાં સુધી concentrator ધીમો ન પડે, અને પછી deploy પગલું રૂટ બનવાના પહેલાં ચાલી જાય છે. નિષ્ફળતા પછી deploy સાધનની અંદર ખાનગી host સામે timeout તરીકે દેખાય છે, જે ટનલ વિશે કંઈ કહેતું નથી.
- 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લૂપ બે વસ્તુઓ જુએ છે કારણ કે એમાંથી કોઈ પણ તૂટેલો અડધો ભાગ હોઈ શકે. getent hosts સાબિત કરે છે કે push કરેલો resolver એ નામ માટે જવાબ આપે છે, અને socket ખૂલવું સાબિત કરે છે કે deploy જે પોર્ટ વાપરશે ત્યાં કંઈક સાંભળે છે; ફક્ત રૂટવાળી profileને શબ્દશઃ સરનામું અને ભૂંસાયેલી getent લાઇન જોઈએ.
લૂપ પૂરો થાય ત્યારે, log એ જ એકમાત્ર વસ્તુ છે જે ત્રણ અલગ ખામીઓને છૂટી પાડે છે: નકારેલું પ્રમાણપત્ર, ખોટો auth મોડ અને એવો રૂટ જે કદી આવ્યો નહીં. tail પહેલાં ફિલ્ટર કરવું એ આઉટપુટને job હજી નિષ્ફળ જતું હોય ત્યારે વાંચી શકાય એટલું ટૂંકું રાખે છે. પહેલી ભૂલ વાંચો, છેલ્લી લાઇન નહીં, કારણ કે જે client પ્રમાણિત થઈ શકતું નથી તે લૂપ હાર ન માને ત્યાં સુધી પોતાને પુનરાવર્તિત કરે છે. ip -4 route show dev tun0 એ સહેલા સવાલનો જવાબ આપે છે કે રૂટ push થયો હતો કે નહીં, અને એ જ લૂપમાં એક લાઇનનો ખર્ચ છે.
તોડી પાડવું અને artifactનો સવાલ
jobને એવા પગલાથી બંધ કરો જે if: always() દ્વારા સુરક્ષિત હોય અને sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" તથા બીજું કંઈ ન ચલાવે. વહેંચાયેલા પોતાના runner પર કદી પ્રક્રિયાના નામ પર મારશો નહીં: બીજા job પાસે એ જ binary અને મળતા આવતા આર્ગ્યુમેન્ટવાળું client હોઈ શકે. પછી નિષ્ફળતા બીજા ક્રમે ચાલેલા job પર પડે છે, અને તેનો log કંઈ ખોટું ન કરેલા workflow તરફ ઇશારો કરે છે.
સુરક્ષા મહત્ત્વની છે કારણ કે નિષ્ફળ deploy તોય જીવતી ટનલ છોડે છે. always() વગર સફાઈનું પગલું બરાબર ત્યારે જ છોડી દેવાય છે જ્યારે તેની જરૂર હોય, અને આગલું રન પહેલેથી જોડાયેલા client સામે શરૂ થાય છે.
કોઈ પણ રચના અપનાવતા પહેલાં એક સવાલ બાકી છે: build તબક્કાને ખરેખર ખાનગી રૂટની જરૂર છે? જે deployment agent પહેલેથી નેટવર્કની અંદર બેઠું છે તે મંજૂર artifact ખેંચી શકે છે, જે સામાન્ય buildsને ખાનગી માર્ગથી દૂર રાખે છે. ઓછા job ટનલ ધરાવે એટલે ઓછી જગ્યાઓ જ્યાં જૂનો રૂટ છુપાઈ શકે.