การตรวจสอบความมีชีวิตชีวาใน Kubernetes อาจเป็นอันตรายได้

บันทึก. แปล: Henning Jacobs หัวหน้าวิศวกรจาก Zalando สังเกตเห็นปัญหาในหมู่ผู้ใช้ Kubernetes ซ้ำแล้วซ้ำเล่าในการทำความเข้าใจวัตถุประสงค์ของโพรบความพร้อมใช้งาน (และความพร้อม) และการใช้งานที่ถูกต้อง ดังนั้น เขาจึงรวบรวมความคิดของเขาไว้ในบันทึกอันกว้างขวางนี้ ซึ่งในที่สุดจะกลายเป็นส่วนหนึ่งของเอกสารของ K8

การตรวจสอบความมีชีวิตชีวาใน Kubernetes อาจเป็นอันตรายได้

การตรวจสุขภาพ หรือที่เรียกใน Kubernetes ว่า โพรบความมีชีวิตชีวา (เช่น แท้จริงแล้ว “การทดสอบความมีชีวิต” - การแปลโดยประมาณ)ค่อนข้างจะเป็นอันตรายได้ ฉันแนะนำให้หลีกเลี่ยงหากเป็นไปได้: ข้อยกเว้นเพียงอย่างเดียวคือเมื่อมีความจำเป็นจริงๆ และคุณตระหนักดีถึงลักษณะเฉพาะและผลที่ตามมาของการใช้งาน เอกสารนี้จะพูดถึงการตรวจสอบความสดและความพร้อม และจะแจ้งให้คุณทราบในกรณีใดบ้าง เป็น และคุณไม่ควรใช้มัน

Sandor เพื่อนร่วมงานของฉันได้แชร์บน Twitter ถึงข้อผิดพลาดที่พบบ่อยที่สุดที่เขาพบ รวมถึงข้อผิดพลาดที่เกี่ยวข้องกับการใช้การตรวจสอบความพร้อม/ความมีชีวิตชีวา:

การตรวจสอบความมีชีวิตชีวาใน Kubernetes อาจเป็นอันตรายได้

กำหนดค่าไม่ถูกต้อง livenessProbe สามารถทำให้สถานการณ์ที่มีการโหลดสูงรุนแรงขึ้น (การปิดระบบสโนว์บอล + เวลาเริ่มต้นคอนเทนเนอร์/แอปพลิเคชันที่อาจยาวนาน) และนำไปสู่ผลกระทบด้านลบอื่นๆ เช่น การพึ่งพาลดลง (ดูสิ่งนี้ด้วย บทความล่าสุดของฉัน เกี่ยวกับการจำกัดจำนวนคำขอในชุดค่าผสม K3s+ACME). จะแย่ไปกว่านั้นอีกเมื่อรวมการตรวจสอบความสดเข้ากับการตรวจสุขภาพซึ่งเป็นฐานข้อมูลภายนอก: ความล้มเหลวของ DB เพียงครั้งเดียวจะรีสตาร์ทคอนเทนเนอร์ทั้งหมดของคุณ!

ข้อความทั่วไป "อย่าใช้เครื่องตรวจสอบความมีชีวิตชีวา" ในกรณีนี้ก็ไม่ได้ช่วยอะไรมาก มาดูกันว่าการตรวจสอบความพร้อมและความสดมีไว้เพื่ออะไร

หมายเหตุ: การทดสอบด้านล่างส่วนใหญ่เดิมรวมอยู่ในเอกสารสำหรับนักพัฒนาภายในของ Zalando

การตรวจสอบความพร้อมและความมีชีวิตชีวา

Kubernetes มีกลไกสำคัญสองกลไกที่เรียกว่า การสอบสวนความมีชีวิตชีวาและการสอบสวนความพร้อม. โดยจะดำเนินการบางอย่างเป็นระยะๆ เช่น การส่งคำขอ HTTP การเปิดการเชื่อมต่อ TCP หรือดำเนินการคำสั่งในคอนเทนเนอร์ เพื่อยืนยันว่าแอปพลิเคชันทำงานตามที่คาดไว้

