GitOps คืออะไร และช่วยดูแลระบบได้อย่างไร
GitOps ใช้ Git เก็บสภาพที่ระบบควรเป็น แล้วให้ software คอยเทียบและปรับระบบจริง ชวนดูผ่านการอัปเดต service ว่าช่วยอะไร และเมื่อไรทีมเล็กควรเริ่มใช้
ไฟล์ configuration ใน Git บอกว่า service ควรใช้เวอร์ชันหนึ่ง แต่เครื่องที่กำลังทำงานอยู่อาจใช้คนละเวอร์ชัน แล้วเราจะเชื่อฝั่งไหนดีครับ
เก็บไฟล์ไว้ใน Git ช่วยให้ดูประวัติได้ แต่หลังจากมีคนเข้าไปแก้ที่เครื่องโดยตรง ไฟล์กับระบบจริงก็เริ่มแยกทางกันได้ GitOps เข้ามาช่วยเชื่อมสองฝั่งนี้ โดยให้ software คอยอ่านสภาพที่เราต้องการจาก Git เทียบกับของที่กำลังทำงาน และพยายามปรับให้ตรงกัน
ลองตามการอัปเดตเว็บหนึ่งตัวไปด้วยกันครับ
จากไฟล์ที่เก็บไว้ ไปเป็นสภาพที่ต้องการ
สมมติเรามีเว็บภายในบน Kubernetes ซึ่งเป็นระบบจัดการ application ที่รันใน container ไฟล์ที่อธิบายเว็บนี้ระบุว่าจะใช้ container image เวอร์ชัน 1.4 และรันสองชุด เมื่อจะอัปเดตเป็น 1.5 เราแก้ไฟล์ใน repository แล้วเปิด Pull Request ให้คนอื่นเห็นสิ่งที่จะเปลี่ยนก่อนรวมเข้า branch ที่ใช้ดูแลระบบ
ไฟล์แบบนี้บอกผลที่ต้องการ เช่น “ให้เว็บรันสองชุดด้วย image นี้” แทนการบอกให้คนทำคำสั่งทีละขั้น ลักษณะนี้เรียกว่า declarative ส่วนผลที่ระบุไว้เรียกว่า desired state หรือสภาพที่ระบบควรเป็น
OpenGitOps อธิบายหลักการ ว่าสภาพที่ต้องการต้องเขียนแบบ declarative เก็บเป็นเวอร์ชันที่รักษาประวัติไว้ ให้ software ดึงมาอัตโนมัติ และคอยเทียบกับระบบจริงอย่างต่อเนื่อง กระบวนการเทียบแล้วพยายามปรับให้ตรงกันนี้เรียกว่า reconciliation
ดังนั้น การเอาไฟล์ขึ้น Git แล้วให้คน SSH ไปสั่ง deploy ยังมีประโยชน์ แต่ยังขาดวงจรที่คอยดูของจริง ส่วน script ที่ทำงานครั้งเดียวหลัง push ก็อาจไม่รู้ว่าพรุ่งนี้มีคนแก้ค่าที่เครื่องไปแล้ว
อัปเดตเว็บหนึ่งครั้ง งานเดินอย่างไร

งาน build และ test ยังอยู่ในฝั่ง CI หรือ Continuous Integration ส่วน GitOps ช่วยจัดการว่าระบบปลายทางควรนำ image ไหนไปทำงาน
สำหรับตัวอย่างนี้ CI สร้าง image และส่งเข้า registry ซึ่งเป็นที่เก็บ container image จากนั้นทีมเสนอแก้ configuration ให้ชี้ไปยัง image ใหม่ เมื่อ review ผ่านและรวมเข้า branch ที่ติดตามอยู่ ตัวควบคุมฝั่งระบบปลายทางจึงอ่านการเปลี่ยนแปลงแล้วดำเนินการตามนโยบายที่ตั้งไว้
เครื่องมืออย่าง Argo CD และ Flux รองรับงานลักษณะนี้บน Kubernetes ตัวควบคุมหรือ controller มีหน้าที่ติดตาม configuration และจัดการทรัพยากรที่อยู่ในขอบเขตของมัน GitOps เป็นแนวทาง ส่วนเครื่องมือเป็นตัวทำให้แนวทางนั้นเกิดขึ้นจริง
คน review เห็นว่าเปลี่ยนจาก 1.4 เป็น 1.5 พร้อมเหตุผล คนรับช่วงย้อนดูได้ว่าเปลี่ยนอะไร โดยต้องชัดว่าไฟล์ใดมีผลกับระบบทดสอบหรือระบบที่คนใช้จริง ผมชอบประโยชน์เรื่องตามงานต่อได้มากกว่าการวัดแค่ว่า deploy เร็วขึ้นกี่นาที
ถ้ามีคนแก้ที่ระบบจริงอีกครั้ง

