บันทึก. แปล: Henning Jacobs หัวหน้าวิศวกรจาก Zalando สังเกตเห็นปัญหาในหมู่ผู้ใช้ Kubernetes ซ้ำแล้วซ้ำเล่าในการทำความเข้าใจวัตถุประสงค์ของโพรบความพร้อมใช้งาน (และความพร้อม) และการใช้งานที่ถูกต้อง ดังนั้น เขาจึงรวบรวมความคิดของเขาไว้ในบันทึกอันกว้างขวางนี้ ซึ่งในที่สุดจะกลายเป็นส่วนหนึ่งของเอกสารของ K8
การตรวจสุขภาพ หรือที่เรียกใน Kubernetes ว่า โพรบความมีชีวิตชีวา (เช่น แท้จริงแล้ว “การทดสอบความมีชีวิต” - การแปลโดยประมาณ)ค่อนข้างจะเป็นอันตรายได้ ฉันแนะนำให้หลีกเลี่ยงหากเป็นไปได้: ข้อยกเว้นเพียงอย่างเดียวคือเมื่อมีความจำเป็นจริงๆ และคุณตระหนักดีถึงลักษณะเฉพาะและผลที่ตามมาของการใช้งาน เอกสารนี้จะพูดถึงการตรวจสอบความสดและความพร้อม และจะแจ้งให้คุณทราบในกรณีใดบ้าง เป็น และคุณไม่ควรใช้มัน
Sandor เพื่อนร่วมงานของฉันได้แชร์บน Twitter ถึงข้อผิดพลาดที่พบบ่อยที่สุดที่เขาพบ รวมถึงข้อผิดพลาดที่เกี่ยวข้องกับการใช้การตรวจสอบความพร้อม/ความมีชีวิตชีวา:
กำหนดค่าไม่ถูกต้อง livenessProbe
สามารถทำให้สถานการณ์ที่มีการโหลดสูงรุนแรงขึ้น (การปิดระบบสโนว์บอล + เวลาเริ่มต้นคอนเทนเนอร์/แอปพลิเคชันที่อาจยาวนาน) และนำไปสู่ผลกระทบด้านลบอื่นๆ เช่น การพึ่งพาลดลง (ดูสิ่งนี้ด้วย
ข้อความทั่วไป "อย่าใช้เครื่องตรวจสอบความมีชีวิตชีวา" ในกรณีนี้ก็ไม่ได้ช่วยอะไรมาก มาดูกันว่าการตรวจสอบความพร้อมและความสดมีไว้เพื่ออะไร
หมายเหตุ: การทดสอบด้านล่างส่วนใหญ่เดิมรวมอยู่ในเอกสารสำหรับนักพัฒนาภายในของ Zalando
การตรวจสอบความพร้อมและความมีชีวิตชีวา
Kubernetes มีกลไกสำคัญสองกลไกที่เรียกว่า
การใช้งาน Kubernetes การสอบสวนความพร้อมเพื่อทำความเข้าใจว่าคอนเทนเนอร์พร้อมที่จะรับปริมาณการใช้งานเมื่อใด พ็อดจะถือว่าพร้อมใช้งานหากภาชนะทั้งหมดพร้อม การใช้กลไกนี้อย่างหนึ่งคือควบคุมว่าพ็อดใดที่จะใช้เป็นแบ็กเอนด์สำหรับบริการ Kubernetes (และโดยเฉพาะ Ingress)
เครื่องตรวจสอบความมีชีวิตชีวา ช่วยให้ Kubernetes เข้าใจว่าเมื่อถึงเวลาต้องรีสตาร์ทคอนเทนเนอร์ ตัวอย่างเช่น การตรวจสอบดังกล่าวช่วยให้คุณสามารถสกัดกั้นการหยุดชะงักเมื่อแอปพลิเคชันติดค้างอยู่ในที่เดียว การรีสตาร์ทคอนเทนเนอร์ในสถานะนี้ช่วยให้แอปพลิเคชันไม่ทำงานแม้ว่าจะมีข้อผิดพลาด แต่ก็สามารถนำไปสู่ความล้มเหลวแบบเรียงซ้อนได้ (ดูด้านล่าง)
หากคุณพยายามปรับใช้การอัปเดตแอปพลิเคชันที่ไม่ผ่านการตรวจสอบความพร้อมใช้งาน/ความพร้อม การเปิดตัวจะหยุดชะงักเนื่องจาก Kubernetes รอสถานะ Ready
จากฝักทั้งหมด
ตัวอย่าง
นี่คือตัวอย่างของการสอบสวนความพร้อมในการตรวจสอบเส้นทาง /health
ผ่าน HTTP ด้วยการตั้งค่าเริ่มต้น (ระยะห่าง: 10 วินาที การหยุดพักชั่วคราว: 1 วินาที, เกณฑ์ความสำเร็จ: 1, เกณฑ์ความล้มเหลว: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080
แนะนำ
- สำหรับไมโครเซอร์วิสที่มีจุดสิ้นสุด HTTP (REST ฯลฯ) กำหนดการสอบสวนความพร้อมเสมอซึ่งจะตรวจสอบว่าแอปพลิเคชัน (พ็อด) พร้อมที่จะรับการรับส่งข้อมูลหรือไม่
- ตรวจสอบให้แน่ใจว่ามีการสอบสวนความพร้อม ครอบคลุมความพร้อมใช้งานของพอร์ตเว็บเซิร์ฟเวอร์จริง:
- การใช้พอร์ตเพื่อวัตถุประสงค์ในการดูแลระบบ เรียกว่า "ผู้ดูแลระบบ" หรือ "การจัดการ" (เช่น 9090) สำหรับ
readinessProbe
ตรวจสอบให้แน่ใจว่าปลายทางส่งคืนค่า OK หากพอร์ต HTTP หลัก (เช่น 8080) พร้อมที่จะรับการรับส่งข้อมูล*;*ฉันทราบอย่างน้อยหนึ่งกรณีที่ Zalando ซึ่งเหตุการณ์นี้ไม่เกิดขึ้น กล่าวคือ
readinessProbe
ฉันตรวจสอบพอร์ต "การจัดการ" แล้ว แต่ตัวเซิร์ฟเวอร์เองไม่ได้เริ่มทำงานเนื่องจากปัญหาในการโหลดแคช - การติดโพรบความพร้อมเข้ากับพอร์ตแยกต่างหากอาจทำให้โอเวอร์โหลดบนพอร์ตหลักจะไม่สะท้อนให้เห็นในการตรวจสอบสภาพ (นั่นคือ เธรดพูลบนเซิร์ฟเวอร์เต็ม แต่การตรวจสอบสภาพยังคงแสดงให้เห็นว่าทุกอย่างเรียบร้อยดี ).
- การใช้พอร์ตเพื่อวัตถุประสงค์ในการดูแลระบบ เรียกว่า "ผู้ดูแลระบบ" หรือ "การจัดการ" (เช่น 9090) สำหรับ
- ทำให้เเน่นอน การสอบสวนความพร้อมเปิดใช้งานการเริ่มต้น/การย้ายฐานข้อมูล;
- วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการติดต่อเซิร์ฟเวอร์ HTTP หลังจากการกำหนดค่าเริ่มต้นเสร็จสมบูรณ์แล้วเท่านั้น (เช่น การย้ายฐานข้อมูลจาก
ฟลายเวย์ และอื่นๆ.); นั่นคือ แทนที่จะเปลี่ยนสถานะการตรวจสอบสภาพ อย่าเริ่มเว็บเซิร์ฟเวอร์จนกว่าการย้ายฐานข้อมูลจะเสร็จสิ้น** คุณยังสามารถเรียกใช้การย้ายฐานข้อมูลจากคอนเทนเนอร์เริ่มต้นภายนอกพ็อดได้ ฉันยังคงเป็นแฟนตัวยงของแอปพลิเคชันที่มีอยู่ในตัวเองนั่นคือแอปพลิเคชันที่คอนเทนเนอร์ของแอปพลิเคชันรู้วิธีนำฐานข้อมูลเข้าสู่สถานะที่ต้องการโดยไม่ต้องมีการประสานงานจากภายนอก
- วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการติดต่อเซิร์ฟเวอร์ HTTP หลังจากการกำหนดค่าเริ่มต้นเสร็จสมบูรณ์แล้วเท่านั้น (เช่น การย้ายฐานข้อมูลจาก
- ใช้
httpGet
เพื่อตรวจความพร้อมผ่านจุดตรวจสุขภาพทั่วไป (เช่น/health
). - ทำความเข้าใจกับพารามิเตอร์การตรวจสอบเริ่มต้น (
interval: 10s
,timeout: 1s
,successThreshold: 1
,failureThreshold: 3
):- ตัวเลือกเริ่มต้นหมายความว่าพ็อดจะกลายเป็น ไม่พร้อม หลังจากนั้นประมาณ 30 วินาที (การตรวจสอบสุขภาพจิตล้มเหลว 3 ครั้ง)
- ใช้พอร์ตแยกต่างหากสำหรับ "ผู้ดูแลระบบ" หรือ "การจัดการ" หากกลุ่มเทคโนโลยี (เช่น Java/Spring) อนุญาต เพื่อแยกการจัดการสุขภาพและตัวชี้วัดออกจากการรับส่งข้อมูลปกติ:
- แต่อย่าลืมข้อ 2 ด้วย
- หากจำเป็น สามารถใช้หัววัดความพร้อมเพื่ออุ่นเครื่อง/โหลดแคชและส่งคืนรหัสสถานะ 503 จนกว่าคอนเทนเนอร์จะอุ่นขึ้น:
- ฉันขอแนะนำให้คุณอ่านเช็คใหม่ด้วย
startupProbe
,ปรากฏในเวอร์ชัน 1.16 (เราเขียนเกี่ยวกับเรื่องนี้เป็นภาษารัสเซียที่นี่ - ประมาณ แปล.).
- ฉันขอแนะนำให้คุณอ่านเช็คใหม่ด้วย
ข้อควรระวัง
- อย่าพึ่งพาการพึ่งพาภายนอก (เช่น คลังข้อมูล) เมื่อรันการทดสอบความพร้อม/ความพร้อมใช้งาน ซึ่งอาจนำไปสู่ความล้มเหลวแบบเรียงซ้อน:
- ตามตัวอย่าง ลองใช้บริการ REST stateful ที่มี 10 พ็อดขึ้นอยู่กับฐานข้อมูล Postgres หนึ่งฐานข้อมูล: เมื่อการตรวจสอบขึ้นอยู่กับการเชื่อมต่อที่ใช้งานได้กับ DB พ็อดทั้ง 10 พ็อดอาจล้มเหลวหากมีความล่าช้าในเครือข่าย/ฝั่ง DB - โดยปกติแล้ว ทุกอย่างจบลงเลวร้ายเกินกว่าจะเป็นไปได้
- โปรดทราบว่า Spring Data จะตรวจสอบการเชื่อมต่อฐานข้อมูลตามค่าเริ่มต้น*;
* นี่เป็นพฤติกรรมเริ่มต้นของ Spring Data Redis (อย่างน้อยก็เป็นครั้งสุดท้ายที่ฉันตรวจสอบ) ซึ่งนำไปสู่ความล้มเหลว "หายนะ": เมื่อ Redis ไม่พร้อมใช้งานในช่วงเวลาสั้น ๆ พ็อดทั้งหมดจะ "ขัดข้อง"
- “ภายนอก” ในแง่นี้ยังหมายถึงพ็อดอื่นๆ ของแอปพลิเคชันเดียวกัน กล่าวคือ ตามหลักการแล้ว การตรวจสอบไม่ควรขึ้นอยู่กับสถานะของพ็อดอื่นๆ ในคลัสเตอร์เดียวกันเพื่อป้องกันการแครชแบบเรียงซ้อน:
- ผลลัพธ์อาจแตกต่างกันไปสำหรับแอปพลิเคชันที่มีสถานะแบบกระจาย (เช่น การแคชในหน่วยความจำในพ็อด)
- อย่าใช้เครื่องตรวจสอบความมีชีวิตชีวา สำหรับพ็อด (ข้อยกเว้นคือกรณีที่จำเป็นจริงๆ และคุณตระหนักดีถึงลักษณะเฉพาะและผลที่ตามมาของการใช้งาน):
- การตรวจสอบความมีชีวิตชีวาสามารถช่วยกู้คืนคอนเทนเนอร์ที่ค้างได้ แต่เนื่องจากคุณสามารถควบคุมแอปพลิเคชันของคุณได้อย่างสมบูรณ์ สิ่งต่างๆ เช่น กระบวนการที่หยุดทำงานและการหยุดชะงักไม่ควรเกิดขึ้น ทางเลือกที่ดีที่สุดคือจงใจทำให้แอปพลิเคชันเสียหายและนำแอปพลิเคชันกลับสู่สถานะคงที่ก่อนหน้านี้
- การสอบสวนความสดที่ล้มเหลวจะทำให้คอนเทนเนอร์รีสตาร์ท ซึ่งอาจส่งผลให้ผลที่ตามมาจากข้อผิดพลาดที่เกี่ยวข้องกับการโหลดรุนแรงขึ้น: การรีสตาร์ทคอนเทนเนอร์จะส่งผลให้เกิดการหยุดทำงาน (อย่างน้อยในช่วงระยะเวลาของการเริ่มต้นแอปพลิเคชัน กล่าวคือ 30 วินาทีคี่) ทำให้เกิดข้อผิดพลาดใหม่ การเพิ่มภาระบนคอนเทนเนอร์อื่น ๆ และเพิ่มโอกาสที่จะเกิดความล้มเหลว ฯลฯ
- การตรวจสอบความสดรวมกับการขึ้นต่อกันภายนอกเป็นการผสมผสานที่แย่ที่สุดที่เป็นไปได้ ซึ่งคุกคามความล้มเหลวแบบเรียงซ้อน: ความล่าช้าเล็กน้อยในฝั่งฐานข้อมูลจะนำไปสู่การรีสตาร์ทคอนเทนเนอร์ทั้งหมดของคุณ!
- พารามิเตอร์ของการตรวจสอบความสดและความพร้อม จะต้องแตกต่าง:
- คุณสามารถใช้เครื่องมือตรวจสอบความมีชีวิตชีวาด้วยการตรวจสุขภาพแบบเดียวกัน แต่มีเกณฑ์การตอบสนองที่สูงกว่า (
failureThreshold
) เช่น กำหนดสถานะ ไม่พร้อม หลังจากพยายาม 3 ครั้ง และพิจารณาว่าโพรบความสดล้มเหลวหลังจากพยายาม 10 ครั้ง
- คุณสามารถใช้เครื่องมือตรวจสอบความมีชีวิตชีวาด้วยการตรวจสุขภาพแบบเดียวกัน แต่มีเกณฑ์การตอบสนองที่สูงกว่า (
- อย่าใช้การตรวจสอบ execเนื่องจากมีความเกี่ยวข้องกับปัญหาที่ทราบซึ่งนำไปสู่การปรากฏตัวของกระบวนการซอมบี้:
- รายละเอียด: ดู
การนำเสนอโดยผู้เชี่ยวชาญของ Datadog .
- รายละเอียด: ดู
สรุป
- ใช้การสอบสวนความพร้อมเพื่อพิจารณาว่าพ็อดพร้อมรับการรับส่งข้อมูลเมื่อใด
- ใช้การตรวจสอบความมีชีวิตชีวาเมื่อจำเป็นจริงๆ เท่านั้น
- การใช้โพรบความพร้อม/ความคงอยู่อย่างไม่เหมาะสมอาจทำให้ความพร้อมใช้งานลดลงและความล้มเหลวแบบเรียงซ้อน
วัสดุเพิ่มเติมในหัวข้อ
-
เอกสาร Kubernetes: กำหนดค่า Liveness และ Readiness Probes ; -
ทบทวนความมีชีวิตชีวาและความพร้อมของ Kubernetes อีกครั้ง: วิธีหลีกเลี่ยงการยิงตัวเองด้วยเท้าอีกข้าง ; -
NRE Labs หยุดการชันสูตรพลิกศพ (เขายังพูดถึง livenessProbe ด้วย)
อัปเดตครั้งที่ 1 จาก 2019-09-29
อัปเดตครั้งที่ 2 จาก 2019-09-29
ปล.จากผู้แปล
อ่านเพิ่มเติมในบล็อกของเรา:
- «
Kubernetes: พ็อดชีวิต "; - «
7 แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้คอนเทนเนอร์ตาม Google "; - «
หลัก 7 ประการสำหรับการออกแบบแอปพลิเคชันบนคอนเทนเนอร์ '
ที่มา: will.com