การใช้ Istio+Kiali เพื่อเปิดใช้และแสดงภาพการปรับใช้ Canary
บทความในชุดนี้
การปรับใช้ Canary ใน Kubernetes #1: Gitlab CI การปรับใช้ Canary ใน Kubernetes #2: การเปิดตัว Argo - (บทความนี้)
- การปรับใช้ Canary โดยใช้ Jenkins-X Istio Flagger
การปรับใช้นกขมิ้น
เราหวังว่าคุณจะอ่าน
อิสติโอ
และเราถือว่าการอ่านบทความนี้คุณรู้อยู่แล้วว่า Istio คืออะไร ถ้าไม่เช่นนั้นคุณสามารถอ่านเกี่ยวกับเรื่องนี้ได้
ใบสมัครสำหรับการทดสอบ
แต่ละพ็อดประกอบด้วยสองคอนเทนเนอร์: แอปพลิเคชันของเราและ istio-proxy
เราจะใช้แอปพลิเคชันทดสอบง่ายๆ กับพ็อด frontend-nginx และ python แบ็กเอนด์ พ็อด nginx จะเปลี่ยนเส้นทางคำขอแต่ละรายการไปยังพ็อดแบ็กเอนด์และทำงานเป็นพร็อกซี รายละเอียดสามารถพบได้ใน yamls ต่อไปนี้:
เรียกใช้แอปพลิเคชันทดสอบด้วยตัวเอง
หากคุณต้องการติดตามตัวอย่างของฉันและใช้แอปพลิเคชันทดสอบนี้ด้วยตัวเอง โปรดดู
การปรับใช้เบื้องต้น
เมื่อเราเปิดตัว Deployment ครั้งแรก เราจะเห็นว่าพ็อดของแอปพลิเคชันของเรามีเพียง 2 คอนเทนเนอร์ กล่าวคือ Istio sidecar เพิ่งถูกนำมาใช้:
และเรายังเห็น Istio Gateway Loadbalancer ในเนมสเปซด้วย istio-system
:
การสร้างทราฟฟิก
เราจะใช้ IP ต่อไปนี้เพื่อสร้างการรับส่งข้อมูลที่พ็อดส่วนหน้าจะได้รับและส่งต่อไปยังพ็อดแบ็กเอนด์:
while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done
เราจะเพิ่มด้วย frontend.istio-test
ไปยังไฟล์โฮสต์ของเรา
ดู Mesh ผ่าน Kiali
เราติดตั้งแอปพลิเคชันทดสอบและ Istio พร้อมกับ Tracing, Grafana, Prometheus และ Kiali (ดูรายละเอียดด้านล่าง)
istioctl dashboard kiali # admin:admin
Kiali แสดงภาพการจราจรปัจจุบันผ่าน Mesh
ดังที่เราเห็น 100% ของการรับส่งข้อมูลไปที่บริการส่วนหน้า จากนั้นไปที่พ็อดส่วนหน้าที่มีป้ายกำกับ v1 เนื่องจากเราใช้พร็อกซี nginx แบบธรรมดาที่เปลี่ยนเส้นทางคำขอไปยังบริการแบ็กเอนด์ ซึ่งจะเปลี่ยนเส้นทางไปยังพ็อดแบ็กเอนด์ พร้อมป้ายกำกับ v1.
Kiali ทำงานได้ดีกับ Istio และมอบโซลูชันการเรนเดอร์ Mesh แบบบรรจุกล่อง ดีเพียง.
การปรับใช้นกขมิ้น
แบ็กเอนด์ของเรามีการปรับใช้ k8s สองรายการแล้ว หนึ่งรายการสำหรับ v1 และอีกรายการหนึ่งสำหรับ v2 ตอนนี้เราแค่ต้องบอก Istio ให้ส่งต่อคำขอเปอร์เซ็นต์หนึ่งไปยังเวอร์ชัน 2
ขั้นตอนที่ 1: 10%
และสิ่งที่เราต้องทำคือปรับน้ำหนักของ VirtualService ค่ะ
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
- match:
- {}
route:
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 90
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 10
เราพบว่าคำขอ 10% ถูกเปลี่ยนเส้นทางไปยังเวอร์ชัน 2
ขั้นตอนที่ 2: 50%
และตอนนี้ก็เพียงพอแล้วที่จะเพิ่มเป็น 50%:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
...
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 50
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 50
ขั้นตอนที่ 3: 100%
ขณะนี้การปรับใช้ Canary ถือว่าเสร็จสมบูรณ์แล้ว และการรับส่งข้อมูลทั้งหมดถูกเปลี่ยนเส้นทางไปที่ v2:
การทดสอบ Canary ด้วยตนเอง
สมมติว่าตอนนี้เราส่งคำขอทั้งหมด 2% ไปยังแบ็กเอนด์ v10 จะเป็นอย่างไรหากเราต้องการทดสอบ v2 ด้วยตนเองเพื่อให้แน่ใจว่าทุกอย่างทำงานได้ตามที่เราคาดหวัง
เราสามารถเพิ่มกฎการจับคู่พิเศษตามส่วนหัว HTTP:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
- match:
- headers:
canary:
exact: "canary-tester"
route:
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 100
- match:
- {}
route:
- destination:
host: backend.default.svc.cluster.local
subset: v1
port:
number: 80
weight: 90
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 10
ตอนนี้เมื่อใช้ curl เราสามารถบังคับคำขอ v2 ได้โดยการส่งส่วนหัว:
คำขอที่ไม่มีส่วนหัวจะยังคงขับเคลื่อนด้วยอัตราส่วน 1/10:
Canary สำหรับสองเวอร์ชันที่ขึ้นต่อกัน
ตอนนี้เราจะพิจารณาตัวเลือกที่เรามีเวอร์ชัน v2 สำหรับทั้งส่วนหน้าและส่วนหลัง สำหรับทั้งสองอย่าง เราได้ระบุว่า 10% ของการเข้าชมควรไปที่เวอร์ชัน 2:
เราจะเห็นว่าส่วนหน้า v1 และ v2 ทั้งการรับส่งข้อมูลส่งต่อที่อัตราส่วน 1/10 ต่อแบ็กเอนด์ v1 และ v2
จะเกิดอะไรขึ้นหากเราต้องการส่งต่อการรับส่งข้อมูลจาก frontend-v2 ไปยัง backend-v2 เท่านั้น เนื่องจากเข้ากันไม่ได้กับ v1 ในการดำเนินการนี้ เราจะกำหนดอัตราส่วน 1/10 สำหรับส่วนหน้า ซึ่งจะควบคุมว่าการรับส่งข้อมูลใดจะไปถึงแบ็กเอนด์-v2 โดยใช้การเจรจาต่อรอง sourceLabels
:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: backend
namespace: default
spec:
gateways: []
hosts:
- "backend.default.svc.cluster.local"
http:
...
- match:
- sourceLabels:
app: frontend
version: v2
route:
- destination:
host: backend.default.svc.cluster.local
subset: v2
port:
number: 80
weight: 100
เป็นผลให้เราได้รับสิ่งที่เราต้องการ:
ความแตกต่างจากแนวทาง Canary แบบแมนนวล
В ส่วนแรก เราดำเนินการปรับใช้ Canary ด้วยตนเอง โดยใช้การปรับใช้ k8 สองครั้งด้วย ที่นั่นเราควบคุมอัตราส่วนของคำขอโดยการเปลี่ยนจำนวนแบบจำลอง วิธีนี้ใช้ได้ผล แต่มีข้อเสียร้ายแรง
Istio ช่วยให้สามารถกำหนดอัตราส่วนของคำขอโดยไม่คำนึงถึงจำนวนเรพลิกา ซึ่งหมายความว่า เราสามารถใช้ HPA (Horizontal Pod Autoscalers) ได้ และไม่จำเป็นต้องกำหนดค่าตามสถานะปัจจุบันของการปรับใช้ Canary
ทั้งหมด
Istio ใช้งานได้ดีและใช้ร่วมกับ Kiali ทำให้เกิดการผสมผสานที่ทรงพลังมาก ถัดไปในรายการความสนใจของฉันคือการรวม Spinnaker กับ Istio สำหรับระบบอัตโนมัติและการวิเคราะห์ Canary
ที่มา: will.com