080-6372314
2020-10-30

Deploy App Zero Downtime with Kubernetes Deployment


"Downtime"

เนื้อหาในบทความนี้จะมาแนะนำการ deploy application ยังไงให้ไม่มี downtime โดยที่คนเข้าใช้งาน app ของเราไม่รู้เลยว่าเรามีการอัพเดท code ขึ้นไปใหม่ มาเริ่มกันเลย


Deployment Strategy

การ deploy application ของเราบน kubernetes ปกติแล้วเราจะเขียนไฟล์ที่เรียกว่า deployment ของเราขึ้นมา เพื่อบอกว่าจะให้ app เรามีการทำงานกี่ pod และแต่ละ pod มี container อะไรบ้าง ซึ่งโดยทั่วไปหน้าตาก็จะประมานนี้


"deployment"


แต่ใน deployment นั้นมี feature ที่เราสามารถกำหนดได้ว่าการ deploy app ของเรานั้นจะเป็นรูปแบบไหน สิ่งนี้จะเรียกมันว่า strategy ซึ่งการกำหนด strategy ใน deployment นั้นแบ่งได้หลายแบบ ดังนี้


  1. Recreate
  2. RollingUpdate
  3. Blue/Green 
  4. Canary

ซึ่งในบทความนี้เราจะพูดถึงการใช้ RollingUpdate


Rolling Update


เป็น default strategy deployment ของ kubernetes เราสามารถตรวจสอบ deployment ก่อนหน้านี้ ด้วยคำสั่ง

kubectl describe deployment

จะเห็นว่าส่วนที่เป็น StrategyType จะเป็น RollingUpdate เพราะเราไม่ได้กำหนดมา kubernetes จึงใช้ค่า default


"describe deployment"


การทำงานของ RollingUpdate จะค่อยๆสร้าง Pod ใหม่และลบ Pod เก่าออก การที่เราจะใช้ Strategy RollingUpdate นั่นจะต้องเข้าใจคุณสมบัติอีก 2 ตัวที่จะทำงานร่วมกับ RollingUpdate

maxSurge คือ กำหนดจำนวนของ Pod ที่สามารถสร้างได้สูงสุดระหว่าง Update Pod ในแต่ละครั้ง
maxUnavailable คือ กำหนดจำนวนของ Pod เก่าที่จะถูกลบในแต่ละครั้งที่มีการ Update Pod

ทั้ง 2 ตัวนี้สามารถกำหนดเป็น int หรือ % ก็ได้ ตัวอย่างการใช้งานดังนี้

"rollingupdate"


จากตัวอย่างมีการกำหนด maxSurge เป็น 1 และ maxUnavailable เป็น 1 หมายความว่า Pod ใหม่จะถูกสร้างใหม่ทีละ 1 Pod และ Pod เก่าก็จะถูกลบออกที่ละ 1 Pod นั่นเอง จากการ config ข้างต้นเมื่อเรา deploy app ใหม่เหมือนจะไม่มี downtime เกิดขึ้นใช่ไหม เพราะมีการสร้าง Pod ใหม่ และลบ Pod เก่าออก app เราก็น่าจะใช้งานได้ทันทีใช่ไหมละครับ แต่การกำหนดแบบนี้ยังเกิด downtime อยู่ดี เพราะ kubernetes ไม่รู้ว่าเมื่อไหร่ที่ Pod ใหม่พร้อมใช้งาน เพราะ Pod ที่กำลังสร้างใหม่ Pod เก่าก็ถูกลบทันที โดยไม่มีการรอ จึงเกิด downtime ขึ้นนั่นเอง kubernetes จึงมีสิ่งที่เรียกว่า Readiness Probe มาแก้ไขปัญหานี้


Readiness Probe


Readiness Probe จะมาช่วยให้เรามั่นใจได้ว่า Pod ที่สร้างใหม่พร้อมใช้งาน ก่อนที่จะลบ Pod เก่าออก สิ่งสำคัญของการใช้ feature นี้ก็คือ จะต้องมีการกำหนด path ขึ้นมาสำหรับการทำ health check และ return status code 200

"readinessProbe"


จากรูปมีการกำหนด readinessProbe ภายใต้ spec.containers โดยมีการกำหนดการทำงานต่างๆดังนี้


httpGet คือ จะใช้ http get method ในการตรวจสอบ app ของเรา


path คือ ที่เราสร้างขึ้นมาใน application เพื่อ return status 200


port คือ port ที่ app เราใช้งาน


initialDelaySecons คือ เมื่อ container สร้างเสร็จแล้วจะรออีก 5 วิ ก่อนจะทำงาน


periodSeconds คือ จะทำงานทุกๆ 5 วิ


successThreshold คือ return 200 กี่ครั้งถึงจะหยุดการทำงาน


สิ่งที่เกิดขึ้น ก็คือ เมื่อเรามีการ deploy app pod เก่าจะยังไม่ถูกลบทันที app ของเราก็ยังเข้าใช้งานได้ปกติ จะรอจนกว่า pod ใหม่สร้างเสร็จจน status เป็น Ready แสดงว่าพร้อมที่จะรับ traffic แทน pod เก่าแล้ว pod เก่าก็จะถูกลบ และคนที่เข้า app เราก็จะได้ app ที่เป็นของใหม่แทน จะเห็นว่าการทำงานที่เกิดขึ้นคนที่เข้า app ของเราจะไม่รู้เลยว่าเรามีการอัพเดทระบบอยู่ เราก็จะได้ deploy app แบบ zero downtime จริงๆนั่นเอง


สรุป


การ deploy app แบบ zero downtime นั้นจะทำให้ app ของเรานั่นมีความน่าเชื่อถือต่อผู้ใช้งานมากขึ้น เพราะผู้ใช้งานก็คาดหวังว่าจะสามารถใช้งาน app ของเราได้ตลอดเวลา และ Developer เองก็จะได้ update code ได้อย่างสบายใจไม่กระทบต่อการใช้งาน สุดท้ายนี้เนื้อหาข้างต้นเกิดจากความเข้าใจของผู้เขียนที่ได้ลองทำ ถ้าเนื้อหาตรงไหนไม่ถูกต้องหรือเข้าใจผิดต้องขออภัยด้วยนะครับ ^_^