มาลอง Setup Gitops ด้วย ArgoCD + Kustomize กันเถอะ Part 1
สวัสดีครับ บทความนี้จะพูดถึงการ deploy application ด้วย pull model อย่าง Gitops ด้วย Argo CD และ Kustomize จากการลองผิดลองถูกของผมมาสักพักใหญ่ๆ จะเป็นอย่างไรบ้างมารับชมกันเลย
เกริ่นนำ
ในช่วงไม่กี่เดือนก่อนหน้านี้ทางชมรม Thinc. ของเราได้รับ server มาจากคณะวิศวกรรมศาสตร์ จุฬาลงกรณ์มหาวิทยาลัย ซึ่งมี spec ที่เยอะพอสมควรจึงทำให้เราสามารถทำอะไรได้หลายอย่างมากขึ้น
สิ่งที่ผมทำกับ server เครื่องนี้คือการ install k3s และเพื่อให้มันง่ายต่อการ deploy, manage configuration ของ service ต่างๆ และความอยากลองเล่นเองด้วยเลยลองทำ Gitops ที่จะใช้ deploy service ต่างๆใน server ตัวนี้
Prerequisite
เนื่องจากว่าการทำ Gitops จะเป็นหนึ่งในกระบวนการที่มาช่วยในการจัดการ resource ต่างๆด้วย Kubernetes ผู้อ่านจึงควรจะมีความรู้พื้นฐานในการใช้ Kubernetes มาก่อนบ้างเพื่อที่จะง่ายต่อการทำความเข้าใจมากขึ้น
การ Deploy Application
เมื่อคุณเขียน service เสร็จเรียบร้อยแล้วการที่จะส่งไปให้ถึงมือผู้ใช้งาน คุณจำเป็นจะต้อง deploy service ของคุณไป Hosting สักที่นึงเช่น Cloud หรือ Self Host
ซึ่งท่ามาตรฐานที่ชมรม Thinc. ของเราใช้กันบ่อยๆคือ
- build docker image
- push ขึ้นไปเก็บที่ registry สักที่นึง
- เขียน
docker-compose.yaml
มาไฟล์นึงพร้อมกับ setup config ของ proxy เช่น traefik - จากนั้น ssh เข้า VM
- run คำสั่ง
docker compose up
ฟังดูยุ่งยากใช่ไหมล่ะ!! กว่าจะ deploy ได้ต้องมีขั้นตอนอะไรเยอะแยะ!
ในสมัยนี้ชมรมเราจึงเริ่มมีการเขียน CI/CD
ขึ้นมาเพื่อให้ run process ทั้งหมดที่พูดถึงก่อนหน้านี้เพื่อให้มัน automate และลด affort ที่เราจะต้องทำทุกอย่างด้วยตัวเอง
ในตอนนี้เราแค่ push source code ขึ้น git และนั่งรอ CI/CD
run ให้เสร็จก็พอ
ฟังเหมือนดูดีแต่มันยังมีปัญหาอะไรอีกบ้างและแบบนี้เรียกว่า Gitops แล้วยังนะ 🤔
CI/CD คืออะไร
ก่อนที่จะไปพูดถึงเรื่อง GitOps ขอแวะพูดถึงเรื่อง CI/CD
ก่อนเผื่องงกันว่ามันคืออะไรและทำอะไรได้บ้าง
CI/CD
จะถูกแบ่งเป็น 2 ส่วนคือ Continuous Integration (CI) และ Continuous Deployment/Continuous Delivery (CD)
Continuous Integration (CI)
Continuous Integration คือการที่เรานำ code จากทีมมา build รวมเป็นชิ้นเดียวและนำไป test ด้วย unit test หรือ integration test ที่ developer เขียนมาก่อนที่จะ push ไปเก็บไว้ใน container registry เมื่อ test ผ่านเรียบร้อย
บางทีเราจะเรียกส่วน Continuous Integration นี้ว่า Build Pipeline
Continuous Delivery vs Continuous Deployment (CD)
Continuous Deployment คือกระบวนการที่รวบรวม code ของสมาชิกภายในทีมมาทำตาม process ตลอดจนถึงการ deploy to production แบบอัตโนมัติ
Continuous Delivery คือกระบวนการที่รวบรวม code ของสมาชิกภายในทีมมาทำตาม process ให้พร้อมสำหรับการ deploy to production แบบ manual
Push Model vs Pull Model
Push Model
คือการที่เรา apply change จาก Pipeline ซึ่งจำเป็นที่จะต้องนำ credential ของ server เช่น private key ออกมาใส่ไว้ที่ Pipeline ข้างนอกเพื่อที่ CD จะสามารถ login และ apply change ได้
ซึ่งการที่เรา deploy แบบใช้ docker-compose
นับว่าเป็นการ deploy แบบ push model เพราะเราต้องนำ private key มาให้ CD ของเราทำการ connect ไปที่ VM ด้วย ssh key เพื่อ run คำสั่ง docker compose up
ถ้า project มี Git Repository หลาย repository ก็ต้องนำไปใส่ให้ครบทั้งหมดซึ่งเป็นความยุ่งยากในการ manage credential และอาจจะนำมาสู่ปัญหาเรื่อง security
Pull Model
คือการที่เราให้ credential กับ CD ที่ deploy ใน server ของเราแล้ว CD จะเป็นตัวที่ทำการ Pull YAML file จาก Git Repository เมื่อมีการ update content เกิดขึ้นเช่น การเปลี่ยน image tag
สังเกตุได้ว่า Pull Model จะเป็นการนำ credential มาเก็บไว้ที่เดียวคือ CD ที่อยู่ภายใน server ของเราซึ่งสามารถ manage เรื่อง credential ได้ง่ายกว่า Push Model เพราะไม่ต้องนำ credential ไปใส่ในทุก Git Repository เพื่อทำการ deploy จึงทำให้ Pull Model มีความปลอดภัยมากกว่า Push Model
Gitops คืออะไร
Gitops คือการที่คุณนำข้อมูลที่จะใช้ในการ deploy ทุกอย่างของ service มาจากใน Git ซึ่งเราจำเป็นที่จะต้อง commit state ทุกอย่างเข้าไปใน Git Repository ด้วยเช่น image tag หรือ configuration อื่นๆ
Gitops ดีอย่างไร
คุณอาจจะมีคำถามว่าในเมื่อการ deploy ที่ทำปกติมันก็ใช้ได้อยู่แล้วจะไปเปลี่ยนมาใช้ Gitops ทำไม?
- Gitops เป็นการ deploy แบบ “pull model” ซึ่งจะเป็นการดึง configuration YAML จาก Git ทำให้สามารถจัดการ credential ได้ง่ายกว่าและปลอดภัยกว่าแบบ “push model” ที่เราต้องนำ credential ต่างๆไปเพื่อ apply YAML เข้าสู่ kubernetes cluster ของเรา
- เมื่อเกิดปัญหาสามารถ recovery ได้ง่าย (git revert commit)
- การเปลี่ยนแปลงจะมี history ชัดเจนสามารถดูได้จาก git commit ที่ผ่านมา
Argo CD คืออะไร
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Argo CD คือเครื่องมือที่จะมาช่วยในการทำ Continuous Delivery (CD) สำหรับ Kubernetes
ในวงการ Gitops Argo CD เป็นหนึ่งในเครื่องมือที่มีชื่อเสียงมากด้วยการที่ Argo CD สามารถรองรับ template ได้หลากหลายรูปแบบไม่ว่าจะเป็น Kustomize, Jsonnet หรือ Helm Chart เป็นต้น ซึ่งภายในเนื้อหาของบทความนี้เราจะพูดถึงการใช้ Argo CD ร่วมกับ Kustomize
รวมคำศัพท์ที่ควรรู้ใน Argo CD
Application
คือกลุ่ม Resource ของ Kubernetes ที่ถูก defined ด้วย manifest เป็น Custom Resource Definition (CRD) ของ Argo CD
Project
คือกลุ่มของ Application
Sync
คือการที่ทำให้ state ของ Application เป็นไปตาม State ล่าสุดที่ Argo CD Fetch มาได้จาก Git Repository
Refresh
คือการเปรียบเทียบ code ล่าสุดที่อยู่ใน Git กับ State ปัจจุบันของ Application เพื่อดูความแตกต่างและนำไป Sync ในขั้นตอนต่อไป
Argo CD ทำงานอย่างไร
- Argo CD จะทำการ Polling ไปที่ Repository ที่เรา Setup ไว้ทุกๆ 3 นาทีต่อ 1 Application (default setting)
- ทำการเปรียบเทียบ State ว่ามีอะไรที่เปลี่ยนแปลงจากเดิมบ้าง
- ทำการ Sync ในส่วนที่มีการเปลี่ยนแปลงเพื่อทำการ Update State
App of Apps Pattern
การที่เราทำ Gitops เพื่อที่จะลดปัญหาของการ apply YAML โดยตรงแต่ว่าทุกๆครั้งที่เราจะสร้าง Application เพิ่มเราจำเป็นที่จะต้อง apply YAML ไฟล์ด้วยมือมันจึงเป็นหนึ่งในปัญหาที่เกิดขึ้น
Argo CD ได้คิดวิธีการแก้ปัญหาเหล่านี้ด้วย App of Apps Pattern ซึ่งเป็นการที่เราใช้ Application หลักตัวนึงให้ชี้ไปที่ folder ที่เก็บ Templates ของ Application อื่นๆและ Argo CD จะนำ Application ใน folder นี้มา deploy
พูดง่ายๆคือจากที่เราจะต้องมาเขียน YAML แล้ว apply ทุกๆไฟล์เองกลายเป็นว่าทุกครั้งที่เราจะเพิ่ม Application ใหม่ให้เราเขียน YAML และนำไปใส่ใน templates folder ก็พอแล้วที่เหลือ Argo CD จะจัดการ Deploy Application เหล่านี้ให้ด้วยการเช็ค state ที่มีการเปลี่ยนแปลงตามที่พูดถึงก่อนหน้านี้
จาก App of Apps Pattern ทำให้เราจำเป็นที่จะต้อง apply YAML แค่ไฟล์เดียว คือ Application หลักที่จะชี้ไปที่ template folder
แวะขายของนิดนึง มีตัวอย่างอยู่ในบทความหน้านะ อิอิ
Argo CD Best Practice
อ้างอิงมาจาก Official Docs ของ Argo CD สิ่งที่เน้นหลักๆคือ
แยก Config Repository จาก Source Code Repository ของ Service
Using a separate Git repository to hold your kubernetes manifests, keeping the config separate from your application source code, is highly recommended
เหตุผลหลักๆที่ควรต้องแยกกันคือ
- ทำให้ config และ source code แยกกันโดยสมบูรณ์เพื่อเวลาที่คุณทำการแก้ไข manifest ของ k8s จะได้ไม่มีโอกาสไป trigger ให้ CI ของ source code ทำงาน
- Cleaner Audit Log ทำให้สามารถเช็ค history จาก commit ได้ง่ายยิ่งขึ้นเพราะจะไม่มี commit ที่เกี่ยวกับ source code มาปนกับ commit ของ k8s manifest
- Application ของคุณอาจจะประกอบมาจาก service ในหลายๆ repository เช่น microservice ซึ่งมันไม่ make sense ที่จะเก็บทุก manifest ไว้ใน repository เดียว
- เพื่อที่จะสามารถจัดการเรื่อง Access Control ได้ง่ายยิ่งขึ้นโดยดารที่เราแยก repository ออกมาจะทำให้คุณสามารถจำกัดสิทธิในการเข้าถึงของทีมคุณได้
- ถ้าคุณใช้ CI ในการ push change ใส่ manifest อาจจะทำให้เกิด infinite loop ของการ build และ trigger ภายใน repository ได้
สามารถไปอ่าน Best Practice เพิ่มเติมได้ใน Official Docs
Kustomize คืออะไร
Kustomize helps customizing config files in a template free way.
Kustomize provides a number of handy methods like generators to make customization easier.
Kustomize uses patches to introduce environment specific changes on an already existing standard config file without disturbing it.
ถ้าให้แปลง่ายๆ Kustomize คือเครื่องมือที่จะมาช่วยในการ customize kubernetes manifest file ให้แยกไปตามแต่ละ environment ตามที่เรา Setup ไว้ได้
เราจะนำเจ้า Kustomize มาช่วย Setup Configuration ของ Service เราให้เป็นไปตามแต่ละ Environment
ตอนต่อไป!
พูดลอยๆแบบนี้ทุกคนอาจจะยังไม่เห็นภาพในบทความหน้าจะมีตัวอย่าง code ให้น่าจะเห็นภาพมากขึ้นสามารถติดตามได้ในตอนต่อไป!!