กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

บันทึก. แปล: Service meshes ได้กลายเป็นโซลูชันที่เกี่ยวข้องในโครงสร้างพื้นฐานสมัยใหม่สำหรับแอปพลิเคชันที่เป็นไปตามสถาปัตยกรรมไมโครเซอร์วิสอย่างแน่นอน แม้ว่า Istio อาจอยู่ในสายตาของวิศวกร DevOps หลายคน แต่ก็เป็นผลิตภัณฑ์ที่ค่อนข้างใหม่ซึ่งแม้จะครอบคลุมในแง่ของความสามารถที่มีให้ แต่ก็อาจต้องใช้เวลาพอสมควรในการทำความคุ้นเคย Rinor Maloku วิศวกรชาวเยอรมัน ซึ่งรับผิดชอบด้านการประมวลผลแบบคลาวด์สำหรับลูกค้ารายใหญ่ของบริษัทโทรคมนาคม Orange Networks ได้เขียนชุดเนื้อหาที่ยอดเยี่ยมที่ช่วยให้คุณเจาะลึกเข้าไปใน Istio ได้อย่างรวดเร็วและลึกซึ้ง เขาเริ่มต้นเรื่องราวของเขาด้วยสิ่งที่ Istio สามารถทำได้โดยทั่วไป และวิธีที่คุณสามารถเห็นด้วยตาของคุณเองได้อย่างรวดเร็ว

อิสติโอ — โครงการโอเพ่นซอร์สที่พัฒนาร่วมกับทีมงานจาก Google, IBM และ Lyft ช่วยแก้ไขความซับซ้อนที่เกิดขึ้นในแอปพลิเคชันที่ใช้ไมโครเซอร์วิส เช่น:

  • การจัดการจราจร: หมดเวลา, ลองใหม่, ปรับสมดุลโหลด;
  • ความปลอดภัย: การรับรองความถูกต้องและการอนุญาตผู้ใช้ปลายทาง
  • ความสามารถในการสังเกต: การติดตาม การตรวจสอบ การบันทึก

ทั้งหมดนี้สามารถแก้ไขได้ในระดับแอปพลิเคชัน แต่หลังจากนั้นบริการของคุณจะไม่เป็นแบบ "ไมโคร" อีกต่อไป ความพยายามพิเศษทั้งหมดในการแก้ไขปัญหาเหล่านี้คือการสิ้นเปลืองทรัพยากรของบริษัทซึ่งสามารถนำมาใช้เพื่อสร้างมูลค่าทางธุรกิจได้โดยตรง ลองดูตัวอย่าง:

ผู้จัดการโครงการ: การเพิ่มฟีเจอร์คำติชมใช้เวลานานเท่าใด
ผู้พัฒนา: สองสปรินต์

MP: อะไรนะ.. มันก็แค่ CRUD!
คำตอบ: การทำ CRUD เป็นส่วนที่ง่าย แต่เรายังจำเป็นต้องตรวจสอบและอนุญาตผู้ใช้และบริการ เนื่องจากเครือข่ายไม่น่าเชื่อถือ คุณจะต้องดำเนินการตามคำขอซ้ำๆ ด้วยเช่นกัน รูปแบบเบรกเกอร์ ในลูกค้า นอกจากนี้ เพื่อให้แน่ใจว่าระบบทั้งหมดไม่ล่ม คุณจะต้องมีการหมดเวลาและ กำแพงกั้น (สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบที่กล่าวถึงทั้งสอง ดูภายหลังในบทความ - การแปลโดยประมาณ)และเพื่อตรวจจับปัญหา ติดตาม ติดตาม […]

MP: โอ้ งั้นเรามาแทรกฟีเจอร์นี้ลงในบริการผลิตภัณฑ์กันดีกว่า

ฉันคิดว่าแนวคิดนี้ชัดเจน: จำนวนขั้นตอนและความพยายามที่จำเป็นในการเพิ่มบริการหนึ่งนั้นยิ่งใหญ่มาก ในบทความนี้ เราจะดูว่า Istio ขจัดความซับซ้อนทั้งหมดที่กล่าวมาข้างต้น (ซึ่งไม่ได้ตั้งใจให้เป็นตรรกะทางธุรกิจ) ออกจากบริการได้อย่างไร

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

หมายเหตุ: บทความนี้ถือว่าคุณมีความรู้เกี่ยวกับการทำงานของ Kubernetes มิฉะนั้นฉันแนะนำให้อ่าน การแนะนำ Kubernetes ของฉัน และหลังจากนั้นก็อ่านเนื้อหานี้ต่อเท่านั้น

ความคิดของอิสติโอ

ในโลกที่ไม่มี Istio บริการหนึ่งจะส่งคำขอโดยตรงไปยังอีกบริการหนึ่ง และในกรณีที่เกิดความล้มเหลว บริการจะต้องจัดการเอง เช่น ลองใหม่ หมดเวลา เปิดเซอร์กิตเบรกเกอร์ ฯลฯ

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
การรับส่งข้อมูลเครือข่ายใน Kubernetes

