Deploy кадамыңыз ички хост атында илинип турат, ал ошол эле буйрук ноутбукуңуздан дароо жооп берет жана эки машинадагы клиент курулушу бирдей. Жумуш GitHub хостингиндеги раннерде аткарылат: ушул бир жумуш үчүн GitHub булутунда түзүлгөн виртуалдык машина; анын жеке дарек мейкиндигиңизге маршруту жок, ички зона үчүн резолвер жазуусу жок жана жеке endpoint кабыл ала турган сертификат да жок. Бул чектөөгө эки долбоор гана батат жана экөөнү тең кийин жумуш агымын кайра куруу менен гана күйгүзсө болот. Биринчи YAML сабынын алдында тандаңыз, анткени кийин көчүү биринчи аракеттен кымбат.

Тандоо тармак мурун эле бүткөн жерге коюлган раннер менен бир гана жумуш жашаган туннелдин ортосунда. Экөө тең жылдар бою өндүрүштүк деплойлорду көтөрүп келет жана ар башка жол менен ишке ашпай калат.

Чек ара чындыгында кайда

Ноутбукуңузга орноткондун баары ноутбукта токтойт, ал эми жумуш убагында орнотконуңуз раннер менен кошо жоголот. Клиент жүгүртүүлөрдүн ортосунда илинип тура турган туруктуу тармактык мейкиндик жок, ошондуктан ар бир жүгүртүү ошол эле жетүүгө мүмкүн эмес абалдан башталат. Azure бул чекти Microsoft хостингиндеги агенттер үчүн документтештирет: жеке тармактарга VPN жана ExpressRoute байланыштары ал жерде колдоого алынбайт, ал эми GitHub хостингиндеги раннерлер өзүнчө механизм эмес, ушундай эле чектөө формасын алып жүрөт. Муну продукттун касиети деп окуңуз, айланып өтүүчү кемчилик деп эмес.

Эч бир репозиторий жөндөөсү муну бошотпойт. Жумуш белгиси кайсы пул ишти алаарын чечет, ал эми хостингиндеги белги бүт жүгүртүү бою периметриңизден тышкаркы машинаны билдирет.

Ошондуктан жеке жетүү өзүңүзгө таандык нерседен келиши керек. Тармак мурун эле бүткөн жерге коюлган раннер же бир жумуш жашаган туннель. Макаланын калганы өндүрүштө эсеп-кысапты табуунун ордуна ушул экөөнүн бирине атайын төлөө тууралуу.

Жүгүртүү жыштыгы боюнча чечиңиз, адат боюнча эмес

Деплойлор күнүнө бир нече жолу келсе, жумуш бирден ашык жеке портту тийсе же платформа командасы патчтоо жана каттоо маалыматтарын айландырууну өзүнө алса, VPC же кеңсе тармагынын ичинде өз раннериңизди колдонуңуз. Ошол машинадагы жумуш брандмауэрдин артындагы каалаган хост сыяктуу аталышты чечип, маршруттайт. Тармак иши орнотуу убагында бир жолу болот, ар бир жүгүртүүдө эмес.

Жетүү сейрек болсо жана тармагыңызга каттоо маалыматын кармап турган узак өмүрдүү агент керек болбосо, туннелди жумуштун ичинде куруңуз. Жумуш бир нече мүнөт өзүнүн тармактык клиентине айланат жана артында эч нерсе калтырбайт, бул көбүнчө бүт максат.

Туннелди тандоодон мурун анын баасын баалаңыз. Ар бир жүгүртүү профилди материалдаштырууга, клиентти иштетүүгө, даярдыкка жана бузууга төлөйт. Көтөрүлгөн, бирок эч качан текшерилбеген туннель жарым жолдо ишке ашпаган деплой жаратат жана жеке абалды эч ким пландабаган формада калтырат. Кийинки кайталоо сейрек таза болот, ал эми экинчи ийгиликсиздик адатта клиент версиясына жабылат.

Профилди кадам үзүлбөй тургандай жазуу

Профилдерди жана каттоо маалыматтарын репозиторийден тышкары кармаңыз жана аларды керектүү кадамда секреттерден жаратыңыз. Тартип жумуштун аман калаарын чечет: sudo астында түзүлгөн файл rootко таандык, ал эми кадамдын артыкчылыгы жок кабыгы ага мындан ары жаза албайт.

- 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 менен профиль 0600 режиминде раннер колдонуучусунун менчигинде болот, sudo али окуй алат, ал эми клиент журналын раннер мурун эле ээлик кылган файлга жазат, ошондуктан даярдык циклы бул журналды экинчи судосуз окуй алат. --writepid бузуу көздөй турган PIDди жазып коёт.

Клиент сертификаты менен аутентификацияланган профиль өз ачкычын ушундай эле жазылган талап кылат, ал эми static-challenge профилине тиешелүү auth режими керек. DNS опцияларын push кылган профилдерге Ubuntu жана Debianде openvpn-systemd-resolved керек, анткени push өзү базалык сүрөттө эч нерсени өзгөртпөйт.

Даярдык — бул зонд, тыныгуу эмес

Туруктуу sleep концентратор жайлаган учурга чейин гана чыдайт, андан кийин деплой кадамы маршрут пайда боло электе аткарылат. Ката андан кийин деплой куралынын ичинде жеке хостко каршы 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 кылынган резолвер ошол атка жооп берерин далилдейт, socketтин ачылышы деплой колдоно турган портто бирөө угуп турганын далилдейт; маршруту гана бар профилге түз дарек жана өчүрүлгөн getent сабы керек.

Цикл бүткөндө, үч түрдүү бузулууну ажырата турган жалгыз нерсе — журнал: четке кагылган сертификат, туура эмес auth режими жана эч качан келбеген маршрут. tail алдында чыпкалоо бул чыгарылышты жумуш али ийгиликсиз болуп жатканда окууга жарактуудай кыска кармайт. Акыркы сапты эмес, биринчи катаны окуңуз, анткени аутентификациялана албаган клиент цикл багынганга чейин өзүн кайталайт. ip -4 route show dev tun0 маршрут такыр push кылынган-кылынбаганы тууралуу жөнөкөй суроого жооп берет жана ошол эле циклдин ичинде бир сапты ээлейт.

Бузуу жана артефакт суроосу

Жумушту if: always() коргогон жана тек sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" аткарган кадам менен жабыңыз. Жалпы өз раннериңизде эч качан процесстин аты менен өлтүрбөңүз: башка жумушта ошол эле бинар жана окшош аргументтери бар клиент болушу мүмкүн. Анда ката экинчи болуп жүгүргөн жумушка түшөт, анын журналы эч нерсе туура эмес кылбаган жумуш агымын көрсөтөт.

Коргоо маанилүү, анткени ийгиликсиз деплой баары бир тирүү туннель калтырат. always() болбосо, тазалоо кадамы так ал керек болгон учурда өткөрүп жиберилет, ал эми кийинки жүгүртүү мурун эле туташкан клиентке каршы башталат.

Эки долбоордун кайсынысын болбосун кабыл алардан мурун бир суроо калат: куруу баскычына чын эле жеке маршрут керекпи? Тармактын ичинде отурган деплой агенти бекитилген артефактты тартып алат, бул кадимки курууларды жеке жолдон алыс кармайт. Туннель кармаган жумуш канча аз болсо, эски маршрут жашына турган орун да ошончо аз.

Тектеш макалалар