Таны deploy алхам дотоод хост нэр дээр гацаж байхад мөнөөх команд таны зөөврийн компьютерээс шууд хариулдаг бөгөөд хоёр машин дээрх клиент бүтээц ижил байна. Ажил GitHub-ийн байршуулсан раннер дээр ажиллаж байна: яг тэр нэг ажлын төлөө GitHub-ийн үүлэн дотор үүсгэсэн виртуал машин; таны хувийн хаягийн орон зай руу явах зам байхгүй, дотоод бүсийн резолвер бүртгэл байхгүй бөгөөд хувийн эндпойнт хүлээж авах гэрчилгээ ч байхгүй. Энэ хязгаарт зөвхөн хоёр загвар багтах бөгөөд алийг нь ч ажлын урсгалыг дахин бүтээхгүйгээр дараа нь асаах боломжгүй. Эхний YAML мөрийн өмнө сонгоорой, учир нь дараа нүүх нь эхний оролдлогоос илүү үнэтэй.

Сонголт нь сүлжээ аль хэдийн дуусах газарт байрлуулсан раннер болон зөвхөн нэг ажил амьдрах туннелийн хооронд байна. Хоёулаа олон жил production deploy үүрч ирсэн бөгөөд өөр өөр аргаар бүтэлгүйтдэг.

Хил үнэхээр хаана байна

Зөөврийн компьютерт суулгасан бүхэн зөөврийн компьютер дээр зогсдог, ажлын үеэр суулгасан бүхэн раннертай хамт алга болдог. Клиентийг ажиллуулалтын хооронд холбогдож байх байнгын сүлжээний namespace байхгүй тул ажиллуулалт бүр ижил хүрэх боломжгүй төлвөөс эхэлдэг. Azure энэ хилийг Microsoft-ийн байршуулсан агентуудад баримтжуулдаг: хувийн сүлжээ рүү VPN болон ExpressRoute холболт тэнд дэмжигддэггүй, харин GitHub-ийн байршуулсан раннерууд тусдаа механизм биш яг ижил хэлбэрийн хязгаарлалт үүрдэг. Үүнийг бүтээгдэхүүний шинж чанар гэж уншина уу, тойрч гарах ёстой алдаа гэж биш.

Ямар ч repository тохиргоо үүнийг сулруулахгүй. Ажлын шошго аль pool ажлыг авахыг шийддэг, байршуулсан шошго нь бүх ажиллуулалтын турш таны периметрийн гаднах машин гэсэн үг.

Тиймээс хувийн хүртээмж таны эзэмшлийн зүйлээс ирэх ёстой. Сүлжээ аль хэдийн дуусах газарт байрлуулсан раннер, эсвэл нэг ажил амьдрах туннель. Өгүүллийн үлдсэн хэсэг нь production дээр нэхэмжлэх олж мэдэхийн оронд эдгээрийн аль нэгэнд нь санаатайгаар төлөх тухай.

Ажиллуулалтын давтамжаар шийдээрэй, дадал зуршлаар биш

Deploy өдөрт хэд хэдэн удаа ирэх үед, ажил нэгээс олон хувийн порт хүрэх үед, эсвэл платформын баг нөхөөс болон итгэмжлэлийн эргэлтийг аль хэдийн хариуцаж байгаа үед VPC эсвэл оффисын сүлжээний дотор өөрийн раннерийг ашиглаарай. Тэр машин дээрх ажил галт ханын ард байгаа бусад хост шиг нэрийг шийдэж, замыг тодорхойлдог. Сүлжээний ажил суулгах үед нэг удаа хийгддэг, ажиллуулалт бүрт биш.

Хандалт хааяа л байдаг бөгөөд сүлжээнд итгэмжлэл барих урт насалсан агент хэрэггүй бол туннелийг ажлын дотор бариарай. Ажил хэдэн минутын турш өөрийн сүлжээний клиент болж, ардаа юу ч үлдээдэггүй, энэ нь ихэвчлэн бүх зорилго нь байдаг.

Туннелийг сонгохын өмнө зардлыг нь тооцоорой. Ажиллуулалт бүр профайлыг материалчлах, клиент эхлүүлэх, бэлэн байдал, буулгах ажилд төлдөг. Босч байгаа ч хэзээ ч баталгаажуулагдаагүй туннель хагас замд бүтэлгүйтэх deploy үүсгэж, хувийн төлвийг хэн ч төлөвлөөгүй хэлбэрээр үлдээдэг. Дараах дахин оролдлого цэвэр байх нь ховор бөгөөд хоёр дахь бүтэлгүйтлийг ихэвчлэн клиентийн хувилбарт тохдог.

Профайлыг алхам тасрахгүй байхаар бичих

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

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

Бэлэн байдал бол шалгалт, завсарлага биш

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

Давталт дуусахад гурван өөр гэмтлийг ялгадаг цорын ганц зүйл бол лог: татгалзсан гэрчилгээ, буруу auth горим, хэзээ ч ирээгүй зам. tail-ийн өмнө шүүх нь тэр гаралтыг ажил амжилтгүй болсоор байхад уншиж болохоор богино байлгадаг. Сүүлийн мөрийг биш эхний алдааг уншаарай, учир нь баталгаажуулж чадахгүй клиент давталт бууж өгөх хүртэл өөрийгөө давтдаг. ip -4 route show dev tun0 зам ер нь push хийгдсэн эсэх гэсэн энгийн асуултад хариулдаг бөгөөд мөнөөх давталтын дотор нэг мөр болдог.

Буулгалт ба артефактын асуулт

Ажлыг if: always() хамгаалсан, зөвхөн sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" ажиллуулдаг алхмаар хаагаарай. Хамтарсан өөрийн раннер дээр хэзээ ч процессыН нэрээр бүү ал: өөр ажил ижил бинарь болон төстэй аргументтай клиенттэй байж болно. Тэгвэл алдаа хоёрдугаарт ажилласан ажилд буух бөгөөд түүний лог юу ч буруу хийгээгүй ажлын урсгалыг заана.

Хамгаалалт чухал, учир нь бүтэлгүйтсэн deploy амьд туннель үлдээдэг. always() байхгүй бол цэвэрлэх алхам яг хэрэгтэй үед алгасагдаж, дараагийн ажиллуулалт аль хэдийн холбогдсон клиентийн эсрэг эхэлдэг.

Аль нэг загварыг хүлээж авахаас өмнө нэг асуулт үлддэг: бүтээх үе шатанд үнэхээр хувийн зам хэрэгтэй юу? Сүлжээний дотор аль хэдийн суусан deployment агент зөвшөөрөгдсөн артефакт татаж чаддаг бөгөөд энэ нь энгийн бүтээцүүдийг хувийн замаас хол байлгадаг. Туннель барих ажил цөөн байх нь хуучин зам нуугдаж болох газар цөөн гэсэн үг.

Холбоотой нийтлэлүүд