Istio นำเสนอโซลูชันพิเศษที่แยกออกจากบริการและการทำงานโดยสิ้นเชิงโดยรบกวนการสื่อสารผ่านเครือข่าย และด้วยเหตุนี้จึงดำเนินการ:

  • ความอดทนต่อความผิดพลาด: ตามรหัสสถานะในการตอบกลับ จะเข้าใจว่าคำขอล้มเหลวและดำเนินการใหม่อีกครั้ง
  • การเปิดตัว Canary: เปลี่ยนเส้นทางคำขอเป็นเปอร์เซ็นต์คงที่ไปยังเวอร์ชันใหม่ของบริการ
  • การตรวจสอบและตัวชี้วัด: ใช้เวลานานแค่ไหนในการให้บริการในการตอบกลับ?
  • การติดตามและการสังเกต: เพิ่มส่วนหัวพิเศษให้กับแต่ละคำขอและติดตามทั่วทั้งคลัสเตอร์
  • ความปลอดภัย: ดึงโทเค็น JWT ตรวจสอบสิทธิ์และให้สิทธิ์ผู้ใช้

นี่เป็นเพียงไม่กี่ความเป็นไปได้ (เพียงไม่กี่อย่างเท่านั้น!) ที่จะทำให้คุณทึ่ง ตอนนี้เรามาดูรายละเอียดทางเทคนิคกันดีกว่า!

สถาปัตยกรรมอิสติโอ

Istio สกัดกั้นการรับส่งข้อมูลเครือข่ายทั้งหมด และใช้ชุดกฎกับเครือข่าย โดยแทรกสมาร์ทพร็อกซีในรูปแบบของคอนเทนเนอร์ไซด์คาร์ลงในแต่ละพ็อด พรอกซีที่เปิดใช้งานความสามารถทั้งหมดในรูปแบบ ระนาบข้อมูลและสามารถกำหนดค่าแบบไดนามิกได้โดยใช้ เครื่องบินควบคุม.

ระนาบข้อมูล

พร็อกซีที่แทรกลงในพ็อดช่วยให้ Istio สามารถตอบสนองความต้องการที่เราต้องการได้อย่างง่ายดาย ตัวอย่างเช่น ลองตรวจสอบฟังก์ชันการลองซ้ำและเบรกเกอร์

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
วิธีการลองใหม่และการทำลายวงจรใน Envoy

เพื่อสรุป:

  1. ราชทูต (เรากำลังพูดถึงพร็อกซีที่อยู่ในคอนเทนเนอร์รถเทียมข้างรถจักรยานยนต์ซึ่งกระจายเป็น สินค้าแยกต่างหาก - ประมาณ แปล.) ส่งคำขอไปยังอินสแตนซ์แรกของบริการ B และล้มเหลว
  2. ทูตไซด์คาร์พยายามอีกครั้ง (ลองอีกครั้ง). (1)
  3. คำขอล้มเหลวและถูกส่งกลับไปยังพร็อกซีที่เรียกใช้
  4. ซึ่งจะเป็นการเปิด Circuit Breaker และเรียกใช้บริการถัดไปสำหรับการร้องขอครั้งต่อไป (2)

ซึ่งหมายความว่าคุณไม่จำเป็นต้องใช้ไลบรารี Retry อื่น คุณไม่จำเป็นต้องดำเนินการ Circuit Breaking และ Service Discovery ของคุณเองในภาษาการเขียนโปรแกรม X, Y หรือ Z ทั้งหมดนี้และอีกมากมายมีพร้อมให้ใช้งานทันที ใน Istio และไม่ต้องการ ไม่ การเปลี่ยนแปลงในรหัส

ยอดเยี่ยม! ตอนนี้คุณอาจต้องการไปเที่ยวกับ Istio แต่คุณยังมีข้อสงสัยอยู่คำถามปลายเปิด หากนี่เป็นวิธีแก้ปัญหาที่เป็นสากลสำหรับทุกโอกาสในชีวิต แสดงว่าคุณมีข้อสงสัยโดยธรรมชาติ ท้ายที่สุดแล้ว วิธีแก้ปัญหาดังกล่าวทั้งหมดในความเป็นจริงกลับกลายเป็นว่าไม่เหมาะกับทุกกรณี

และสุดท้ายคุณก็ถามว่า “มันปรับแต่งได้หรือเปล่า?”

ตอนนี้คุณพร้อมสำหรับการเดินทางทางทะเลแล้ว มาทำความรู้จักกับ Control Plane กันดีกว่า

เครื่องบินควบคุม

ประกอบด้วยสามองค์ประกอบ: นักบิน, เครื่องผสม и ป้อมปราการ, — ซึ่งทำงานร่วมกันเพื่อกำหนดค่า Envoys เพื่อกำหนดเส้นทางการรับส่งข้อมูล บังคับใช้นโยบาย และรวบรวมข้อมูลการวัดและส่งข้อมูลทางไกล แผนผังทุกอย่างมีลักษณะดังนี้:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
ปฏิสัมพันธ์ของระนาบควบคุมกับระนาบข้อมูล

ทูต (เช่น Data Plane) ได้รับการกำหนดค่าโดยใช้ Kubernetes CRD (คำจำกัดความทรัพยากรที่กำหนดเอง) กำหนดโดย Istio และมีจุดประสงค์เพื่อจุดประสงค์นี้โดยเฉพาะ สิ่งนี้มีความหมายสำหรับคุณก็คือ ดูเหมือนว่าทรัพยากรเหล่านี้เป็นเพียงแหล่งข้อมูลอื่นใน Kubernetes ที่มีไวยากรณ์ที่คุ้นเคย เมื่อสร้างแล้ว ทรัพยากรนี้จะถูกเลือกโดยเครื่องบินควบคุมและนำไปใช้กับทูต

ความสัมพันธ์ของบริการกับ Istio

เราได้อธิบายความสัมพันธ์ของ Istio กับบริการแล้ว แต่กลับกันไม่ได้: บริการเกี่ยวข้องกับ Istio อย่างไร