การใช้งาน 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

แนะนำ

  1. สำหรับไมโครเซอร์วิสที่มีจุดสิ้นสุด HTTP (REST ฯลฯ) กำหนดการสอบสวนความพร้อมเสมอซึ่งจะตรวจสอบว่าแอปพลิเคชัน (พ็อด) พร้อมที่จะรับการรับส่งข้อมูลหรือไม่
  2. ตรวจสอบให้แน่ใจว่ามีการสอบสวนความพร้อม ครอบคลุมความพร้อมใช้งานของพอร์ตเว็บเซิร์ฟเวอร์จริง:
    • การใช้พอร์ตเพื่อวัตถุประสงค์ในการดูแลระบบ เรียกว่า "ผู้ดูแลระบบ" หรือ "การจัดการ" (เช่น 9090) สำหรับ readinessProbeตรวจสอบให้แน่ใจว่าปลายทางส่งคืนค่า OK หากพอร์ต HTTP หลัก (เช่น 8080) พร้อมที่จะรับการรับส่งข้อมูล*;

      *ฉันทราบอย่างน้อยหนึ่งกรณีที่ Zalando ซึ่งเหตุการณ์นี้ไม่เกิดขึ้น กล่าวคือ readinessProbe ฉันตรวจสอบพอร์ต "การจัดการ" แล้ว แต่ตัวเซิร์ฟเวอร์เองไม่ได้เริ่มทำงานเนื่องจากปัญหาในการโหลดแคช

    • การติดโพรบความพร้อมเข้ากับพอร์ตแยกต่างหากอาจทำให้โอเวอร์โหลดบนพอร์ตหลักจะไม่สะท้อนให้เห็นในการตรวจสอบสภาพ (นั่นคือ เธรดพูลบนเซิร์ฟเวอร์เต็ม แต่การตรวจสอบสภาพยังคงแสดงให้เห็นว่าทุกอย่างเรียบร้อยดี ).
  3. ทำให้เเน่นอน การสอบสวนความพร้อมเปิดใช้งานการเริ่มต้น/การย้ายฐานข้อมูล;
    • วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการติดต่อเซิร์ฟเวอร์ HTTP หลังจากการกำหนดค่าเริ่มต้นเสร็จสมบูรณ์แล้วเท่านั้น (เช่น การย้ายฐานข้อมูลจาก ฟลายเวย์ และอื่นๆ.); นั่นคือ แทนที่จะเปลี่ยนสถานะการตรวจสอบสภาพ อย่าเริ่มเว็บเซิร์ฟเวอร์จนกว่าการย้ายฐานข้อมูลจะเสร็จสิ้น*

      * คุณยังสามารถเรียกใช้การย้ายฐานข้อมูลจากคอนเทนเนอร์เริ่มต้นภายนอกพ็อดได้ ฉันยังคงเป็นแฟนตัวยงของแอปพลิเคชันที่มีอยู่ในตัวเองนั่นคือแอปพลิเคชันที่คอนเทนเนอร์ของแอปพลิเคชันรู้วิธีนำฐานข้อมูลเข้าสู่สถานะที่ต้องการโดยไม่ต้องมีการประสานงานจากภายนอก

  4. ใช้ httpGet เพื่อตรวจความพร้อมผ่านจุดตรวจสุขภาพทั่วไป (เช่น /health).
  5. ทำความเข้าใจกับพารามิเตอร์การตรวจสอบเริ่มต้น (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • ตัวเลือกเริ่มต้นหมายความว่าพ็อดจะกลายเป็น ไม่พร้อม หลังจากนั้นประมาณ 30 วินาที (การตรวจสอบสุขภาพจิตล้มเหลว 3 ครั้ง)
  6. ใช้พอร์ตแยกต่างหากสำหรับ "ผู้ดูแลระบบ" หรือ "การจัดการ" หากกลุ่มเทคโนโลยี (เช่น Java/Spring) อนุญาต เพื่อแยกการจัดการสุขภาพและตัวชี้วัดออกจากการรับส่งข้อมูลปกติ:
    • แต่อย่าลืมข้อ 2 ด้วย
  7. หากจำเป็น สามารถใช้หัววัดความพร้อมเพื่ออุ่นเครื่อง/โหลดแคชและส่งคืนรหัสสถานะ 503 จนกว่าคอนเทนเนอร์จะอุ่นขึ้น:
    • ฉันขอแนะนำให้คุณอ่านเช็คใหม่ด้วย startupProbe, ปรากฏในเวอร์ชัน 1.16 (เราเขียนเกี่ยวกับเรื่องนี้เป็นภาษารัสเซีย ที่นี่ - ประมาณ แปล.).

ข้อควรระวัง

  1. อย่าพึ่งพาการพึ่งพาภายนอก (เช่น คลังข้อมูล) เมื่อรันการทดสอบความพร้อม/ความพร้อมใช้งาน ซึ่งอาจนำไปสู่ความล้มเหลวแบบเรียงซ้อน:
    • ตามตัวอย่าง ลองใช้บริการ REST stateful ที่มี 10 พ็อดขึ้นอยู่กับฐานข้อมูล Postgres หนึ่งฐานข้อมูล: เมื่อการตรวจสอบขึ้นอยู่กับการเชื่อมต่อที่ใช้งานได้กับ DB พ็อดทั้ง 10 พ็อดอาจล้มเหลวหากมีความล่าช้าในเครือข่าย/ฝั่ง DB - โดยปกติแล้ว ทุกอย่างจบลงเลวร้ายเกินกว่าจะเป็นไปได้
    • โปรดทราบว่า Spring Data จะตรวจสอบการเชื่อมต่อฐานข้อมูลตามค่าเริ่มต้น*;

      * นี่เป็นพฤติกรรมเริ่มต้นของ Spring Data Redis (อย่างน้อยก็เป็นครั้งสุดท้ายที่ฉันตรวจสอบ) ซึ่งนำไปสู่ความล้มเหลว "หายนะ": เมื่อ Redis ไม่พร้อมใช้งานในช่วงเวลาสั้น ๆ พ็อดทั้งหมดจะ "ขัดข้อง"

    • “ภายนอก” ในแง่นี้ยังหมายถึงพ็อดอื่นๆ ของแอปพลิเคชันเดียวกัน กล่าวคือ ตามหลักการแล้ว การตรวจสอบไม่ควรขึ้นอยู่กับสถานะของพ็อดอื่นๆ ในคลัสเตอร์เดียวกันเพื่อป้องกันการแครชแบบเรียงซ้อน:
      • ผลลัพธ์อาจแตกต่างกันไปสำหรับแอปพลิเคชันที่มีสถานะแบบกระจาย (เช่น การแคชในหน่วยความจำในพ็อด)
  2. อย่าใช้เครื่องตรวจสอบความมีชีวิตชีวา สำหรับพ็อด (ข้อยกเว้นคือกรณีที่จำเป็นจริงๆ และคุณตระหนักดีถึงลักษณะเฉพาะและผลที่ตามมาของการใช้งาน):
    • การตรวจสอบความมีชีวิตชีวาสามารถช่วยกู้คืนคอนเทนเนอร์ที่ค้างได้ แต่เนื่องจากคุณสามารถควบคุมแอปพลิเคชันของคุณได้อย่างสมบูรณ์ สิ่งต่างๆ เช่น กระบวนการที่หยุดทำงานและการหยุดชะงักไม่ควรเกิดขึ้น ทางเลือกที่ดีที่สุดคือจงใจทำให้แอปพลิเคชันเสียหายและนำแอปพลิเคชันกลับสู่สถานะคงที่ก่อนหน้านี้
    • การสอบสวนความสดที่ล้มเหลวจะทำให้คอนเทนเนอร์รีสตาร์ท ซึ่งอาจส่งผลให้ผลที่ตามมาจากข้อผิดพลาดที่เกี่ยวข้องกับการโหลดรุนแรงขึ้น: การรีสตาร์ทคอนเทนเนอร์จะส่งผลให้เกิดการหยุดทำงาน (อย่างน้อยในช่วงระยะเวลาของการเริ่มต้นแอปพลิเคชัน กล่าวคือ 30 วินาทีคี่) ทำให้เกิดข้อผิดพลาดใหม่ การเพิ่มภาระบนคอนเทนเนอร์อื่น ๆ และเพิ่มโอกาสที่จะเกิดความล้มเหลว ฯลฯ
    • การตรวจสอบความสดรวมกับการขึ้นต่อกันภายนอกเป็นการผสมผสานที่แย่ที่สุดที่เป็นไปได้ ซึ่งคุกคามความล้มเหลวแบบเรียงซ้อน: ความล่าช้าเล็กน้อยในฝั่งฐานข้อมูลจะนำไปสู่การรีสตาร์ทคอนเทนเนอร์ทั้งหมดของคุณ!
  3. พารามิเตอร์ของการตรวจสอบความสดและความพร้อม จะต้องแตกต่าง:
    • คุณสามารถใช้เครื่องมือตรวจสอบความมีชีวิตชีวาด้วยการตรวจสุขภาพแบบเดียวกัน แต่มีเกณฑ์การตอบสนองที่สูงกว่า (failureThreshold) เช่น กำหนดสถานะ ไม่พร้อม หลังจากพยายาม 3 ครั้ง และพิจารณาว่าโพรบความสดล้มเหลวหลังจากพยายาม 10 ครั้ง
  4. อย่าใช้การตรวจสอบ execเนื่องจากมีความเกี่ยวข้องกับปัญหาที่ทราบซึ่งนำไปสู่การปรากฏตัวของกระบวนการซอมบี้:

สรุป

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

การตรวจสอบความมีชีวิตชีวาใน Kubernetes อาจเป็นอันตรายได้

วัสดุเพิ่มเติมในหัวข้อ

อัปเดตครั้งที่ 1 จาก 2019-09-29

เกี่ยวกับคอนเทนเนอร์เริ่มต้นสำหรับการย้ายฐานข้อมูล: เพิ่มเชิงอรรถแล้ว

อีเจเตือนฉัน เกี่ยวกับ PDB: ปัญหาประการหนึ่งของการตรวจสอบความสดคือการขาดการประสานงานระหว่างพ็อด Kubernetes ก็มี งบประมาณการหยุดชะงักของพ็อด (PDB) เพื่อจำกัดจำนวนความล้มเหลวที่เกิดขึ้นพร้อมกันที่แอปพลิเคชันสามารถประสบได้ อย่างไรก็ตาม การตรวจสอบจะไม่คำนึงถึง PDB ตามหลักการแล้ว เราสามารถบอก K8 ให้ "รีสตาร์ทหนึ่งพ็อดหากการทดสอบล้มเหลว แต่อย่ารีสตาร์ททั้งหมดเพื่อหลีกเลี่ยงไม่ให้สิ่งที่แย่ลง"

ไบรอันพูดได้อย่างสมบูรณ์แบบ: “ใช้การตรวจสอบความมีชีวิตชีวาเมื่อคุณรู้ว่าอะไรชัดเจน สิ่งที่ดีที่สุดที่ต้องทำคือการฆ่าแอปพลิเคชัน“(ย้ำอีกครั้งว่าอย่าถูกพาไป)

การตรวจสอบความมีชีวิตชีวาใน Kubernetes อาจเป็นอันตรายได้

อัปเดตครั้งที่ 2 จาก 2019-09-29

เกี่ยวกับการอ่านเอกสารก่อนใช้งาน: ฉันสร้างคำขอที่เกี่ยวข้อง (คำขอคุณสมบัติ) เพื่อเพิ่มเอกสารประกอบเกี่ยวกับโพรบ liveness

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

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

ที่มา: will.com

เพิ่มความคิดเห็น