หลังอัปเดต สมมติมีคนเปลี่ยนจำนวนชุดที่รันจากสองเป็นสามโดยตรง ความต่างนี้เรียกว่า configuration drift ตัวควบคุมสามารถตรวจพบว่าไฟล์กับของจริงไม่ตรงกัน แต่จะปรับกลับเมื่อไรต้องดูนโยบายของเครื่องมือด้วย
ตัวอย่างเช่น Argo CD แยกการตั้งค่า automatic sync, self-heal และ pruning การเปิด automatic sync เพื่อรับการเปลี่ยนจาก Git ไม่ได้หมายความว่าจะเปิด self-heal เพื่อแก้การเปลี่ยนที่ระบบจริง หรือ pruning เพื่อลบทรัพยากรที่หายจาก Git ไปด้วยทั้งหมด
ถ้าเปิด self-heal การแก้ด้วยมืออาจถูกปรับกลับ ช่วงแก้ฉุกเฉินจึงต้องรู้วิธีพัก controller และนำสิ่งที่ต้องการเก็บไว้กลับเข้า Git ภายหลัง เพื่อไม่ให้แก้สวนกัน
ส่วนการลบไฟล์ออกจาก repository ก็ต้องคิดให้ดีว่าอยากให้ลบทรัพยากรจริงด้วยหรือไม่ ผมจะยังไม่เปิดการลบอัตโนมัติครอบคลุมทุกอย่างตั้งแต่วันแรก โดยเฉพาะของที่ผูกกับข้อมูล ก่อนเห็นว่าทีมอ่านผลกระทบของการเปลี่ยนได้ครบ
ถ้าอนุมัติค่าผิด controller ก็สามารถนำค่าผิดไปใช้ได้ สิทธิ์แก้ branch ที่ใช้ deploy และการ review จึงมีผลกับระบบจริงโดยตรง
ย้อนเวอร์ชันได้ แต่ต้องรู้ว่ากำลังย้อนอะไร
ถ้าเว็บ 1.5 มีปัญหา เราอาจสร้าง commit ใหม่ที่คืน configuration ไปอ้าง image 1.4 แล้วให้ controller นำสภาพนั้นกลับไปใช้ตามนโยบายเดิม วิธีนี้ทำให้ประวัติยังเห็นทั้งการอัปเดตและการแก้กลับ โดยต้องมั่นใจว่า image เก่ายังมีและใช้กับข้อมูลปัจจุบันได้
แต่ถ้า 1.5 เปลี่ยนโครงสร้างฐานข้อมูลไปแล้ว การคืน image ไม่ได้คืนข้อมูลตามไปด้วย ต้องพิจารณาความเข้ากันได้และแผนกู้ข้อมูลแยกกัน Git เก็บประวัติ configuration ไม่ได้สำรองฐานข้อมูลของเว็บให้เรา
หลังระบบตรงกับ Git แล้ว ควรลองเปิดเว็บหรือทดสอบฟังก์ชันที่ทีมใช้ด้วย สถานะตรงกันตอบเรื่อง configuration ส่วนเว็บทำงานถูกต้องไหมต้องตรวจ application และ monitoring เพิ่มเติม
อีกอย่างที่ควรแยกออกจากไฟล์ทั่วไปคือรหัสผ่านและ API token อย่าใส่ค่าลับแบบอ่านได้ลง Git เพียงเพราะ repository เป็น private แม้แต่ Kubernetes Secret ที่เก็บค่าเป็น base64 ก็ไม่ได้เข้ารหัสให้ ต้องเลือกวิธีจัดการ secret เช่นแหล่งเก็บภายนอกหรือไฟล์เข้ารหัสที่แยกการดูแลกุญแจให้เหมาะกับระบบ
ทีมเล็กหรือ Homelab ควรเริ่มตรงไหน

ถ้ามี Kubernetes อยู่แล้ว และเริ่มเสียเวลากับการตามว่าแต่ละ environment ใช้ค่าอะไร ผมจะเลือกเว็บทดลองหนึ่งตัวที่ไม่มีข้อมูลสำคัญมาเริ่ม ให้ configuration ผ่าน Git แล้วลองอัปเดตเวอร์ชัน ดูความต่าง และคืนเวอร์ชันเดิมให้ครบก่อนขยายไป service อื่น
ผลที่อยากเห็นคือคนรับช่วงรู้ว่าควรใช้เวอร์ชันไหน ตรวจของจริงได้ และรู้วิธีรับมือเมื่อ controller ติดต่อ Git ไม่ได้
สำหรับ homelab ที่มี Docker Compose บนเครื่องเดียว การเก็บไฟล์ใน Git และมีวิธีนำขึ้นกับกู้กลับที่ชัดเจนอาจเพียงพอแล้ว ผมจะไม่เพิ่ม Kubernetes เพื่อให้ได้ใช้ GitOps อย่างเดียว เพราะต้องดูแลทั้งระบบจัดการ container และ controller เพิ่ม ทั้งที่ปัญหาเดิมอาจแก้ได้ด้วย workflow เล็กกว่า
หลักการ GitOps ใช้กับระบบอื่นได้เมื่อมีเครื่องมือรองรับวงจรนี้ แต่ถ้ายังไม่รู้ว่า configuration ที่ควรใช้อยู่ไหน เริ่มรวบรวมเข้า Git ก่อนครับ แล้วดูว่างานที่ยังต้องตามแก้ด้วยมือคุ้มกับการเพิ่ม controller หรือยัง