พูดตามตรง บริการต่างๆ ต่างตระหนักถึงการปรากฏตัวของ Istio เหมือนกับว่าปลาคือน้ำ เมื่อพวกเขาถามตัวเองว่า "น้ำคืออะไร"

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
ภาพประกอบ วิกตอเรีย ดิมิตราโกปูลอส: - คุณชอบน้ำแค่ไหน? - น้ำคืออะไรล่ะ?

ดังนั้นคุณสามารถใช้คลัสเตอร์การทำงานได้และหลังจากการปรับใช้ส่วนประกอบ Istio บริการที่อยู่ในนั้นจะยังคงทำงานต่อไปและหลังจากลบส่วนประกอบเหล่านี้แล้วทุกอย่างจะดีอีกครั้ง เป็นที่ชัดเจนว่าในกรณีนี้ คุณจะสูญเสียความสามารถที่ Istio มอบให้

ทฤษฎีเพียงพอแล้ว - มานำความรู้นี้ไปปฏิบัติกันเถอะ!

อิสติโอในทางปฏิบัติ

Istio ต้องการคลัสเตอร์ Kubernetes ที่มี vCPU อย่างน้อย 4 ตัวและ RAM 8 GB หากต้องการตั้งค่าคลัสเตอร์อย่างรวดเร็วและทำตามคำแนะนำจากบทความ ฉันขอแนะนำให้ใช้ Google Cloud Platform ซึ่งเสนอผู้ใช้ใหม่ ฟรี $300.

หลังจากสร้างคลัสเตอร์และกำหนดค่าการเข้าถึง Kubernetes ผ่านคอนโซลยูทิลิตี้แล้ว คุณจะติดตั้ง Istio ผ่านตัวจัดการแพ็คเกจ Helm ได้

การติดตั้งหมวกกันน็อค

ติดตั้งไคลเอ็นต์ Helm บนคอมพิวเตอร์ของคุณ ตามที่อธิบายไว้ใน เอกสารราชการ. เราจะใช้สิ่งนี้เพื่อสร้างเทมเพลตสำหรับการติดตั้ง Istio ในส่วนถัดไป

กำลังติดตั้ง Istio

ดาวน์โหลดทรัพยากร Istio จาก รุ่นล่าสุด (ลิงก์ของผู้เขียนต้นฉบับไปยังเวอร์ชัน 1.0.5 ได้ถูกเปลี่ยนเป็นลิงก์ปัจจุบัน เช่น 1.0.6 - การแปลโดยประมาณ)แยกเนื้อหาออกเป็นไดเร็กทอรีเดียว ซึ่งฉันจะเรียกต่อจากนี้ไป [istio-resources].

หากต้องการระบุทรัพยากร Istio ได้อย่างง่ายดาย ให้สร้างเนมสเปซในคลัสเตอร์ K8 istio-system:

$ kubectl create namespace istio-system

ดำเนินการติดตั้งให้เสร็จสิ้นโดยไปที่ไดเร็กทอรี [istio-resources] และรันคำสั่ง:

$ helm template install/kubernetes/helm/istio 
  --set global.mtls.enabled=false 
  --set tracing.enabled=true 
  --set kiali.enabled=true 
  --set grafana.enabled=true 
  --namespace istio-system > istio.yaml

คำสั่งนี้จะส่งออกองค์ประกอบหลักของ Istio ไปยังไฟล์ istio.yaml. เราได้ปรับเปลี่ยนเทมเพลตมาตรฐานให้เหมาะกับตัวเราเอง โดยระบุพารามิเตอร์ต่อไปนี้:

  • global.mtls.enabled ติดตั้งใน false (เช่น การรับรองความถูกต้อง mTLS ถูกปิดใช้งาน - ประมาณ)เพื่อทำให้กระบวนการออกเดทของเราง่ายขึ้น
  • tracing.enabled รวมถึงการติดตามคำขอโดยใช้ Jaeger;
  • kiali.enabled ติดตั้ง Kiali ลงในคลัสเตอร์เพื่อแสดงภาพบริการและการรับส่งข้อมูล
  • grafana.enabled ติดตั้ง Grafana เพื่อแสดงภาพตัวชี้วัดที่รวบรวม

ลองใช้ทรัพยากรที่สร้างขึ้นด้วยคำสั่ง:

$ kubectl apply -f istio.yaml

การติดตั้ง Istio บนคลัสเตอร์เสร็จสมบูรณ์! รอจนกระทั่งพ็อดทั้งหมดอยู่ในเนมสเปซ istio-system จะสามารถ Running หรือ Completedโดยรันคำสั่งด้านล่าง:

$ kubectl get pods -n istio-system

ตอนนี้เราพร้อมที่จะดำเนินการต่อในส่วนถัดไปแล้ว ซึ่งเราจะเริ่มต้นใช้งานแอปพลิเคชัน

สถาปัตยกรรมของแอปพลิเคชันการวิเคราะห์ความรู้สึก

ลองใช้ตัวอย่างของแอปพลิเคชันไมโครเซอร์วิส Sentiment Analysis ที่ใช้ในที่กล่าวไปแล้ว บทความแนะนำ Kubernetes. มันซับซ้อนพอที่จะแสดงความสามารถของ Istio ในทางปฏิบัติได้

