DEV Community

Tossapol Ritcharoenwattu
Tossapol Ritcharoenwattu

Posted on

Kubernetes Workshop1 : Step8 : Update and Rollback Deployment

ในเรื่องของการ Update and Rollback เรามารู้จักหัวข้อหลักๆ ที่ต้องใช้ในเรื่องนี้กันก่อนประกอบด้วย

1. Rollout

การปรับเปลี่ยนเวอร์ชันแอปใน Kubernetes แบบไม่ทำให้ระบบล่ม
คือกระบวนการที่ Deployment อัปเดตแอป จากเวอร์ชันเดิม → ไปยังเวอร์ชันใหม่ ทำแบบ ค่อย ๆ แทนที่ Pod เก่า ด้วย Pod ใหม่ (Rolling Update) ช่วยให้ แอปยังใช้งานได้ตลอด → ไม่มี downtime
Rollout สำคัญอย่างไร

  • อัปเดตแอปโดย ไม่หยุดให้บริการ
  • ลดความเสี่ยง → ถ้าเวอร์ชันใหม่พัง → Rollback กลับได้ทันที
  • ช่วยให้ Deploy เวอร์ชันใหม่ได้ปลอดภัยกว่า Rollout ทำงานยังไง ตัวอย่างเช่น: คุณมี Deployment ที่รัน nginx:1.18 ต้องการเปลี่ยนเป็น nginx:1.19

เราจะลองทำ lab กันดู โดยการ สร้าง deployment nginx:1.18 ก่อน
'''
kubectl create deployment my-nginx --image=nginx:1.18 --replicas=3
'''

จะเห็นว่าตอนนี้เรามี deployment my-nginx:1.18

เราจะทำการ rollout nginx version ใหม่เป็น 1.19

kubectl set image deployment/my-nginx nginx=nginx:1.19
Enter fullscreen mode Exit fullscreen mode

เช็คสถานะการ rollout

kubectl rollout status deployment
Enter fullscreen mode Exit fullscreen mode

เช็ค history การ rollout

kubectl rollout history deployment/my-nginx
Enter fullscreen mode Exit fullscreen mode


สรุปขั้นตอนการทำงานของ rollout
Kubernetes จะสร้าง ReplicaSet ใหม่ สำหรับเวอร์ชันใหม่และค่อย ๆ ปิด Pod เก่า แล้วสร้าง Pod ใหม่แทนจนครบจำนวน replicas ที่กำหนด

ก่อน Rollout:
[Pod v1] [Pod v1] [Pod v1]
ระหว่าง Rollout:
[Pod v1] [Pod v1] [Pod v2]
[Pod v1] [Pod v2] [Pod v2]
[Pod v2] [Pod v2] [Pod v2]
หลัง Rollout เสร็จ:
[Pod v2] [Pod v2] [Pod v2]

  • ถ้าแก้ไข image ใน deployment.yaml แล้วสั่ง apply kubernetes จะทำการ rollout ให้เช่นกัน

2. Versioning

คือการจัดการเวอร์ชันของแอปหรือ Deployment เพื่อให้รู้ว่าเรากำลังรันแอปเวอร์ชันไหน และสามารถย้อนกลับได้ถ้าพัง
Versioning ใช้ทำอะไร?

  • รู้ว่า ตอนนี้รันแอปเวอร์ชันไหน (image, config)
  • ช่วยให้ Kubernetes ทำ Rollback ได้ง่าย
  • ช่วยเก็บ ประวัติการเปลี่ยนแปลง (Revision History) ของ Deployment
  • ลดความเสี่ยงเวลาปล่อยแอปเวอร์ชันใหม่

เวลาสร้างหรือแก้ไข Deployment → Kubernetes จะสร้าง ReplicaSet ใหม่ ทุกครั้งที่มีการเปลี่ยนแปลง โดยแต่ละ ReplicaSet = แต่ละเวอร์ชันของ Deployment
ตัวอย่างหลังจาก rollout แล้ว ถ้าเรา เช็คดูว่าใน cluster มี replicaset อะไรอยู่บ้าง

kubectl get replicaset -o wide
Enter fullscreen mode Exit fullscreen mode


จะเห็นว่า มี replicaset อยู่ 2 โดย replicaset nginx:1.19 มี pod ที่พร้อมทำงานอยู่ 3 แต่ใน nginx:1.18 ไม่มี pod ที่พร้อมทำงาน เนื่องจาก kubernetes จะเก็บ version เดิมไว้เผื่อระบบเกิดปัญหา ต้องทำการ rollback

3. Rollback

คือการย้อนกลับไปใช้ version ก่อนหน้า ถ้าเวอร์ชันใหม่พัง → Rollback กลับเวอร์ชันเดิมได้ทันที
เราสามารถสั่งด้วย command

kubectl rollout undo deployment/my-nginx
Enter fullscreen mode Exit fullscreen mode


Kubernetes จะสลับกลับไปใช้ ReplicaSet ของเวอร์ชันเก่า
ลองเช็ค replicaset ดู จะเห็นว่า pod ready จะกลับมาอยู่ที่ nginx:1.18 แล้ว

4. Deployment Strategy

คือรูปแบบการ rollout version ใหม่ มี 2 แบบคือ Rolling-Update เป็นค่า default ที่ kubernetes ใช้ ตามที่อธิบายแล้วด้านบน และ Recreate เป็นการ ลบ pod เก่าออกจากระบบทั้งหมดก่อน แล้วจึงสร้าง pod ใหม่มาแทนที่ ซึ่งวิธีนี้อาจมี downtime
เหตุผลที่ควรใช้ Recreate
1. แอปทำงานพร้อมกันหลายเวอร์ชันไม่ได้

  • Database Migration
  • Stateful App ที่ต้องการ Lock Resource
  • Service ที่ใช้ Port เดียวกัน ตัวอย่าง: ถ้าคุณมี Database Migration → ต้องหยุด Service ก่อน deploy schema ใหม่ → ใช้ Recreate เหมาะสุด 2. ป้องกัน Conflicts
  • แอปบางตัวอาจชนกันถ้ารันหลายเวอร์ชันพร้อมกัน 3. ต้องการ Clean Slate อยาก ล้างของเก่าให้หมดก่อน deploy ใหม่ ไม่ควรใช้ Recreate ตอนไหน?
  • แอปที่ต้อง ให้บริการตลอดเวลา (Zero Downtime)
  • แอปที่ต้องการ High Availability

การกำหนดให้ kubernetes ใช้ Deployment Strategy แบบ Recreate สามารถทำได้ด้วย yaml เท่านั้น โดยการกำหนด Strategy type

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
    type: front-end
spec:
  strategy:
    type: Recreate
  replicas: 3
  selector:
    matchLabels:
      type: front-end
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.1
Enter fullscreen mode Exit fullscreen mode

Top comments (0)