VPN ของ CI runner: tunnel อยู่ยาวกว่า build หรือไม่?
CI runner ที่ใช้ร่วมกันเก็บเส้นทางและโปรเซสไว้ระหว่างงาน วางแผนสถานะของ VPN ก่อน ระหว่าง และหลังงาน และล้างเฉพาะการเชื่อมต่อที่งานเป็นเจ้าของ
งาน deploy เชื่อมต่อ คัดลอก artifact ของตน และรายงานความสำเร็จ tunnel ที่มันเปิดอาจยังทำงานอยู่เมื่องานถัดไปเริ่ม และเส้นทางที่มันเปลี่ยนเป็นของ host ทั้งเครื่อง ผลลัพธ์ของ build อธิบายคำสั่ง ไม่ใช่สถานะที่มันทิ้งไว้ มอง VPN เป็นทรัพยากรที่มีอายุการใช้งาน ไม่ใช่บรรทัดเดียวตอนเริ่มสเตจ
มีอะไรอื่นทำงานบน host นี้
โหนด Jenkins รัน executor ได้หลายตัวพร้อมกัน และงานที่เปลี่ยนเส้นทางของ host การตั้งค่า resolver หรือการเชื่อมต่อระดับระบบจะเปลี่ยนให้ทุกคนด้วย ว่างานอื่นจะสังเกตเห็นหรือไม่ขึ้นอยู่กับนโยบายเส้นทางและการกรอง ไม่ใช่กฎทั่วไปเกี่ยวกับ VPN การเข้าถึง repository การเข้าถึง artifact และช่องทางควบคุมเป็นข้อกำหนดแยกกันที่ runner ยังต้องมี เพิ่มสิ่งเหล่านั้นลงในรายการปลายทางของ deploy ก่อนเลือก tunnel แบบเต็ม
ถ้าช่องทางควบคุมต้องผ่าน tunnel การออกแบบต้องระบุไว้อย่างตั้งใจ การค้นพบเรื่องนี้ระหว่าง rollback ไม่ใช่แผน เขียนสองรายการลงไป: งานต้องเข้าถึงอะไรแบบส่วนตัว และ runner ต้องเข้าถึงอะไรไม่ว่าจะเกิดอะไร
งานนี้ต้องการการเข้าถึงแบบส่วนตัวเลยหรือไม่
ถามก่อนเพิ่ม tunnel ว่าสเตจ build ต้องการมันหรือไม่ เอเจนต์ deploy แบบส่วนตัวดึง artifact ที่อนุมัติแล้วและทำ deploy ได้ ซึ่งทำให้สเตจ build ทั่วไปอยู่นอกเครือข่ายส่วนตัว การแยกเช่นนั้นมักถูกกว่าการสอนทุกขั้นตอนของ build ให้วิ่งผ่าน tunnel
เลือกขอบเขตจากขั้นตอนการทำงาน ไม่ใช่จากความเคยชิน ถ้าคำตอบคือไม่ ส่วนที่เหลือของหน้านี้ไม่จำเป็น และนั่นคือผลลัพธ์ที่ดีที่สุดที่หาได้
สถานะที่งานถัดไปสืบทอด
อธิบายว่าอะไรควรเป็นจริงก่อนงาน ขณะที่งานมีการเข้าถึงแบบส่วนตัว และหลังจากงานจบ รวมถึงการยกเลิก สถานะสุดท้ายคือสิ่งที่มักถูกปล่อยให้เป็นนัยบ่อยที่สุด และเป็นสิ่งที่งานถัดไปสืบทอด เขียนมันไว้ข้าง pipeline แทนที่จะปล่อยไว้ในความจำของใครคนหนึ่ง
| Moment | What proves it | What leaks if it is skipped |
|---|---|---|
| Job start: pre-flight route check | The route table shows no tunnel from an earlier job, and the profile list is empty | A stale route sends deployment traffic into a dead tunnel |
| Job end: disconnect and shred | The profile is down and the temporary key file is gone | The next job inherits an open tunnel and a usable credential |
| Cancelled job: reboot or disposal | The host is replaced or rebooted before the next job starts | A killed process leaves the tunnel up with no owner |
เอเจนต์เฉพาะหรืองานเดียวใช้ทำให้บังคับขอบเขตเหล่านั้นได้ง่ายขึ้น container หรือ namespace ช่วยได้ก็ต่อเมื่อการจัดเครือข่ายและสิทธิ์ของมันแยกการเปลี่ยนแปลงได้จริง
หยุดการเชื่อมต่อ ไม่ใช่โปรแกรม
ใช้ เส้นทางการจบงานของ pipeline เพื่อปิดการเชื่อมต่อที่งานนี้เริ่มไว้และลบข้อมูลรับรองชั่วคราวของมัน อย่าจับคู่โปรเซสด้วยชื่อโปรแกรมบน host ที่งานอื่นใช้ ให้หยุดการเชื่อมต่อที่เฉพาะเจาะจงแทน คำสั่งสองข้อด้านล่างคือการล้างทั้งหมด และทั้งสองไม่ขึ้นกับการหาโปรเซส
vpn-cli disconnect --profile "$PROFILE"
rm -f "$RUNNER_TEMP/client.key"
การจบงานไม่ใช่การแยก: runner ที่ตายยังคงเก็บ tunnel ที่มันเปิดไว้ และโปรเซสที่ถูกบังคับหยุดจะข้ามบล็อกนั้นไปทั้งหมด นั่นคือเหตุผลที่คำสั่งล้างเพียงอย่างเดียวเป็นดีไซน์ทั้งหมดไม่ได้ นี่คือวิธีที่มันล้มเหลวในทางปฏิบัติ: งาน deploy ถูกยกเลิกที่ขั้นตอนคัดลอก บล็อกจบงานไม่เคยทำงาน และงานถัดไปบน host เดียวกันเริ่มด้วย tunnel ที่ยังมีชีวิตและเส้นทางที่ชี้ไปยังเครือข่ายที่มันไปไม่ถึง ความล้มเหลวดูเหมือนปัญหา 'DNS' ใน build ถัดไป หลายชั่วโมงหลังจากงานที่ก่อเรื่องจบลง
บันทึกชื่อ profile และพาธของข้อมูลรับรองลงในเอาต์พุตของงาน คำสั่งยกเลิกการเชื่อมต่อเปล่า ๆ ที่ไม่มีตัวระบุนั้นตรวจสอบย้อนหลังได้ยาก บรรทัด log ก็เป็นสิ่งที่พิสูจน์ว่าบล็อกนั้นทำงานเมื่อการสอบสวนในภายหลังถามถึง
ให้ host ที่ไม่มีใครอื่นใช้แก่งาน
โครงสร้างพื้นฐานแบบใช้ครั้งเดียวกำจัดปัญหาการสืบทอดแทนที่จะจัดการมัน เอเจนต์ใหม่ต่องานเริ่มโดยไม่มีเส้นทาง ไม่มี profile และไม่มีข้อมูลรับรองของใครอื่น และการทำลายมันล้างสิ่งที่งานทิ้งไว้ นั่นมีต้นทุนต่อ build สูงกว่า และเป็นราคาที่ซื่อตรงของขอบเขตที่ไม่ขึ้นกับโค้ดล้างข้อมูล สำหรับงานที่แตะเครือข่ายโปรดักชัน มักเป็นทางเลือกที่ถูกกว่าเมื่อนับจำนวนเหตุการณ์
ในที่ที่ runner ที่ใช้ร่วมกันต้องอยู่ต่อ ทดสอบความล้มเหลวและการยกเลิกอย่างละเอียดเท่ากับการคัดลอกที่สำเร็จ การทดสอบควรแสดงว่างานถัดไปจะเห็นอะไรถ้างานนี้ถูกยกเลิกกลางทาง งานจบเมื่อการเข้าถึงและสถานะชั่วคราวของมันสิ้นสุดลง ไม่ใช่เมื่อคำสั่งคัดลอกคืนค่าศูนย์