บันทึก. แปล:
นอกจากนี้เรายังเตือนคุณด้วยว่าบทความนี้ใช้การกำหนดค่า (รายการสำหรับ Kubernetes และ Istio) จากพื้นที่เก็บข้อมูล
การจัดการจราจร
ด้วย Istio ความสามารถใหม่จะปรากฏในคลัสเตอร์เพื่อมอบ:
- การกำหนดเส้นทางคำขอแบบไดนามิก: การเปิดตัวคานารี, การทดสอบ A/B;
- โหลดบาลานซ์: เรียบง่ายและสม่ำเสมอ โดยยึดตามแฮช
- การฟื้นตัวหลังการล้ม: หมดเวลา, ลองใหม่, เซอร์กิตเบรกเกอร์;
- การแทรกข้อบกพร่อง: ความล่าช้า คำขอที่ตกหล่น ฯลฯ
ในขณะที่บทความดำเนินต่อไป ความสามารถเหล่านี้จะแสดงตัวอย่างโดยใช้แอปพลิเคชันที่เลือกไว้เป็นตัวอย่าง และแนวคิดใหม่ๆ จะถูกแนะนำไปพร้อมกัน แนวคิดดังกล่าวแรกจะเป็น DestinationRules
(เช่น กฎเกี่ยวกับผู้รับการรับส่งข้อมูล/คำขอ - การแปลโดยประมาณ)ด้วยความช่วยเหลือในการเปิดใช้งานการทดสอบ A/B
การทดสอบ A/B: กฎปลายทางในทางปฏิบัติ
การทดสอบ A/B ใช้ในกรณีที่แอปพลิเคชันมีสองเวอร์ชัน (โดยปกติจะมีความแตกต่างกันทางสายตา) และเราไม่แน่ใจ 100% ว่าเวอร์ชันใดจะปรับปรุงประสบการณ์ผู้ใช้ได้ ดังนั้นเราจึงเรียกใช้ทั้งสองเวอร์ชันพร้อมกันและรวบรวมเมตริก
หากต้องการปรับใช้ฟรอนท์เอนด์เวอร์ชันที่สอง ซึ่งจำเป็นสำหรับการสาธิตการทดสอบ A/B ให้รันคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
รายการการปรับใช้สำหรับเวอร์ชันสีเขียวมีความแตกต่างกันในสองตำแหน่ง:
- รูปภาพนี้ใช้แท็กอื่น -
istio-green
, - พ็อดมีฉลาก
version: green
.
เนื่องจากการปรับใช้ทั้งสองมีป้ายกำกับ app: sa-frontend
คำขอที่กำหนดเส้นทางโดยบริการเสมือน sa-external-services
สำหรับการบริการ sa-frontend
จะถูกเปลี่ยนเส้นทางไปยังอินสแตนซ์ทั้งหมด และโหลดจะถูกกระจายผ่าน
ไม่พบไฟล์ที่ร้องขอ
ไม่พบไฟล์เหล่านี้เนื่องจากมีการตั้งชื่อแตกต่างกันในเวอร์ชันต่างๆ ของแอปพลิเคชัน มาตรวจสอบสิ่งนี้กัน:
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.c7071b22.css
/static/js/main.059f8e9c.js
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.f87cd8c9.css
/static/js/main.f7659dbb.js
ซึ่งหมายความว่า index.html
โหลดบาลานเซอร์สามารถส่งคำขอไฟล์คงที่เวอร์ชันหนึ่งไปยังพ็อดที่มีเวอร์ชันอื่นได้ โดยที่ไฟล์ดังกล่าวไม่มีอยู่จริงด้วยเหตุผลที่ชัดเจน ดังนั้นเพื่อให้แอปพลิเคชันทำงานได้ เราจำเป็นต้องกำหนดข้อจำกัด: “เวอร์ชันเดียวกันของแอปพลิเคชันที่ให้บริการ index.html ควรตอบสนองคำขอที่ตามมา'
เราจะไปถึงที่นั่นด้วยการปรับสมดุลโหลดตามแฮชที่สอดคล้องกัน (โหลดบาลานซ์แฮชที่สอดคล้องกัน). ในกรณีนี้ คำขอจากไคลเอ็นต์เดียวกันจะถูกส่งไปยังอินสแตนซ์แบ็กเอนด์เดียวกันซึ่งใช้คุณสมบัติที่กำหนดไว้ล่วงหน้า เช่น ส่วนหัว HTTP ดำเนินการโดยใช้ DestinationRules
กฎปลายทาง
หลังจากที่ บริการเสมือน ส่งคำขอไปยังบริการที่ต้องการ โดยใช้ DestinationRules เราสามารถกำหนดนโยบายที่จะนำไปใช้กับการรับส่งข้อมูลที่กำหนดไว้สำหรับอินสแตนซ์ของบริการนี้:
การจัดการการรับส่งข้อมูลด้วยทรัพยากรของ Istio
หมายเหตุ: ผลกระทบของทรัพยากร Istio ต่อการรับส่งข้อมูลเครือข่ายมีการนำเสนอไว้ที่นี่ในลักษณะที่เข้าใจง่าย พูดให้ถูกก็คือ การตัดสินใจว่าอินสแตนซ์ใดที่จะส่งคำขอไปนั้นกระทำโดยทูตใน Ingress Gateway ที่กำหนดค่าไว้ใน CRD
ด้วยกฎปลายทาง เราสามารถกำหนดค่าการปรับสมดุลโหลดเพื่อใช้แฮชที่สอดคล้องกัน และให้แน่ใจว่าอินสแตนซ์บริการเดียวกันตอบสนองต่อผู้ใช้คนเดียวกัน การกำหนดค่าต่อไปนี้ช่วยให้คุณบรรลุเป้าหมายนี้ (
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1
1 - แฮชจะถูกสร้างขึ้นตามเนื้อหาของส่วนหัว HTTP version
.
ใช้การกำหนดค่าด้วยคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created
ตอนนี้ให้รันคำสั่งด้านล่างและตรวจสอบให้แน่ใจว่าคุณได้รับไฟล์ที่ถูกต้องเมื่อคุณระบุส่วนหัว version
:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
หมายเหตุ: หากต้องการเพิ่มค่าต่างๆ ในส่วนหัวและทดสอบผลลัพธ์โดยตรงในเบราว์เซอร์ คุณสามารถใช้ได้
โดยทั่วไป DestinationRules มีความสามารถมากกว่าในด้านการทำโหลดบาลานซ์ - ตรวจสอบรายละเอียดใน
ก่อนที่จะศึกษา VirtualService เพิ่มเติม ให้ลบ "เวอร์ชันสีเขียว" ของแอปพลิเคชันและกฎทิศทางการรับส่งข้อมูลที่เกี่ยวข้องออกโดยการรันคำสั่งต่อไปนี้:
$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions “sa-frontend-green” deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io “sa-frontend” deleted
การมิเรอร์: บริการเสมือนจริงในทางปฏิบัติ
แชโดว์ (“การป้องกัน”) หรือการมิเรอร์ (“การมิเรอร์”) ใช้ในกรณีที่เราต้องการทดสอบการเปลี่ยนแปลงในการผลิตโดยไม่ส่งผลกระทบต่อผู้ใช้: ในการดำเนินการนี้ เราจะทำซ้ำคำขอ (“มิเรอร์”) ไปยังอินสแตนซ์ที่สองที่ทำการเปลี่ยนแปลงตามที่ต้องการ และดูผลที่ตามมา พูดง่ายๆ คือนี่คือตอนที่เพื่อนร่วมงานของคุณเลือกปัญหาที่สำคัญที่สุดและยื่นคำขอดึงข้อมูลในรูปแบบของก้อนสิ่งสกปรกขนาดใหญ่ที่ไม่มีใครสามารถตรวจสอบได้จริง
เพื่อทดสอบสถานการณ์นี้ในทางปฏิบัติ เรามาสร้างอินสแตนซ์ที่สองของ SA-Logic พร้อมข้อบกพร่อง (buggy
) โดยรันคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
และตอนนี้เรามารันคำสั่งเพื่อให้แน่ใจว่าทุกกรณีด้วย app=sa-logic
นอกจากนี้ยังมีป้ายกำกับที่มีเวอร์ชันที่เกี่ยวข้องด้วย:
$ kubectl get pods -l app=sa-logic --show-labels
NAME READY LABELS
sa-logic-568498cb4d-2sjwj 2/2 app=sa-logic,version=v1
sa-logic-568498cb4d-p4f8c 2/2 app=sa-logic,version=v1
sa-logic-buggy-76dff55847-2fl66 2/2 app=sa-logic,version=v2
sa-logic-buggy-76dff55847-kx8zz 2/2 app=sa-logic,version=v2
บริการ sa-logic
กำหนดเป้าหมายพ็อดด้วยป้ายกำกับ app=sa-logic
ดังนั้นคำขอทั้งหมดจะถูกกระจายไปยังทุกกรณี:
... แต่เราต้องการให้ส่งคำขอไปยังอินสแตนซ์ v1 และมิเรอร์ไปยังอินสแตนซ์ v2:
เราจะบรรลุเป้าหมายนี้ผ่าน VirtualService ร่วมกับ DestinationRule โดยที่กฎจะกำหนดชุดย่อยและเส้นทางของ VirtualService ไปยังชุดย่อยเฉพาะ
การกำหนดชุดย่อยในกฎปลายทาง
เซตย่อย (เซตย่อย) ถูกกำหนดโดยการกำหนดค่าต่อไปนี้ (
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-logic
spec:
host: sa-logic # 1
subsets:
- name: v1 # 2
labels:
version: v1 # 3
- name: v2
labels:
version: v2
- เจ้าภาพ (
host
) กำหนดว่ากฎนี้ใช้กับกรณีที่เส้นทางไปยังบริการเท่านั้นsa-logic
; - ชื่อเรื่อง (
name
) เซ็ตย่อยถูกใช้เมื่อกำหนดเส้นทางไปยังอินสแตนซ์เซ็ตย่อย - ฉลาก (
label
) กำหนดคู่คีย์-ค่าที่อินสแตนซ์ต้องตรงกันจึงจะกลายเป็นส่วนหนึ่งของชุดย่อย
ใช้การกำหนดค่าด้วยคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created
เมื่อกำหนดเซ็ตย่อยแล้ว เราก็สามารถดำเนินการต่อและกำหนดค่า VirtualService เพื่อใช้กฎกับคำขอไปยัง sa-logic เพื่อให้:
- ถูกส่งไปยังเซตย่อย
v1
, - มิเรอร์ไปยังเซตย่อย
v2
.
ประกาศต่อไปนี้ช่วยให้คุณบรรลุแผนของคุณ (
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
mirror:
host: sa-logic
subset: v2
ไม่จำเป็นต้องมีคำอธิบาย ดังนั้นเรามาดูการทำงานกัน:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
มาเพิ่มโหลดด้วยการเรียกคำสั่งต่อไปนี้:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done
มาดูผลลัพธ์ใน Grafana ซึ่งคุณจะเห็นว่าเวอร์ชันมีข้อบกพร่อง (buggy
) ส่งผลให้เกิดความล้มเหลวประมาณ 60% ของคำขอ แต่ไม่มีความล้มเหลวเหล่านี้ส่งผลกระทบต่อผู้ใช้ปลายทาง เนื่องจากบริการที่ทำงานอยู่ตอบสนองพวกเขา
การตอบสนองที่ประสบความสำเร็จของบริการ sa-logic เวอร์ชันต่างๆ
อันดับแรกเราจะได้เห็นว่า VirtualService นำไปใช้กับทูตบริการของเราอย่างไร: เมื่อใด sa-web-app
ทำการร้องขอ sa-logic
โดยจะผ่าน Sidecar Envoy ซึ่ง - ผ่าน VirtualService - ได้รับการกำหนดค่าเพื่อกำหนดเส้นทางคำขอไปยังชุดย่อย v1 และสะท้อนคำขอไปยังชุดย่อย v2 ของบริการ sa-logic
.
ฉันรู้ว่าคุณอาจคิดอยู่แล้วว่า Virtual Services นั้นเรียบง่าย ในส่วนถัดไป เราจะขยายความโดยบอกว่าพวกมันก็ยอดเยี่ยมเช่นกัน
การเปิดตัว Canary
Canary Deployment เป็นกระบวนการในการเปิดตัวแอปพลิเคชันเวอร์ชันใหม่ให้กับผู้ใช้จำนวนไม่มาก ใช้เพื่อให้แน่ใจว่าไม่มีปัญหาในการเผยแพร่และหลังจากนั้นเมื่อมีความมั่นใจในคุณภาพ (การเผยแพร่) แล้วจึงแจกจ่ายให้กับผู้ใช้รายอื่นоผู้ชมจำนวนมากขึ้น
เพื่อสาธิตการเปิดตัว Canary เราจะดำเนินการกับชุดย่อยต่อไป buggy
у sa-logic
.
อย่าเสียเวลากับเรื่องเล็ก ๆ น้อย ๆ และส่งผู้ใช้ 20% ไปยังเวอร์ชันที่มีข้อบกพร่องทันที (ซึ่งจะแสดงถึงการเปิดตัว Canary ของเรา) และอีก 80% ที่เหลือเป็นบริการปกติ เมื่อต้องการทำเช่นนี้ ใช้ VirtualService ต่อไปนี้ (
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 80 # 1
- destination:
host: sa-logic
subset: v2
weight: 20 # 1
1 คือน้ำหนัก (weight
) ซึ่งระบุเปอร์เซ็นต์ของคำขอที่จะถูกส่งไปยังผู้รับหรือกลุ่มย่อยของผู้รับ
มาอัปเดตการกำหนดค่า VirtualService ก่อนหน้าสำหรับ sa-logic
ด้วยคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured
... และเราจะเห็นทันทีว่าคำขอบางรายการนำไปสู่ความล้มเหลว:
$ while true; do
curl -i http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}'
--silent -w "Time: %{time_total}s t Status: %{http_code}n"
-o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500
VirtualServices เปิดใช้งานการเปิดตัว canary: ในกรณีนี้ เราได้จำกัดผลกระทบที่อาจเกิดขึ้นจากปัญหาให้แคบลงเหลือ 20% ของฐานผู้ใช้ มหัศจรรย์! ในตอนนี้ ในทุกกรณีที่เราไม่แน่ใจในโค้ดของเรา (หรืออีกนัยหนึ่งคือ - เสมอ...) เราสามารถใช้การมิเรอร์และการเปิดตัว Canary ได้
หมดเวลาและลองอีกครั้ง
แต่จุดบกพร่องไม่ได้จบลงที่โค้ดเสมอไป ในรายการจาก "
สำหรับการสาธิต เราจะใช้เวอร์ชันปัญหาเดิมต่อไป sa-logic
(buggy
) และเราจะจำลองความไม่น่าเชื่อถือของเครือข่ายโดยมีความล้มเหลวแบบสุ่ม
ให้บริการที่มีข้อบกพร่องของเรามีโอกาส 1/3 ที่จะใช้เวลานานเกินไปในการตอบสนอง มีโอกาส 1/3 ที่จะจบลงด้วยข้อผิดพลาดเซิร์ฟเวอร์ภายใน และโอกาส 1/3 ที่จะส่งคืนเพจได้สำเร็จ
เพื่อลดผลกระทบของปัญหาดังกล่าวและทำให้ชีวิตผู้ใช้ดีขึ้น เราสามารถ:
- เพิ่มการหมดเวลาหากบริการใช้เวลาตอบสนองนานกว่า 8 วินาที
- ลองอีกครั้งหากคำขอล้มเหลว
สำหรับการนำไปใช้งาน เราจะใช้คำจำกัดความของทรัพยากรต่อไปนี้ (
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 50
- destination:
host: sa-logic
subset: v2
weight: 50
timeout: 8s # 1
retries:
attempts: 3 # 2
perTryTimeout: 3s # 3
- การหมดเวลาสำหรับการร้องขอถูกตั้งค่าเป็น 8 วินาที
- มีการลองส่งคำขออีกครั้ง 3 ครั้ง
- และความพยายามแต่ละครั้งจะถือว่าไม่สำเร็จหากเวลาตอบสนองเกิน 3 วินาที
นี่คือการเพิ่มประสิทธิภาพเนื่องจากผู้ใช้ไม่ต้องรอเกิน 8 วินาที และเราจะพยายามรับการตอบกลับใหม่สามครั้งในกรณีที่เกิดความล้มเหลว ซึ่งจะเพิ่มโอกาสการตอบกลับที่สำเร็จ
ใช้การกำหนดค่าที่อัปเดตด้วยคำสั่งต่อไปนี้:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configured
และตรวจสอบกราฟ Grafana ว่าจำนวนการตอบกลับที่สำเร็จเพิ่มขึ้นด้านบน:
การปรับปรุงสถิติการตอบสนองที่ประสบความสำเร็จหลังจากเพิ่มการหมดเวลาและลองใหม่
ก่อนที่จะไปยังส่วนถัดไป (หรือมากกว่านั้นไปที่ส่วนถัดไปของบทความเพราะในนี้จะไม่มีการทดลองเชิงปฏิบัติอีกต่อไป - การแปลโดยประมาณ), ลบ sa-logic-buggy
และ VirtualService โดยการรันคำสั่งต่อไปนี้:
$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” deleted
เซอร์กิตเบรกเกอร์และรูปแบบกั้น
เรากำลังพูดถึงรูปแบบที่สำคัญสองรูปแบบในสถาปัตยกรรมไมโครเซอร์วิสที่ช่วยให้คุณสามารถกู้คืนตนเองได้ (การรักษาตนเอง) บริการ
เบรกเกอร์ ("เบรกเกอร์") ใช้เพื่อยุติคำขอที่มาถึงอินสแตนซ์ของบริการที่ถือว่าไม่มีประสิทธิภาพ และกู้คืนในขณะที่คำขอของลูกค้าถูกเปลี่ยนเส้นทางไปยังอินสแตนซ์ที่มีประสิทธิภาพของบริการนั้น (ซึ่งจะเพิ่มเปอร์เซ็นต์ของการตอบกลับที่สำเร็จ) (หมายเหตุ: สามารถดูคำอธิบายรูปแบบโดยละเอียดเพิ่มเติมได้ เช่น
กำแพงกั้น ("พาร์ติชัน") แยกความล้มเหลวของบริการออกจากผลกระทบต่อระบบทั้งหมด ตัวอย่างเช่น บริการ B ใช้งานไม่ได้และบริการอื่น (ไคลเอนต์ของบริการ B) ทำการร้องขอไปยังบริการ B ทำให้เธรดพูลหมดและไม่สามารถให้บริการคำขออื่น ๆ ได้ (แม้ว่าจะไม่ได้มาจากบริการ B ก็ตาม) (หมายเหตุ: สามารถดูคำอธิบายรูปแบบโดยละเอียดเพิ่มเติมได้ เช่น
ฉันจะละเว้นรายละเอียดการใช้งานของรูปแบบเหล่านี้เนื่องจากง่ายต่อการค้นหา
ปล.จากผู้แปล
อ่านเพิ่มเติมในบล็อกของเรา:
- "กลับสู่ไมโครเซอร์วิสด้วย Istio":
ตอนที่ 1 (แนะนำคุณสมบัติหลัก) ,ส่วนที่ 3 (การรับรองความถูกต้องและการอนุญาต) ; - «
ท่อร้อยสาย - บริการตาข่ายน้ำหนักเบาสำหรับ Kubernetes "; - «
Service Mesh คืออะไร และเหตุใดฉันจึงต้องมี [สำหรับแอปพลิเคชันระบบคลาวด์ที่มีไมโครเซอร์วิส] '
ที่มา: will.com