แอปพลิเคชันประกอบด้วยไมโครเซอร์วิสสี่รายการ:

  1. บริการ SA-ส่วนหน้าซึ่งทำหน้าที่เป็นส่วนหน้าของแอปพลิเคชัน Reactjs
  2. บริการ SA-WebAppซึ่งให้บริการแบบสอบถามการวิเคราะห์ความรู้สึก
  3. บริการ SA-ลอจิกซึ่งดำเนินการเอง การวิเคราะห์ความรู้สึก;
  4. บริการ SA-ข้อเสนอแนะซึ่งได้รับการตอบรับจากผู้ใช้เกี่ยวกับความแม่นยำของการวิเคราะห์

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

ในแผนภาพนี้ นอกเหนือจากบริการแล้ว เรายังเห็น Ingress Controller ซึ่งใน Kubernetes กำหนดเส้นทางคำขอขาเข้าไปยังบริการที่เหมาะสม Istio ใช้แนวคิดที่คล้ายกันภายใน Ingress Gateway ซึ่งมีรายละเอียดเพิ่มเติมตามมา

เรียกใช้แอปพลิเคชันด้วยพร็อกซีจาก Istio

สำหรับการดำเนินการเพิ่มเติมที่กล่าวถึงในบทความ ให้โคลนพื้นที่เก็บข้อมูลของคุณ istio-เชี่ยวชาญ. ประกอบด้วยแอปพลิเคชันและรายการสำหรับ Kubernetes และ Istio

การใส่รถเทียมข้างรถจักรยานยนต์

การแทรกสามารถทำได้ อัตโนมัติ หรือ ด้วยมือ. หากต้องการแทรกคอนเทนเนอร์เทียมอัตโนมัติ คุณจะต้องตั้งค่าป้ายกำกับให้กับเนมสเปซ istio-injection=enabledซึ่งทำได้ด้วยคำสั่งต่อไปนี้:

$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

ตอนนี้แต่ละพ็อดที่จะถูกปรับใช้ในเนมสเปซเริ่มต้น (default) จะได้รับคอนเทนเนอร์เทียมข้างรถ เพื่อตรวจสอบสิ่งนี้ เรามาปรับใช้แอปพลิเคชันทดสอบโดยไปที่ไดเร็กทอรีรากของที่เก็บ [istio-mastery] และรันคำสั่งต่อไปนี้:

$ kubectl apply -f resource-manifests/kube
persistentvolumeclaim/sqlite-pvc created
deployment.extensions/sa-feedback created
service/sa-feedback created
deployment.extensions/sa-frontend created
service/sa-frontend created
deployment.extensions/sa-logic created
service/sa-logic created
deployment.extensions/sa-web-app created
service/sa-web-app created

หลังจากปรับใช้บริการแล้ว ให้ตรวจสอบว่าพ็อดมีสองคอนเทนเนอร์ (พร้อมตัวบริการเองและตัวพ่วง) โดยการรันคำสั่ง kubectl get pods และตรวจสอบให้แน่ใจว่าอยู่ใต้คอลัมน์ READY ค่าที่ระบุ 2/2ซึ่งเป็นสัญลักษณ์ว่าคอนเทนเนอร์ทั้งสองกำลังทำงานอยู่:

$ kubectl get pods
NAME                           READY     STATUS    RESTARTS   AGE
sa-feedback-55f5dc4d9c-c9wfv   2/2       Running   0          12m
sa-frontend-558f8986-hhkj9     2/2       Running   0          12m
sa-logic-568498cb4d-2sjwj      2/2       Running   0          12m
sa-logic-568498cb4d-p4f8c      2/2       Running   0          12m
sa-web-app-599cf47c7c-s7cvd    2/2       Running   0          12m

สายตาดูเหมือนว่านี้:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
พร็อกซีทูตในพ็อดอันใดอันหนึ่ง

เมื่อแอปพลิเคชันเริ่มทำงานแล้ว เราจะต้องอนุญาตให้มีการรับส่งข้อมูลเข้ามายังแอปพลิเคชัน

ทางเข้าเกตเวย์

แนวทางปฏิบัติที่ดีที่สุดในการบรรลุเป้าหมายนี้ (อนุญาตการรับส่งข้อมูลในคลัสเตอร์) คือดำเนินการผ่าน ทางเข้าเกตเวย์ ใน Istio ซึ่งอยู่ที่ "ขอบ" ของคลัสเตอร์ และช่วยให้คุณเปิดใช้งานฟีเจอร์ Istio เช่น การกำหนดเส้นทาง โหลดบาลานซ์ การรักษาความปลอดภัย และการตรวจสอบการรับส่งข้อมูลขาเข้า

คอมโพเนนต์ Ingress Gateway และบริการที่ส่งต่อภายนอกได้รับการติดตั้งในคลัสเตอร์ระหว่างการติดตั้ง Istio หากต้องการค้นหาที่อยู่ IP ภายนอกของบริการ ให้เรียกใช้:

$ kubectl get svc -n istio-system -l istio=ingressgateway
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP
istio-ingressgateway   LoadBalancer   10.0.132.127   13.93.30.120

เราจะเข้าถึงแอปพลิเคชันต่อไปโดยใช้ IP นี้ (ฉันจะเรียกว่า EXTERNAL-IP) ดังนั้นเพื่อความสะดวกเราจะเขียนค่าลงในตัวแปร:

