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 వెలుపల ఉంచి, అవి కావాల్సిన దశలోనే secrets నుండి తయారు చేయండి. క్రమం job బతుకుతుందా అని నిర్ణయిస్తుంది: sudo కింద సృష్టించిన ఫైల్ root కి చెందుతుంది, దశ యొక్క అధికారం లేని 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, పోలిన argument లు ఉన్న client ఉండవచ్చు. అప్పుడు వైఫల్యం రెండోసారి నడిచిన job పై పడుతుంది, దాని log ఏమీ తప్పు చేయని workflow వైపు చూపుతుంది.
రక్షణ ముఖ్యం ఎందుకంటే విఫలమైన deploy అయినా సజీవ టన్నెల్ ను వదిలిస్తుంది. always() లేకుండా శుభ్రపరిచే దశ అవసరమైన సరైన సమయంలోనే దాటవేయబడుతుంది, తదుపరి రన్ ఇప్పటికే కనెక్ట్ అయిన client కు ఎదురుగా ప్రారంభమవుతుంది.
ఏదైనా డిజైన్ స్వీకరించే ముందు ఒక ప్రశ్న మిగిలి ఉంది: build దశకు నిజంగా ప్రైవేట్ రూట్ కావాలా? ఇప్పటికే నెట్వర్క్ లోపల కూర్చున్న deployment agent ఆమోదించిన artifact ను లాగగలదు, ఇది సాధారణ builds ను ప్రైవేట్ మార్గానికి దూరంగా ఉంచుతుంది. తక్కువ job టన్నెల్ పట్టుకుంటే అంటే పాత రూట్ దాక్కోగల తక్కువ చోట్లు.