$ EXTERNAL_IP=$(kubectl get svc -n istio-system 
  -l app=istio-ingressgateway 
  -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

หากคุณพยายามเข้าถึง IP นี้ผ่านเบราว์เซอร์ตอนนี้ คุณจะได้รับข้อผิดพลาด Service Unavailable เนื่องจาก โดยค่าเริ่มต้น Istio จะบล็อกการรับส่งข้อมูลขาเข้าทั้งหมด, เกตเวย์ยังไม่ได้กำหนดไว้

ทรัพยากรเกตเวย์

เกตเวย์คือ CRD (ข้อกำหนดทรัพยากรที่กำหนดเอง) ใน Kubernetes ซึ่งกำหนดหลังจากติดตั้ง Istio ในคลัสเตอร์ และเปิดใช้งานความสามารถในการระบุพอร์ต โปรโตคอล และโฮสต์ที่เราต้องการอนุญาตการรับส่งข้อมูลขาเข้า

ในกรณีของเรา เราต้องการอนุญาตการรับส่งข้อมูล HTTP บนพอร์ต 80 สำหรับโฮสต์ทั้งหมด งานถูกนำไปใช้ตามคำจำกัดความต่อไปนี้ (http-gateway.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: http-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
- "*"

การกำหนดค่านี้ไม่ต้องการคำอธิบายใดๆ ยกเว้นตัวเลือก istio: ingressgateway. ด้วยตัวเลือกนี้ เราสามารถระบุได้ว่าจะใช้ Ingress Gateway ใดในการกำหนดค่า ในกรณีของเรา นี่คือตัวควบคุม Ingress Gateway ซึ่งได้รับการติดตั้งโดยค่าเริ่มต้นใน Istio

การกำหนดค่าถูกนำไปใช้โดยการเรียกคำสั่งต่อไปนี้:

$ kubectl apply -f resource-manifests/istio/http-gateway.yaml gateway.networking.istio.io/http-gateway created

ขณะนี้เกตเวย์อนุญาตให้เข้าถึงพอร์ต 80 ได้ แต่ไม่รู้ว่าจะกำหนดเส้นทางคำขอไปที่ใด สำหรับสิ่งนี้คุณจะต้องมี บริการเสมือน.

ทรัพยากรบริการเสมือน

VirtualService จะบอก Ingress Gateway ถึงวิธีการกำหนดเส้นทางคำขอที่ได้รับอนุญาตภายในคลัสเตอร์

คำขอไปยังแอปพลิเคชันของเราที่มาจาก http-gateway จะต้องส่งไปยังบริการ sa-frontend, sa-web-app และ sa-feedback:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
เส้นทางที่ต้องกำหนดค่าด้วย VirtualServices

มาดูคำขอที่ควรส่งไปยัง SA-Frontend:

  • การแข่งขันที่ตรงกันตลอดทาง / ควรส่งไปที่ SA-Frontend เพื่อรับ index.html;
  • เส้นทางนำหน้า /static/* ต้องส่งไปยัง SA-Frontend เพื่อรับไฟล์คงที่ที่ใช้ในส่วนหน้า เช่น CSS และ JavaScript
  • เส้นทางที่ตรงกับนิพจน์ทั่วไป '^.*.(ico|png|jpg)$'จะต้องส่งไปที่ SA-Frontend เพราะ เหล่านี้เป็นภาพที่แสดงบนหน้า

การนำไปใช้งานทำได้โดยการกำหนดค่าต่อไปนี้ (sa-virtualservice-external.yaml):

kind: VirtualService
metadata:
  name: sa-external-services
spec:
  hosts:
  - "*"
  gateways:
  - http-gateway                      # 1
  http:
  - match:
    - uri:
        exact: /
    - uri:
        exact: /callback
    - uri:
        prefix: /static
    - uri:
        regex: '^.*.(ico|png|jpg)

Важные моменты:

  1. Этот VirtualService относится к запросам, приходящим через http-gateway;
  2. В destination определяется сервис, куда отправляются запросы.
Примечание: Конфигурация выше хранится в файле sa-virtualservice-external.yaml, который также содержит настройки для маршрутизации в SA-WebApp и SA-Feedback, но был сокращён здесь в статье для лаконичности. Применим VirtualService вызовом:
$ kubectl apply -f resource-manifests/istio/sa-virtualservice-external.yaml
virtualservice.networking.istio.io/sa-external-services created

Примечание: Когда мы применяем ресурсы Istio, Kubernetes API Server создаёт событие, которое получает Istio Control Plane, и уже после этого новая конфигурация применяется к прокси-серверам Envoy каждого pod'а. А контроллер Ingress Gateway представляется очередным Envoy, сконфигурированным в Control Plane. Всё это на схеме выглядит так:

Назад к микросервисам вместе с Istio. Часть 1
Конфигурация Istio-IngressGateway для маршрутизации запросов

Приложение Sentiment Analysis стало доступным по http://{EXTERNAL-IP}/. Не переживайте, если вы получаете статус Not Found: иногда требуется чуть больше времени для того, чтобы конфигурация вступила в силу и кэши Envoy обновились.

Перед тем, как продолжить, поработайте немного с приложением, чтобы сгенерировать трафик (его наличие необходимо для наглядности в последующих действиях — прим. перев.).

Kiali : наблюдаемость

Чтобы попасть в административный интерфейс Kiali, выполните следующую команду:

$ kubectl port-forward 
    $(kubectl get pod -n istio-system -l app=kiali 
    -o jsonpath='{.items[0].metadata.name}') 
    -n istio-system 20001

… и откройте http://localhost:20001/, залогинившись под admin/admin. Здесь вы найдете множество полезных возможностей, например, для проверки конфигурации компонентов Istio, визуализации сервисов по информации, собранной при перехвате сетевых запросов, получения ответов на вопросы «Кто к кому обращается?», «У какой версии сервиса возникают сбои?» и т.п. В общем, изучите возможности Kiali перед тем, как двигаться дальше — к визуализации метрик с Grafana.

Назад к микросервисам вместе с Istio. Часть 1

Grafana: визуализация метрик

Собранные в Istio метрики попадают в Prometheus и визуализируются с Grafana. Чтобы попасть в административный интерфейс Grafana, выполните команду ниже, после чего откройте http://localhost:3000/:

$ kubectl -n istio-system port-forward 
    $(kubectl -n istio-system get pod -l app=grafana 
    -o jsonpath={.items[0].metadata.name}) 3000

Кликнув на меню Home слева сверху и выбрав Istio Service Dashboard в левом верхнем углу, начните с сервиса sa-web-app, чтобы посмотреть на собранные метрики:

Назад к микросервисам вместе с Istio. Часть 1

Здесь нас ждёт пустое и совершенно скучное представление — руководство никогда такое не одобрит. Давайте же создадим небольшую нагрузку следующей командой:

$ while true; do 
    curl -i http://$EXTERNAL_IP/sentiment 
    -H "Content-type: application/json" 
    -d '{"sentence": "I love yogobella"}'; 
    sleep .8; done

Вот теперь у нас гораздо более симпатичные графики, а в дополнение к ним — замечательные инструменты Prometheus для мониторинга и Grafana для визуализации метрик, что позволят нам узнать о производительности, состоянии здоровья, улучшениях/деградации в работе сервисов на протяжении времени.

Наконец, посмотрим на трассировку запросов в сервисах.

Jaeger : трассировка

Трассировка нам потребуется, потому что чем больше у нас сервисов, тем сложнее добраться до причины сбоя. Посмотрим на простой случай из картинки ниже:

Назад к микросервисам вместе с Istio. Часть 1
Типовой пример случайного неудачного запроса

Запрос приходит, падает — в чём же причина? Первый сервис? Или второй? Исключения есть в обоих — давайте посмотрим на логи каждого. Как часто вы ловили себя за таким занятием? Наша работа больше похожа на детективов программного обеспечения, а не разработчиков…

Это широко распространённая проблема в микросервисах и решается она распределёнными системами трассировки, в которых сервисы передают друг другу уникальный заголовок, после чего эта информация перенаправляется в систему трассировки, где она сопоставляется с данными запроса. Вот иллюстрация:

Назад к микросервисам вместе с Istio. Часть 1
Для идентификации запроса используется TraceId

В Istio используется Jaeger Tracer, который реализует независимый от вендоров фреймворк OpenTracing API. Получить доступ к пользовательского интерфейсу Jaeger можно следующей командой:

$ kubectl port-forward -n istio-system 
    $(kubectl get pod -n istio-system -l app=jaeger 
    -o jsonpath='{.items[0].metadata.name}') 16686

Теперь зайдите на http://localhost:16686/ и выберите сервис sa-web-app. Если сервис не показан в выпадающем меню — проявите/сгенерируйте активность на странице и обновите интерфейс. После этого нажмите на кнопку Find Traces, которая покажет самые последние трейсы — выберите любой — покажется детализированная информация по всем трейсам:

Назад к микросервисам вместе с Istio. Часть 1

Этот трейс показывает:

  1. Запрос приходит в istio-ingressgateway (это первое взаимодействие с одним из сервисов, и для запроса генерируется Trace ID), после чего шлюз направляет запрос в сервис sa-web-app.
  2. В сервисе sa-web-app запрос подхватывается Envoy sidecar'ом, создаётся «ребёнок» в span'е (поэтому мы видим его в трейсах) и перенаправляется в контейнер sa-web-app. (Span — логическая единица работы в Jaeger, имеющая название, время начало операции и её продолжительность. Span'ы могут быть вложенными и упорядоченными. Ориентированный ациклический граф из span'ов образует trace. — прим. перев.)
  3. Здесь запрос обрабатывается методом sentimentAnalysis. Эти трейсы уже сгенерированы приложением, т.е. для них потребовались изменения в коде.
  4. С этого момента инициируется POST-запрос в sa-logic. Trace ID должен быть проброшен из sa-web-app.

Примечание: На 4 шаге приложение должно увидеть заголовки, сгенерированные Istio, и передать их в последующие запросы, как показано на изображении ниже:

Назад к микросервисам вместе с Istio. Часть 1
(A) За проброс заголовков отвечает Istio; (B) За заголовки отвечают сервисы

Istio делает основную работу, т.к. генерирует заголовки для входящих запросов, создаёт новые span'ы в каждом sidecare'е и пробрасывает их. Однако без работы с заголовками внутри сервисов полный путь трассировки запроса будет утерян.

Необходимо учитывать (пробрасывать) следующие заголовки:

x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context

Это несложная задача, однако для упрощения её реализации уже существует множество библиотек — например, в сервисе sa-web-app клиент RestTemplate пробрасывает эти заголовки, если просто добавить библиотеки Jaeger и OpenTracing в его зависимости.

Заметьте, что приложение Sentiment Analysis демонстрирует реализации на Flask, Spring и ASP.NET Core.

Теперь, когда стало ясно, что мы получаем из коробки (или почти «из коробки»), рассмотрим вопросы тонко настраиваемой маршрутизации, управления сетевым трафиком, безопасности и т.п.!

Прим. перев.: об этом читайте в следующей части материалов по Istio от Rinor Maloku, переводы которых последуют в нашем блоге в ближайшее время. UPDATE (14 марта): Вторая часть уже опубликована.

P.S. от переводчика

Читайте также в нашем блоге:

Источник: habr.com

route:
- destination:
host: sa-frontend # 2
port:
number: 80

จุดสำคัญ:

  1. VirtualService นี้อ้างถึงคำขอที่เข้ามา http-เกตเวย์;
  2. В destination มีการกำหนดบริการที่ส่งคำขอไป

หมายเหตุ: การกำหนดค่าข้างต้นจะถูกจัดเก็บไว้ในไฟล์ sa-virtualservice-external.yamlซึ่งมีการตั้งค่าสำหรับการกำหนดเส้นทางใน SA-WebApp และ SA-Feedback ด้วย แต่ได้ย่อให้สั้นลงที่นี่ในบทความเพื่อความกระชับ

มาใช้ VirtualService โดยโทร:


หมายเหตุ: เมื่อเราใช้ทรัพยากร Istio เซิร์ฟเวอร์ Kubernetes API จะสร้างเหตุการณ์ที่ได้รับจาก Istio Control Plane และหลังจากนั้นจะใช้การกำหนดค่าใหม่กับพร็อกซี Envoy ของพ็อดแต่ละตัว และตัวควบคุม Ingress Gateway ดูเหมือนจะเป็น Envoy อื่นที่กำหนดค่าไว้ใน Control Plane ทั้งหมดนี้มีลักษณะเช่นนี้ในแผนภาพ:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
การกำหนดค่า Istio-IngressGateway สำหรับการกำหนดเส้นทางคำขอ

แอปพลิเคชันการวิเคราะห์ความรู้สึกพร้อมใช้งานแล้วบน http://{EXTERNAL-IP}/. ไม่ต้องกังวลหากคุณได้รับสถานะไม่พบ: บางครั้งการกำหนดค่าจะใช้เวลานานกว่าเล็กน้อยจึงจะมีผลและแคชของ Envoy ในการอัปเดต.

ก่อนดำเนินการต่อ ให้เล่นกับแอปเล็กน้อยเพื่อสร้างการเข้าชม (การมีอยู่เป็นสิ่งจำเป็นเพื่อความชัดเจนในการดำเนินการที่ตามมา - การแปลโดยประมาณ).

Kiali : การสังเกต

หากต้องการไปที่อินเทอร์เฟซผู้ดูแลระบบ Kiali ให้รันคำสั่งต่อไปนี้:


... และเปิด http://localhost:20001/, เข้าสู่ระบบในฐานะผู้ดูแลระบบ/ผู้ดูแลระบบ ที่นี่คุณจะพบคุณสมบัติที่มีประโยชน์มากมาย เช่น เพื่อตรวจสอบการกำหนดค่าส่วนประกอบ Istio แสดงภาพบริการโดยใช้ข้อมูลที่รวบรวมจากการสกัดกั้นคำขอเครือข่าย รับคำตอบสำหรับคำถาม "ใครกำลังติดต่อกับใคร" "บริการเวอร์ชันใดที่กำลังประสบอยู่" ความล้มเหลว?” และอื่น ๆ โดยทั่วไป ให้สำรวจความสามารถของ Kiali ก่อนที่จะก้าวไปสู่การแสดงภาพหน่วยวัดด้วย Grafana

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

Grafana: การแสดงภาพเมตริก

หน่วยวัดที่รวบรวมใน Istio จะเข้าสู่ Prometheus และแสดงภาพด้วย Grafana หากต้องการเข้าถึงอินเทอร์เฟซผู้ดูแลระบบ Grafana ให้รันคำสั่งด้านล่างแล้วเปิดขึ้นมา http://localhost:3000/:


คลิกที่เมนู หน้าแรก ด้านซ้ายบนแล้วเลือก แดชบอร์ดบริการ Istio ที่มุมซ้ายบน เริ่มต้นด้วยบริการ sa-web-appเพื่อดูเมตริกที่รวบรวมไว้:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

สิ่งที่รอเราอยู่ที่นี่คือประสิทธิภาพที่ว่างเปล่าและน่าเบื่ออย่างยิ่ง - ฝ่ายบริหารจะไม่มีวันอนุมัติสิ่งนี้ มาสร้างโหลดขนาดเล็กด้วยคำสั่งต่อไปนี้:


ตอนนี้เรามีกราฟที่สวยงามกว่ามาก และนอกจากนั้นแล้ว ยังมีเครื่องมือ Prometheus ที่ยอดเยี่ยมสำหรับการตรวจสอบและ Grafana สำหรับการแสดงตัวชี้วัดที่จะช่วยให้เราเรียนรู้เกี่ยวกับประสิทธิภาพ ความสมบูรณ์ การปรับปรุง / ความเสื่อมโทรมของบริการเมื่อเวลาผ่านไป

สุดท้ายนี้ มาดูคำขอการติดตามในบริการกัน

เยเกอร์ : การติดตาม

เราจะต้องมีการติดตาม เพราะยิ่งเรามีบริการมากเท่าไร ก็ยิ่งยากที่จะเข้าถึงสาเหตุของความล้มเหลวได้ ลองดูกรณีง่ายๆจากภาพด้านล่าง:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
ตัวอย่างทั่วไปของคำขอที่ล้มเหลวแบบสุ่ม

คำขอมาตก - เหตุผลคืออะไร? บริการครั้งแรก? หรืออันที่สอง? มีข้อยกเว้นในทั้งสองกรณี - ลองดูบันทึกของแต่ละรายการกัน คุณจับได้ว่าตัวเองทำเช่นนี้บ่อยแค่ไหน? งานของเราเป็นเหมือนนักสืบซอฟต์แวร์มากกว่านักพัฒนา...

นี่เป็นปัญหาทั่วไปในไมโครเซอร์วิสและแก้ไขได้โดยระบบการติดตามแบบกระจาย ซึ่งบริการจะส่งส่วนหัวที่ไม่ซ้ำกันให้กันและกัน หลังจากนั้นข้อมูลนี้จะถูกส่งต่อไปยังระบบการติดตาม ซึ่งจะถูกเปรียบเทียบกับข้อมูลคำขอ นี่คือภาพประกอบ:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
TraceId ใช้เพื่อระบุคำขอ

Istio ใช้ Jaeger Tracer ซึ่งใช้เฟรมเวิร์ก OpenTracing API ที่ไม่ขึ้นกับผู้จำหน่าย คุณสามารถเข้าถึงอินเทอร์เฟซผู้ใช้ Jaeger ได้ด้วยคำสั่งต่อไปนี้:


ตอนนี้ไปที่ http://localhost:16686/ และเลือกบริการ sa-web-app. หากบริการไม่แสดงในเมนูแบบเลื่อนลง ให้แสดง/สร้างกิจกรรมบนเพจและอัปเดตอินเทอร์เฟซ หลังจากนั้นคลิกที่ปุ่ม ค้นหาร่องรอยซึ่งจะแสดงการติดตามล่าสุด - เลือกรายการใดก็ได้ - ข้อมูลโดยละเอียดเกี่ยวกับการติดตามทั้งหมดจะปรากฏขึ้น:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1

ร่องรอยนี้แสดงให้เห็นว่า:

  1. คำขอก็เข้ามา istio-ทางเข้าเกตเวย์ (นี่เป็นการโต้ตอบครั้งแรกกับบริการใดบริการหนึ่ง และสร้าง Trace ID สำหรับคำขอ) หลังจากนั้นเกตเวย์จะส่งคำขอไปยังบริการ sa-web-app.
  2. อยู่ในการให้บริการ sa-web-app คำขอถูกหยิบขึ้นมาโดยรถเทียมข้างรถจักรยานยนต์ "ลูก" ถูกสร้างขึ้นในช่วง (นั่นคือสาเหตุที่เราเห็นมันอยู่ในร่องรอย) และเปลี่ยนเส้นทางไปยังคอนเทนเนอร์ sa-web-app. (ระยะ - หน่วยลอจิคัลของงานใน Jaeger ซึ่งมีชื่อ เวลาเริ่มต้นของการดำเนินการ และระยะเวลา Span สามารถซ้อนกันและเรียงลำดับได้ กราฟแบบอะไซคลิกแบบตรงของช่วงจะก่อให้เกิดการติดตาม — ประมาณ แปล)
  3. ที่นี่คำขอได้รับการประมวลผลโดยวิธีการ การวิเคราะห์ความรู้สึก. แอปพลิเคชันสร้างร่องรอยเหล่านี้แล้ว เช่น พวกเขาต้องการการเปลี่ยนแปลงรหัส
  4. นับจากนี้เป็นต้นไป คำขอ POST จะเริ่มต้นขึ้น sa-ตรรกะ. รหัสการติดตามจะต้องส่งต่อจาก sa-web-app.
  5. ...

หมายเหตุ: ในขั้นตอนที่ 4 แอปพลิเคชันควรเห็นส่วนหัวที่สร้างโดย Istio และส่งต่อไปยังคำขอที่ตามมาดังที่แสดงในภาพด้านล่าง:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1
(A) Istio รับผิดชอบในการส่งต่อส่วนหัว (B) บริการมีหน้าที่รับผิดชอบต่อส่วนหัว

Istio ทำงานส่วนใหญ่เพราะ... สร้างส่วนหัวสำหรับคำขอที่เข้ามา สร้างช่วงใหม่ในแต่ละ sidecare และส่งต่อ อย่างไรก็ตาม หากไม่ได้ทำงานกับส่วนหัวภายในบริการ เส้นทางการติดตามคำขอทั้งหมดจะหายไป

ต้องคำนึงถึงส่วนหัวต่อไปนี้:


นี่ไม่ใช่งานที่ยาก แต่มีอยู่แล้วเพื่อทำให้การใช้งานง่ายขึ้น ห้องสมุดหลายแห่ง - ตัวอย่างเช่น ในบริการ sa-web-app ไคลเอ็นต์ RestTemplate จะส่งต่อส่วนหัวเหล่านี้หากคุณเพียงเพิ่มไลบรารี Jaeger และ OpenTracing ไปที่ การเสพติดของเขา.

โปรดทราบว่าแอปพลิเคชันการวิเคราะห์ความรู้สึกสาธิตการใช้งานใน Flask, Spring และ ASP.NET Core

ตอนนี้ก็ชัดเจนว่าเราได้อะไรนอกกรอบ (หรือเกือบจะนอกกรอบ) มาดูการกำหนดเส้นทางที่ปรับแต่ง การจัดการการรับส่งข้อมูลเครือข่าย ความปลอดภัย ฯลฯ กัน!

บันทึก. แปล: อ่านเกี่ยวกับเรื่องนี้ในส่วนถัดไปของเนื้อหาเกี่ยวกับ Istio จาก Rinor Maloku ซึ่งจะตามมาในบล็อกของเราในอนาคตอันใกล้นี้ อัพเดท (14 มีนาคม): ส่วนที่สอง ได้รับการเผยแพร่แล้ว

ปล.จากผู้แปล

อ่านเพิ่มเติมในบล็อกของเรา:

ที่มา: will.com