ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

วันนี้ฉันวางแผนที่จะพูดคุยเกี่ยวกับวิธีเขียนแอปพลิเคชันและข้อกำหนดเพื่อให้แอปพลิเคชันของคุณทำงานได้ดีใน Kubernetes เพื่อจะได้ไม่ต้องปวดหัวกับแอปพลิเคชัน เพื่อที่คุณจะได้ไม่ต้องประดิษฐ์และสร้าง "ช่องโหว่" รอบๆ ตัวมัน - และทุกอย่างก็เป็นไปตามที่ Kubernetes ตั้งใจไว้

การบรรยายนี้เป็นส่วนหนึ่งของ "Slurm Night School บน Kubernetes" คุณสามารถดูการบรรยายภาคทฤษฎีแบบเปิดของโรงเรียนภาคค่ำ บน Youtube โดยจัดกลุ่มเป็นเพลย์ลิสต์. สำหรับผู้ที่ชื่นชอบข้อความมากกว่าวิดีโอ เราได้เตรียมบทความนี้ไว้แล้ว

ฉันชื่อ Pavel Selivanov ปัจจุบันเป็นวิศวกร DevOps ชั้นนำที่ Mail.ru Cloud Solutions เราสร้างคลาวด์ เราสร้าง kubernetes การจัดการ และอื่นๆ งานของฉันตอนนี้รวมถึงการให้ความช่วยเหลือในการพัฒนา การเปิดตัวคลาวด์เหล่านี้ การเปิดตัวแอปพลิเคชันที่เราเขียน และพัฒนาเครื่องมือที่เรามอบให้กับผู้ใช้โดยตรง

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

ฉันทำ DevOps มาตลอด ฉันคิดว่าน่าจะสามปีแล้ว แต่โดยหลักการแล้ว ฉันทำสิ่งที่ DevOps ทำมาประมาณห้าปีแล้ว ก่อนหน้านั้นฉันเกี่ยวข้องกับผู้ดูแลระบบเป็นส่วนใหญ่ ฉันเริ่มทำงานกับ Kubernetes เมื่อนานมาแล้ว - อาจผ่านไปประมาณสี่ปีแล้วนับตั้งแต่ฉันเริ่มทำงาน

โดยทั่วไปแล้ว ฉันเริ่มต้นเมื่อ Kubernetes เป็นเวอร์ชัน 1.3 หรืออาจจะเป็น 1.2 ก็ได้ ตอนที่มันยังอยู่ในช่วงเริ่มต้น ตอนนี้มันไม่ได้อยู่ในวัยเด็กอีกต่อไป - และเห็นได้ชัดว่ามีความต้องการอย่างมากในตลาดสำหรับวิศวกรที่ต้องการทำ Kubernetes และบริษัทต่างๆ ก็มีความต้องการคนประเภทนี้สูงมาก ดังนั้นการบรรยายครั้งนี้จึงเกิดขึ้นจริง

ถ้าเราพูดถึงแผนของสิ่งที่ฉันจะพูดถึงจะมีลักษณะเช่นนี้ในวงเล็บเขียนไว้ (TL;DR) - "ยาวเกินไป; อย่าอ่าน" การนำเสนอของฉันวันนี้จะประกอบด้วยรายการไม่รู้จบ

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

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

เพราะโดยส่วนใหญ่แล้ว ข้อมูลนี้คือ “ctrl+c, ctrl+v” เหนือสิ่งอื่นใดคือ Wiki ของเราในส่วน DevOps ซึ่งเราได้เขียนข้อกำหนดสำหรับนักพัฒนา: “พวกคุณ เพื่อให้เราเปิดแอปพลิเคชันของคุณใน Kubernetes มันควรจะเป็นแบบนี้"

นั่นเป็นสาเหตุที่ทำให้การนำเสนอกลายเป็นรายการจำนวนมาก ขอโทษ. ฉันจะพยายามเล่าให้มากที่สุดเพื่อไม่ให้น่าเบื่อถ้าเป็นไปได้

สิ่งที่เราจะดูตอนนี้:

  • ประการแรกคือบันทึก (บันทึกแอปพลิเคชัน) จะทำอย่างไรกับพวกเขาใน Kubernetes จะทำอย่างไรกับพวกเขา สิ่งที่พวกเขาควรจะเป็น;
  • จะทำอย่างไรกับการกำหนดค่าใน Kubernetes อะไรคือวิธีที่ดีที่สุดและแย่ที่สุดในการกำหนดค่าแอปพลิเคชันสำหรับ Kubernetes
  • เรามาพูดถึงการตรวจสอบการช่วยสำหรับการเข้าถึงโดยทั่วไปว่าเป็นอย่างไร และควรมีลักษณะอย่างไร
  • เรามาพูดถึงการปิดระบบอย่างสง่างามกันดีกว่า
  • มาพูดถึงทรัพยากรกันอีกครั้ง
  • มาพูดถึงหัวข้อการจัดเก็บข้อมูลกันอีกครั้ง
  • และในตอนท้ายฉันจะบอกคุณว่าแอปพลิเคชันบนคลาวด์เนทีฟอันลึกลับนี้คืออะไร Cloudnativeness เป็นคำคุณศัพท์ของคำนี้

บันทึก

ฉันขอแนะนำให้เริ่มต้นด้วยบันทึก - โดยที่จำเป็นต้องบันทึกบันทึกเหล่านี้ใน Kubernetes ตอนนี้คุณได้เปิดตัวแอปพลิเคชันใน Kubernetes แล้ว ตามแบบคลาสสิก ก่อนหน้านี้แอปพลิเคชันจะเขียนบันทึกไว้ที่ใดที่หนึ่งในไฟล์เสมอ แอปพลิเคชันที่ไม่ดีเขียนบันทึกลงในไฟล์ในโฮมไดเร็กทอรีของนักพัฒนาที่เปิดตัวแอปพลิเคชัน แอปพลิเคชันที่ดีเขียนบันทึกลงในไฟล์ที่ไหนสักแห่งใน /var/log.

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

นอกจากนี้ ผู้ดูแลระบบที่ดีจึงมีบางสิ่งที่กำหนดค่าไว้ในโครงสร้างพื้นฐานที่บันทึกเหล่านี้สามารถหมุนเวียนได้ - rsyslog เดียวกันซึ่งดูบันทึกเหล่านี้และเมื่อมีบางอย่างเกิดขึ้นกับบันทึกเหล่านั้น มีจำนวนมาก สร้างสำเนาสำรอง วางบันทึกไว้ที่นั่น , ลบไฟล์เก่า, มากกว่าหนึ่งสัปดาห์, หกเดือน และอื่นๆ อีกมากมาย ตามทฤษฎีแล้ว เราควรมีข้อกำหนดเพื่อให้เพียงเพราะแอปพลิเคชันเขียนบันทึก พื้นที่บนเซิร์ฟเวอร์ที่ใช้งานจริง (เซิร์ฟเวอร์ต่อสู้?) จึงไม่หมด และด้วยเหตุนี้ การผลิตทั้งหมดจึงไม่ได้หยุดลงเนื่องจากท่อนไม้

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

ปรากฎว่าถ้าเราพูดถึง Kubernetes สถานที่ที่เหมาะสมในการเขียนบันทึกจากคอนเทนเนอร์นักเทียบท่าก็คือการเขียนบันทึกจากแอปพลิเคชันไปยังสิ่งที่เรียกว่า Stdout/Stderr ซึ่งก็คือสตรีมเอาต์พุตมาตรฐานของระบบปฏิบัติการ เอาต์พุตข้อผิดพลาดมาตรฐาน นี่เป็นวิธีที่ถูกต้องที่สุด ง่ายที่สุด และสมเหตุสมผลที่สุดในการวางบันทึกในหลักการใน Docker และโดยเฉพาะใน Kubernetis เพราะหากแอปพลิเคชันของคุณเขียนบันทึกไปยัง Stdout/Stderr ก็ขึ้นอยู่กับ Docker และโปรแกรมเสริม Kubernetes ที่จะตัดสินใจว่าจะทำอย่างไรกับบันทึกเหล่านี้ นักเทียบท่าจะสร้างไฟล์พิเศษในรูปแบบ JSON ตามค่าเริ่มต้น

มีคำถามเกิดขึ้น คุณจะทำอย่างไรต่อไปกับบันทึกเหล่านี้ วิธีที่ง่ายที่สุดคือชัดเจนเรามีความสามารถที่จะทำ kubectl logs และดูบันทึกของ "ฝัก" เหล่านี้ แต่อาจไม่ใช่ตัวเลือกที่ดีนัก - ต้องทำอย่างอื่นกับบันทึก

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

เราต้องการเครื่องมือบางอย่างในลักษณะที่เป็นมิตร ซึ่งจะนำบันทึกเหล่านี้ที่นักเทียบท่าของเราใส่ไว้ในไฟล์และส่งไปที่อื่น โดยทั่วไปแล้ว เรามักจะเปิดตัวเอเจนต์บางประเภทภายใน Kubernetes ในรูปแบบของ DaemonSet ซึ่งเป็นตัวรวบรวมบันทึก ซึ่งจะบอกได้ง่ายๆ ว่าบันทึกที่ Docker รวบรวมนั้นอยู่ที่ไหน และตัวแทนรวบรวมรายนี้ก็พาพวกเขาไปบางทีอาจแยกวิเคราะห์พวกเขาไปพร้อมกันบางทีอาจเพิ่มคุณค่าให้กับพวกเขาด้วยข้อมูลเมตาเพิ่มเติมและท้ายที่สุดก็ส่งพวกเขาไปจัดเก็บที่ไหนสักแห่ง ความหลากหลายมีอยู่แล้วที่นั่น สิ่งที่พบบ่อยที่สุดคือ Elasticsearch ซึ่งคุณสามารถจัดเก็บบันทึกและเรียกค้นได้จากที่นั่นอย่างสะดวก จากนั้น เมื่อใช้คำขอ เช่น การใช้ Kibana สร้างกราฟตามกราฟ สร้างการแจ้งเตือนตามกราฟ เป็นต้น

แนวคิดที่สำคัญที่สุดที่ฉันต้องการทำซ้ำอีกครั้งคือภายใน Docker โดยเฉพาะภายใน Kubernetes การจัดเก็บบันทึกของคุณในไฟล์เป็นความคิดที่แย่มาก

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

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

ประเด็นต่อไป ฉันต้องการพูดคุยเกี่ยวกับเรื่องนี้อีกครั้ง เนื่องจากเรากำลังพูดถึงหัวข้อบันทึก จึงเป็นการดีที่จะพูดคุยเกี่ยวกับลักษณะของบันทึกเพื่อให้สะดวกในการทำงานกับบันทึก อย่างที่ฉันบอกไปแล้ว หัวข้อนี้ไม่เกี่ยวข้องโดยตรงกับ Kubernetes แต่เกี่ยวข้องกับหัวข้อของ DevOps เป็นอย่างดี ในหัวข้อวัฒนธรรมการพัฒนาและมิตรภาพระหว่างสองแผนกที่แตกต่างกัน - Dev และ Ops เพื่อให้ทุกคนสบายใจ

ซึ่งหมายความว่า ตามหลักการแล้ว บันทึกควรเขียนในรูปแบบ JSON ในปัจจุบัน หากคุณมีแอปพลิเคชันของคุณเองที่เข้าใจยากซึ่งเขียนบันทึกในรูปแบบที่เข้าใจไม่ได้เนื่องจากคุณแทรกการพิมพ์บางประเภทหรืออะไรทำนองนั้นก็ถึงเวลาที่ต้องใช้ Google เฟรมเวิร์กบางประเภทซึ่งเป็น wrapper บางชนิดที่ช่วยให้คุณใช้การบันทึกตามปกติ เปิดใช้งานพารามิเตอร์การบันทึกใน JSON ที่นั่น เนื่องจาก JSON เป็นรูปแบบที่เรียบง่าย การแยกวิเคราะห์จึงเป็นเรื่องง่าย

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

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

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

แต่การติดตามสแต็กจะเป็นบันทึกแบบหลายบรรทัดเสมอและจะหลีกเลี่ยงได้อย่างไร คำถามที่นี่คือบันทึกคือบันทึกของเหตุการณ์ และจริงๆ แล้ว sactrace ไม่ใช่บันทึก หากเรารวบรวมบันทึกและวางไว้ที่ไหนสักแห่งใน Elasticsearch แล้ววาดกราฟจากบันทึกเหล่านั้น สร้างรายงานกิจกรรมผู้ใช้บนไซต์ของคุณ จากนั้นเมื่อคุณได้รับ Stack Trace นั่นหมายความว่ามีบางสิ่งที่ไม่คาดคิดเกิดขึ้น สถานการณ์ที่ไม่สามารถจัดการได้ในแอปพลิเคชันของคุณ และมันก็สมเหตุสมผลที่จะอัปโหลดการติดตามสแต็กไปยังระบบที่สามารถติดตามได้โดยอัตโนมัติ

นี่คือซอฟต์แวร์ (Sentry เดียวกัน) ที่สร้างขึ้นเพื่อทำงานกับการติดตามสแต็กโดยเฉพาะ โดยสามารถสร้างงานอัตโนมัติได้ทันที มอบหมายงานให้กับบุคคลอื่น แจ้งเตือนเมื่อ Sacttrace เกิดขึ้น จัดกลุ่ม Sacttrace เหล่านี้ตามประเภทเดียว และอื่นๆ โดยหลักการแล้ว มันไม่สมเหตุสมผลเลยที่จะพูดถึง sactraces เมื่อเราพูดถึงบันทึก เพราะท้ายที่สุดแล้วสิ่งเหล่านี้ต่างกันและมีวัตถุประสงค์ต่างกัน

องค์ประกอบ

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

ในความคิดของฉันนักเทียบท่าเป็นเรื่องของมาตรฐาน และมีมาตรฐานสำหรับแทบทุกอย่าง: มาตรฐานสำหรับการสร้างแอปพลิเคชันของคุณ มาตรฐานสำหรับการติดตั้งแอปพลิเคชันของคุณ

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

และสิ่งนี้ - เราใช้มันมาก่อน มันเพิ่งได้รับความนิยมเป็นพิเศษเมื่อมีคอนเทนเนอร์เข้ามา - สิ่งนี้เรียกว่าตัวแปร ENV (สภาพแวดล้อม) นั่นคือตัวแปรสภาพแวดล้อมที่อยู่ในระบบปฏิบัติการของคุณ โดยทั่วไป นี่เป็นวิธีที่เหมาะสมอย่างยิ่งในการกำหนดค่าแอปพลิเคชันของคุณ เพราะหากคุณมีแอปพลิเคชันใน JAVA, Python, Go, Perl, God forbid และแอปพลิเคชันเหล่านั้นสามารถอ่านโฮสต์ฐานข้อมูล ผู้ใช้ฐานข้อมูล ตัวแปรรหัสผ่านฐานข้อมูลได้ ก็เหมาะอย่างยิ่ง คุณมีแอปพลิเคชันในสี่ภาษาที่แตกต่างกันซึ่งกำหนดค่าในแผนฐานข้อมูลในลักษณะเดียวกัน ไม่มีการกำหนดค่าที่แตกต่างกันอีกต่อไป

ทุกอย่างสามารถกำหนดค่าได้โดยใช้ตัวแปร ENV เมื่อเราพูดถึง Kubernetes มีวิธีที่ดีในการประกาศตัวแปร ENV ภายใน Deployment ดังนั้น หากเรากำลังพูดถึงข้อมูลลับ เราก็สามารถส่งข้อมูลลับจากตัวแปร ENV (รหัสผ่านไปยังฐานข้อมูล ฯลฯ) ไปยังข้อมูลลับได้ทันที สร้างคลัสเตอร์ลับและระบุในคำอธิบาย ENV ในการปรับใช้ว่าเราไม่ได้ประกาศโดยตรง ค่าของตัวแปรนี้และค่าของตัวแปรรหัสผ่านฐานข้อมูลนี้จะถูกอ่านจากข้อมูลลับ นี่เป็นพฤติกรรมมาตรฐานของ Kubernetes และนี่คือตัวเลือกที่เหมาะสมที่สุดในการกำหนดค่าแอปพลิเคชันของคุณ ในระดับโค้ด สิ่งนี้ใช้ได้กับนักพัฒนาอีกครั้ง หากคุณเป็น DevOps คุณสามารถถามได้ว่า “เพื่อนๆ โปรดสอนแอปพลิเคชันของคุณให้อ่านตัวแปรสภาพแวดล้อมด้วย และเราทุกคนก็จะมีความสุข"

หากทุกคนในบริษัทอ่านตัวแปรสภาพแวดล้อมที่มีชื่อเหมือนกัน ก็ถือว่าดีมาก เพื่อไม่ให้เกิดขึ้นที่บางคนกำลังรอฐานข้อมูล postgres คนอื่นกำลังรอชื่อฐานข้อมูลคนอื่นกำลังรออย่างอื่นคนอื่นกำลังรอ dbn บางอย่างดังนั้นจึงมีความสม่ำเสมอ

ปัญหาเกิดขึ้นเมื่อคุณมีตัวแปรสภาพแวดล้อมมากมายจนคุณเพิ่งเปิด Deployment และมีตัวแปรสภาพแวดล้อมจำนวนห้าร้อยบรรทัด ในกรณีนี้ คุณมีตัวแปรสภาพแวดล้อมที่โตเกินไป และคุณไม่จำเป็นต้องทรมานตัวเองอีกต่อไป ในกรณีนี้ การเริ่มใช้การกำหนดค่าถือเป็นเรื่องสมเหตุสมผล นั่นคือฝึกแอปพลิเคชันของคุณให้ใช้การกำหนดค่า

คำถามเดียวก็คือการกำหนดค่าไม่ใช่สิ่งที่คุณคิด Config.pi ไม่ใช่การกำหนดค่าที่สะดวกในการใช้งาน หรือการกำหนดค่าบางอย่างในรูปแบบของคุณเอง หรือให้เป็นของขวัญ นี่ไม่ใช่การกำหนดค่าที่ฉันหมายถึงด้วย

สิ่งที่ฉันกำลังพูดถึงคือการกำหนดค่าในรูปแบบที่ยอมรับได้ กล่าวคือ มาตรฐานที่ได้รับความนิยมมากที่สุดคือมาตรฐาน .yaml วิธีอ่านก็ชัดเจน คนอ่านได้ วิธีอ่านก็ชัดเจนจากแอปพลิเคชัน

ดังนั้น นอกเหนือจาก YAML แล้ว คุณยังสามารถใช้ JSON ได้ การแยกวิเคราะห์ยังสะดวกพอๆ กับ YAML ในแง่ของการอ่านการกำหนดค่าแอปพลิเคชันจากที่นั่น ทำให้คนอ่านไม่สะดวกอย่างเห็นได้ชัด คุณสามารถลองใช้รูปแบบ a la ini การอ่านจากมุมมองของมนุษย์ค่อนข้างสะดวก แต่การประมวลผลโดยอัตโนมัติอาจไม่สะดวก ในแง่ที่ว่าหากคุณต้องการสร้างการกำหนดค่าของคุณเอง รูปแบบ ini อาจสร้างไม่สะดวกอยู่แล้ว

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

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

ฉันได้พูดไปแล้วเกี่ยวกับเรื่องนี้อีกครั้ง - ข้อมูลลับไม่อยู่ใน configmap ข้อมูลลับไม่อยู่ในตัวแปร ข้อมูลลับไม่อยู่ในความลับ จากนั้นเชื่อมโยงข้อมูลลับนี้เข้ากับการทูต โดยปกติแล้วเราจะจัดเก็บคำอธิบายทั้งหมดของออบเจ็กต์ Kubernetes, การปรับใช้, configmaps, บริการในรูปแบบ git ดังนั้น การใส่รหัสผ่านไปยังฐานข้อมูลใน git แม้ว่าจะเป็น git ของคุณซึ่งคุณมีภายในบริษัทก็ตาม ถือเป็นความคิดที่ไม่ดี เพราะอย่างน้อยที่สุด git จะจำทุกอย่างได้ และการถอดรหัสผ่านออกจากที่นั่นไม่ใช่เรื่องง่าย

ตรวจสุขภาพ

ประเด็นต่อไปคือสิ่งที่เรียกว่าการตรวจสุขภาพ โดยทั่วไป การตรวจสุขภาพเป็นเพียงการตรวจสอบว่าแอปพลิเคชันของคุณใช้งานได้ ในเวลาเดียวกันเรามักพูดถึงเว็บแอปพลิเคชันบางตัวซึ่งจากมุมมองของการตรวจสุขภาพ (ไม่ควรแปลที่นี่และต่อไป) นี่จะเป็น URL พิเศษบางส่วนซึ่งพวกเขาดำเนินการตาม เป็นมาตรฐาน พวกเขามักจะทำ /health.

เมื่อเข้าถึง URL นี้ แอปพลิเคชันของเราจะแจ้งว่า "ใช่ โอเค ทุกอย่างเรียบร้อยดีสำหรับฉัน 200" หรือ "ไม่ ทุกอย่างไม่ดีกับฉัน ประมาณ 500" ดังนั้น หากแอปพลิเคชันของเราไม่ใช่ http ไม่ใช่เว็บแอปพลิเคชัน ขณะนี้เรากำลังพูดถึง daemon บางประเภท เราก็สามารถหาวิธีตรวจสุขภาพได้ นั่นคือไม่จำเป็นหากแอปพลิเคชันไม่ใช่ http ทุกอย่างจะทำงานได้โดยไม่ต้องตรวจสุขภาพและไม่สามารถทำได้ แต่อย่างใด คุณสามารถอัปเดตข้อมูลบางอย่างในไฟล์ได้เป็นระยะๆ คุณสามารถสร้างคำสั่งพิเศษสำหรับ daemon ของคุณได้ เช่น daemon statusซึ่งจะบอกว่า “ใช่ ทุกอย่างเรียบร้อยดี เดมอนกำลังทำงาน มันยังมีชีวิตอยู่”

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

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

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

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

สิ่งที่ฉันกำลังพูดถึงตอนนี้เรียกว่าการทดสอบความพร้อม/ความมีชีวิตชีวาภายใน Kubernetes ดังนั้น การทดสอบความพร้อมของเราจึงรับผิดชอบต่อความพร้อมใช้งานของแอปพลิเคชันในการปรับสมดุล นั่นคือหากมีการทดสอบความพร้อมในแอปพลิเคชัน ทุกอย่างก็โอเค ปริมาณการใช้งานไคลเอ็นต์จะไปที่แอปพลิเคชัน หากไม่มีการทดสอบความพร้อม แอปพลิเคชันจะไม่เข้าร่วม อินสแตนซ์เฉพาะนี้ไม่มีส่วนร่วมในการปรับสมดุล จะถูกลบออกจากการปรับสมดุล ปริมาณการใช้ไคลเอ็นต์ไม่ไหล ดังนั้นจึงจำเป็นต้องมีการทดสอบ Liveness ภายใน Kubernetes เพื่อว่าหากแอปพลิเคชันค้าง ก็สามารถรีสตาร์ทได้ หากการทดสอบความสดใช้งานไม่ได้กับแอปพลิเคชันที่ประกาศใน Kubernetes แสดงว่าแอปพลิเคชันนั้นไม่เพียงแค่ถูกลบออกจากการปรับสมดุลเท่านั้น แต่ยังถูกรีสตาร์ทอีกด้วย

และนี่คือจุดสำคัญที่ฉันอยากจะพูดถึง: จากมุมมองเชิงปฏิบัติ การทดสอบความพร้อมมักจะใช้บ่อยกว่าและจำเป็นบ่อยกว่าการทดสอบความมีชีวิตชีวา กล่าวคือ การประกาศทั้งการทดสอบความพร้อมและการทดสอบความพร้อมใช้งานโดยไม่ได้ตั้งใจ เนื่องจาก Kubernetes สามารถทำเช่นนั้นได้ และลองใช้ทุกอย่างที่สามารถทำได้นั้นไม่ใช่ความคิดที่ดีนัก ฉันจะอธิบายว่าทำไม เนื่องจากประเด็นที่สองในการทดสอบคือ เป็นความคิดที่ดีที่จะตรวจสอบบริการที่เกี่ยวข้องในการตรวจสุขภาพของคุณ ซึ่งหมายความว่าหากคุณมีเว็บแอปพลิเคชันที่ให้ข้อมูลบางอย่าง ซึ่งแน่นอนว่าจะต้องดึงข้อมูลจากที่ไหนสักแห่ง ในฐานข้อมูล เป็นต้น มันจะบันทึกข้อมูลที่เข้ามาใน REST API นี้ลงในฐานข้อมูลเดียวกัน ดังนั้น หากการตรวจสุขภาพของคุณตอบสนองเหมือนกับการติดต่อกับ slashhealth แอปพลิเคชันจะแจ้งว่า “200 โอเค ทุกอย่างเรียบร้อยดี” และในขณะเดียวกันก็ไม่สามารถเข้าถึงฐานข้อมูลแอปพลิเคชันของคุณ และแอปพลิเคชันตรวจสุขภาพแจ้งว่า “200 โอเค ทุกอย่างเรียบร้อยดี” ” - นี่คือการตรวจสุขภาพที่ไม่ดี นี่ไม่ใช่วิธีที่มันควรจะทำงาน

นั่นคือใบสมัครของคุณเมื่อมีการร้องขอมาถึง /healthมันไม่เพียงแค่ตอบกลับว่า "200 โอเค" แต่ก่อนอื่นมันจะไปที่ฐานข้อมูล พยายามเชื่อมต่อกับมัน ทำบางสิ่งพื้นฐานที่นั่น เช่น เลือกหนึ่งรายการ เพียงตรวจสอบว่ามีการเชื่อมต่อใน ฐานข้อมูลและคุณสามารถสืบค้นฐานข้อมูลได้ หากทั้งหมดนี้ประสบความสำเร็จ คำตอบคือ “200 โอเค” หากไม่สำเร็จจะแจ้งว่ามีข้อผิดพลาดฐานข้อมูลไม่พร้อมใช้งาน

ดังนั้น ในเรื่องนี้ ฉันจึงกลับมาที่การทดสอบความพร้อม/ความมีชีวิตชีวาอีกครั้ง - เหตุใดคุณจึงต้องมีการทดสอบความพร้อมมากที่สุด แต่การทดสอบความมีชีวิตชีวายังเป็นที่น่าสงสัย เพราะถ้าคุณอธิบายการตรวจสุขภาพตรงตามที่ผมบอกไป ปรากฎว่าไม่มีในส่วนของอินสแตนซ์в или со всех instanceในฐานข้อมูล เป็นต้น เมื่อคุณประกาศการทดสอบความพร้อม การตรวจสุขภาพของเราเริ่มล้มเหลว และด้วยเหตุนี้แอปพลิเคชันทั้งหมดที่ไม่สามารถเข้าถึงฐานข้อมูล จึงถูกปิดจากการปรับสมดุล และในความเป็นจริง "หยุดทำงาน" เพียงอยู่ในสถานะที่ถูกละเลยและรอให้ฐานข้อมูลของพวกเขา งาน.

หากเราได้ประกาศการทดสอบความมีชีวิตชีวา ลองจินตนาการว่าฐานข้อมูลของเราเสียหาย และครึ่งหนึ่งของทุกอย่างใน Kubernetes ของคุณเริ่มรีสตาร์ทเนื่องจากการทดสอบความมีชีวิตชีวาล้มเหลว ซึ่งหมายความว่าคุณต้องรีสตาร์ท นี่ไม่ใช่สิ่งที่คุณต้องการเลย ฉันมีประสบการณ์ส่วนตัวในการฝึกฝนด้วยซ้ำ เรามีแอปพลิเคชันแชทที่เขียนด้วย JS และป้อนเข้าสู่ฐานข้อมูล Mongo และปัญหาก็คือว่าในช่วงเริ่มต้นทำงานกับ Kubernetes เราได้อธิบายความพร้อมและความมีชีวิตชีวาของการทดสอบบนหลักการที่ Kubernetes ทำได้ ดังนั้นเราจะใช้มัน ด้วยเหตุนี้ เมื่อถึงจุดหนึ่ง Mongo ก็ "น่าเบื่อ" เล็กน้อย และตัวอย่างก็เริ่มล้มเหลว จากการทดสอบความฝน ผลฝักจึงเริ่ม "ฆ่า"

อย่างที่คุณเข้าใจ เมื่อพวกเขา "ถูกฆ่า" นี่คือการแชท นั่นคือมีการเชื่อมต่อมากมายจากลูกค้าที่ค้างอยู่ พวกเขายัง "ถูกฆ่า" - ไม่ ไม่ใช่ไคลเอนต์ เฉพาะการเชื่อมต่อ - ไม่ใช่ทั้งหมดในเวลาเดียวกัน และเนื่องจากความจริงที่ว่าพวกเขาไม่ได้ถูกฆ่าในเวลาเดียวกัน บางส่วนก่อนหน้านี้ บางส่วนในภายหลัง พวกเขาไม่ได้เริ่มต้นในเวลาเดียวกัน เวลา. นอกจากการสุ่มแบบมาตรฐานแล้ว เราไม่สามารถคาดการณ์เวลาเริ่มต้นของแอปพลิเคชันในแต่ละครั้งด้วยความแม่นยำระดับมิลลิวินาทีได้ ดังนั้นจึงทำครั้งละหนึ่งอินสแตนซ์ จุดข้อมูลหนึ่งเพิ่มขึ้น ถูกเพิ่มเข้าไปในการทรงตัว ลูกค้าทุกคนมาที่นั่น ไม่สามารถทนต่อภาระดังกล่าวได้ เพราะมันอยู่คนเดียว และพูดคร่าวๆ ก็คือ มีคนหลายสิบคนทำงานที่นั่นและมันก็ล้มลง คนต่อไปลุกขึ้นภาระทั้งหมดตกอยู่ที่เขาเขาก็ล้มลงด้วย น้ำตกเหล่านี้ก็ยังคงลดหลั่นกันต่อไป ในท้ายที่สุด วิธีแก้ปัญหานี้ - เราเพียงแค่ต้องหยุดการรับส่งข้อมูลของผู้ใช้ไปยังแอปพลิเคชันนี้อย่างเคร่งครัด ปล่อยให้อินสแตนซ์ทั้งหมดเพิ่มขึ้น จากนั้นจึงเริ่มการรับส่งข้อมูลผู้ใช้ทั้งหมดในครั้งเดียวเพื่อให้มีการกระจายไปยังอินสแตนซ์ทั้ง XNUMX รายการแล้ว

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

ดังนั้นการทดสอบความพร้อมและความมีชีวิตชีวาจึงแตกต่างกัน ยิ่งไปกว่านั้น คุณยังสามารถตรวจสุขภาพที่แตกต่างกันในทางทฤษฎี เช่น รัศมีประเภทหนึ่ง liv ประเภทหนึ่ง และตรวจสอบสิ่งต่าง ๆ กัน ในระหว่างการทดสอบความพร้อม ให้ตรวจสอบแบ็กเอนด์ของคุณ และในการทดสอบความมีชีวิตชีวา คุณไม่ได้ตรวจสอบจากมุมมองว่าการทดสอบความมีชีวิตชีวาโดยทั่วไปเป็นเพียงการตอบสนองของแอปพลิเคชันเท่านั้น หากสามารถตอบสนองได้เลย

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

เกี่ยวกับสิ่งที่คุณต้องตอบเมื่อคุณมีการทดสอบ เมื่อคุณตรวจสุขภาพ มันเป็นความเจ็บปวดจริงๆ คนที่คุ้นเคยกับสิ่งนี้อาจจะหัวเราะ แต่จริงๆ แล้ว ฉันเคยเห็นบริการต่างๆ ในชีวิตที่ตอบ "200" ใน XNUMX% ของกรณีทั้งหมด นั่นคือผู้ที่ประสบความสำเร็จ แต่ในขณะเดียวกันในเนื้อหาของคำตอบพวกเขาเขียนว่า "ข้อผิดพลาดเช่นนั้น"

นั่นคือสถานะการตอบกลับจะมาถึงคุณ - ทุกอย่างสำเร็จ แต่ในเวลาเดียวกัน คุณต้องแยกวิเคราะห์เนื้อหา เนื่องจากเนื้อหาบอกว่า "ขออภัย คำขอจบลงด้วยข้อผิดพลาด" และนี่เป็นเพียงความจริง ฉันเห็นสิ่งนี้ในชีวิตจริง

และเพื่อให้บางคนไม่เห็นว่ามันเป็นเรื่องตลก และคนอื่นๆ พบว่ามันเจ็บปวดมาก ก็ยังคุ้มค่าที่จะปฏิบัติตามกฎง่ายๆ ในการตรวจสภาพและโดยหลักการเมื่อทำงานกับเว็บแอปพลิเคชัน

หากทุกอย่างเป็นไปด้วยดีให้ตอบคำตอบที่สองร้อย โดยหลักการแล้ว คำตอบที่สองในร้อยจะเหมาะกับคุณ หากคุณอ่าน ragsy ได้เป็นอย่างดีและรู้ว่าสถานะการตอบกลับบางสถานะแตกต่างจากสถานะอื่นๆ ให้ตอบด้วยสถานะที่เหมาะสม: 204, 5, 10, 15 อะไรก็ได้ ถ้ามันไม่ดีนักก็แค่ "สองศูนย์ศูนย์" หากทุกอย่างไปไม่ดีและการตรวจสุขภาพไม่ตอบสนอง ให้ตอบด้วยห้าในร้อย ขอย้ำอีกครั้ง หากคุณเข้าใจวิธีการตอบกลับ สถานะการตอบกลับที่แตกต่างกันจะแตกต่างกันอย่างไร หากคุณไม่เข้าใจ 502 คือตัวเลือกของคุณในการตอบสนองต่อการตรวจสุขภาพหากมีสิ่งผิดปกติเกิดขึ้น

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

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

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

ต่อไป เรายังมีปัญหาอันเจ็บปวดประการหนึ่งเมื่อเปิดแอปพลิเคชัน

ในความเป็นจริง สิ่งนี้ไม่เพียงนำไปใช้กับ Kubernetes โดยรวมเท่านั้น แต่ยังเกิดขึ้นเมื่อวัฒนธรรมของการพัฒนาจำนวนมากและโดยเฉพาะ DevOps เริ่มแพร่กระจายในช่วงเวลาเดียวกับ Kubernetes ดังนั้นโดยส่วนใหญ่แล้วปรากฎว่าคุณจำเป็นต้องปิดแอปพลิเคชันของคุณอย่างสวยงามโดยไม่ต้องใช้ Kubernetes แม้กระทั่งก่อน Kubernetes ผู้คนก็ทำเช่นนี้ แต่ด้วยการถือกำเนิดของ Kubernetes เราจึงเริ่มพูดถึงเรื่องนี้กันเป็นจำนวนมาก

การปิดระบบอย่างสง่างาม

โดยทั่วไป Graceful Shutdown คืออะไร และเหตุใดจึงจำเป็น นี่เป็นเรื่องเกี่ยวกับเวลาที่แอปพลิเคชันของคุณล่มด้วยเหตุผลบางประการ คุณต้องดำเนินการ app stop - หรือคุณได้รับ เช่น สัญญาณจากระบบปฏิบัติการ แอปพลิเคชันของคุณจะต้องเข้าใจและดำเนินการบางอย่างกับมัน แน่นอนว่าสถานการณ์กรณีที่เลวร้ายที่สุดคือเมื่อใบสมัครของคุณได้รับ SIGTERM และเป็นเหมือน “SIGTERM ลุยเลย ทำงาน ไม่ต้องทำอะไรเลย” นี่เป็นตัวเลือกที่แย่มาก

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

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

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

SIGTERM เป็น soft Shutdown ออกแบบมาเป็นพิเศษ สามารถดักจับได้ในระดับโค้ด สามารถประมวลผลได้ บอกว่าตอนนี้ เดี๋ยวก่อน เราจะทำงานที่เรามีให้เสร็จก่อน แล้วจึงออก

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

ที่นั่นเราสามารถพูดได้โดยเฉพาะว่าเราต้องรอนานแค่ไหนระหว่างเวลาที่เราส่ง SIGTERM ไปยังแอปพลิเคชัน และเมื่อเราเข้าใจว่าแอปพลิเคชันดูเหมือนจะคลั่งไคล้บางสิ่งบางอย่างหรือ "ติดขัด" และจะไม่สิ้นสุด - และเราจำเป็นต้อง ส่งมันไป SIGKILL นั่นคือทำงานให้สำเร็จอย่างหนัก นั่นคือดังนั้นเราจึงมี daemon บางชนิดที่ทำงานอยู่โดยจะประมวลผลการดำเนินการ เราเข้าใจดีว่าโดยเฉลี่ยแล้วการดำเนินการของเราที่ daemon ทำงานนั้นจะใช้เวลาไม่เกิน 30 วินาทีในแต่ละครั้ง ดังนั้น เมื่อ SIGTERM มาถึง เราเข้าใจว่า daemon ของเราสามารถเสร็จสิ้นหลังจาก SIGTERM ได้สูงสุด 30 วินาที เช่นเราเขียนไว้ 45 วินาทีเผื่อไว้ แล้วพูดว่า SIGTERM หลังจากนั้นเรารอ 45 วินาที ตามทฤษฎีแล้ว ในช่วงเวลานี้ ปีศาจควรทำงานให้เสร็จและจบลงเอง แต่หากจู่ๆ ไม่สามารถทำได้ แสดงว่ามีแนวโน้มว่าจะค้าง—ระบบจะไม่ดำเนินการตามคำขอของเราตามปกติอีกต่อไป และภายใน 45 วินาที คุณสามารถตอกตะปูเขาลงได้อย่างปลอดภัย

และที่นี่สามารถนำมาพิจารณาได้ 2 ด้านด้วยกัน ประการแรก เข้าใจว่าหากคุณได้รับคำขอ คุณจะเริ่มทำงานกับคำขอนั้นและไม่ได้ตอบกลับผู้ใช้ แต่คุณได้รับ SIGTERM เป็นต้น มันสมเหตุสมผลแล้วที่จะปรับแต่งและให้คำตอบกับผู้ใช้ นี่คือประเด็นอันดับหนึ่งในเรื่องนี้ ประเด็นที่สองคือ ถ้าคุณเขียนแอปพลิเคชันของคุณเอง โดยทั่วไปแล้วสร้างสถาปัตยกรรมในลักษณะที่คุณได้รับคำขอสำหรับแอปพลิเคชันของคุณ จากนั้น คุณจะเริ่มทำงาน เริ่มดาวน์โหลดไฟล์จากที่ไหนสักแห่ง ดาวน์โหลดฐานข้อมูล และอื่นๆ อีกมากมาย - ที่. โดยทั่วไปผู้ใช้ของคุณ คำขอของคุณจะหยุดทำงานเป็นเวลาครึ่งชั่วโมงและรอให้คุณตอบเขา - เป็นไปได้มากว่าคุณจะต้องทำงานเกี่ยวกับสถาปัตยกรรม นั่นคือ เพียงคำนึงถึงสามัญสำนึกด้วยว่าหากการดำเนินการของคุณสั้น ก็สมเหตุสมผลที่จะเพิกเฉยต่อ SIGTERM และแก้ไข หากการดำเนินการของคุณใช้เวลานาน ก็ไม่มีเหตุผลที่จะเพิกเฉยต่อ SIGTERM ในกรณีนี้ การออกแบบสถาปัตยกรรมใหม่เพื่อหลีกเลี่ยงการทำงานที่ยาวนานเช่นนี้จึงสมเหตุสมผล เพื่อให้ผู้ใช้ไม่เพียงแค่นั่งรอเฉยๆ ฉันไม่รู้ สร้าง websocket ตรงนั้น ทำ Reverse hooks ที่เซิร์ฟเวอร์ของคุณจะส่งไปยังไคลเอนต์แล้ว หรืออย่างอื่นก็ได้ แต่อย่าบังคับให้ผู้ใช้หยุดทำงานเป็นเวลาครึ่งชั่วโมงแล้วรอเซสชันจนกว่าคุณจะ ตอบเขา เพราะมันไม่อาจคาดเดาได้ว่ามันจะพังตรงไหน

เมื่อใบสมัครของคุณสิ้นสุดลง คุณควรระบุรหัสทางออกที่เหมาะสม นั่นคือหากแอปพลิเคชันของคุณถูกขอให้ปิด หยุด และสามารถหยุดได้ตามปกติ คุณไม่จำเป็นต้องส่งคืนรหัสทางออกบางประเภท 1,5,255 เป็นต้น สิ่งใดก็ตามที่ไม่ใช่รหัสศูนย์ อย่างน้อยในระบบ Linux ฉันมั่นใจในสิ่งนี้ ถือว่าไม่สำเร็จ นั่นคือถือว่าใบสมัครของคุณในกรณีนี้จบลงด้วยข้อผิดพลาด ดังนั้น ในทางที่เป็นมิตร หากใบสมัครของคุณเสร็จสมบูรณ์โดยไม่มีข้อผิดพลาด คุณจะพูดว่า 0 ที่เอาต์พุต หากแอปพลิเคชันของคุณล้มเหลวด้วยเหตุผลบางประการ คุณจะบอกว่าไม่ใช่ 0 ในเอาต์พุต และคุณสามารถทำงานกับข้อมูลนี้ได้

และตัวเลือกสุดท้าย เป็นเรื่องไม่ดีเมื่อผู้ใช้ของคุณส่งคำขอและหยุดทำงานเป็นเวลาครึ่งชั่วโมงในขณะที่คุณดำเนินการ แต่โดยทั่วไปแล้ว ฉันอยากจะพูดถึงสิ่งที่โดยทั่วไปแล้วคุ้มค่าจากฝั่งลูกค้าด้วย ไม่สำคัญว่าคุณจะมีแอปพลิเคชันบนมือถือ ส่วนหน้า ฯลฯ จำเป็นต้องคำนึงว่าโดยทั่วไปเซสชันของผู้ใช้สามารถยุติได้ อะไรก็เกิดขึ้นได้ คำขออาจถูกส่งไป เช่น ประมวลผลน้อยเกินไปและไม่มีการตอบกลับ ส่วนหน้าหรือแอปพลิเคชันมือถือของคุณ - โดยทั่วไปแล้ว ส่วนหน้าใด ๆ ก็ตาม - ควรคำนึงถึงเรื่องนี้ด้วย หากคุณทำงานกับ websockets นี่เป็นความเจ็บปวดที่เลวร้ายที่สุดที่ฉันเคยมี

เมื่อนักพัฒนาของการแชทปกติไม่ทราบ ปรากฎว่า websocket อาจพังได้ สำหรับพวกเขา เมื่อมีอะไรเกิดขึ้นที่พร็อกซี เราแค่เปลี่ยนการกำหนดค่า และมันจะโหลดซ้ำ โดยปกติแล้ว เซสชันที่มีอายุการใช้งานยาวนานทั้งหมดจะถูกขาดในกรณีนี้ นักพัฒนาซอฟต์แวร์วิ่งมาหาเราแล้วพูดว่า: "พวกคุณทำอะไรอยู่ แชทพังทลายเพื่อลูกค้าของเราทุกคน!" เราบอกพวกเขาว่า:“ คุณกำลังทำอะไรอยู่? ลูกค้าของคุณไม่สามารถเชื่อมต่อใหม่ได้หรือไม่? พวกเขาพูดว่า: “ไม่ เราต้องไม่ทำให้เซสชันขาดตอน” สรุปแล้วนี่เป็นเรื่องไร้สาระจริงๆ จะต้องคำนึงถึงฝั่งไคลเอ็นต์ด้วย โดยเฉพาะอย่างยิ่งอย่างที่ฉันพูดไป ด้วยเซสชันที่มีอายุการใช้งานยาวนาน เช่น เว็บซ็อกเก็ต เซสชันดังกล่าวอาจเสียหายได้ และคุณจะต้องติดตั้งเซสชันดังกล่าวใหม่โดยที่ผู้ใช้ไม่มีใครสังเกตเห็น แล้วทุกอย่างสมบูรณ์แบบ

Ресурсы

ที่จริงแล้วที่นี่ฉันจะเล่าเรื่องตรงให้คุณฟัง จากชีวิตจริงอีกครั้ง สิ่งที่แย่ที่สุดที่ฉันเคยได้ยินเกี่ยวกับทรัพยากร

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

เหตุใดจึงจำเป็นต้องใช้ทรัพยากรทั้งหมด? ทรัพยากรใน Kubernetes มี 2 ประเภท บางอย่างเรียกว่าคำขอ บางอย่างเรียกว่าขีดจำกัด ตามทรัพยากรเราจะเข้าใจว่าโดยพื้นฐานแล้วมีข้อ จำกัด พื้นฐานเพียงสองข้อเท่านั้น นั่นคือการจำกัดเวลาของ CPU และการจำกัด RAM สำหรับคอนเทนเนอร์ที่ทำงานใน Kubernetes

ขีดจำกัดจะกำหนดขีดจำกัดสูงสุดเกี่ยวกับวิธีการใช้ทรัพยากรในแอปพลิเคชันของคุณ นั่นคือหากคุณบอกว่า RAM เกินขีดจำกัด 1GB แอปพลิเคชันของคุณจะไม่สามารถใช้ RAM เกิน 1GB ได้ และหากจู่ๆ เขาต้องการและพยายามทำสิ่งนี้ กระบวนการที่เรียกว่า oom killer ซึ่งก็คือหน่วยความจำไม่เพียงพอจะมาและฆ่าแอปพลิเคชันของคุณ - นั่นคือมันจะรีสตาร์ทเอง แอปพลิเคชันจะไม่รีสตาร์ทตาม CPU ในแง่ของ CPU หากแอปพลิเคชันพยายามใช้งานจำนวนมากเกินกว่าที่กำหนดไว้ในขีดจำกัด CPU จะถูกเลือกอย่างเข้มงวด สิ่งนี้ไม่นำไปสู่การรีสตาร์ท นี่คือขีดจำกัด - นี่คือขีดจำกัดบน

และมีการร้องขอ คำขอคือวิธีที่ Kubernetes เข้าใจวิธีการเติมโหนดในคลัสเตอร์ Kubernetes ด้วยแอปพลิเคชัน นั่นคือคำขอถือเป็นการกระทำในใบสมัครของคุณ มันบอกว่าฉันต้องการใช้อะไร: “ฉันอยากให้คุณจอง CPU มากและหน่วยความจำมากนี้ให้ฉัน” การเปรียบเทียบง่ายๆ จะเป็นอย่างไรถ้าเรามีโหนดที่มี CPU ทั้งหมด 8 ตัว ฉันไม่รู้ และพ็อดมาถึงที่นั่น ซึ่งคำขอบอกว่ามี CPU 1 ตัว ซึ่งหมายความว่าโหนดเหลือ CPU อยู่ 7 ตัว นั่นคือทันทีที่ 8 พ็อดมาถึงโหนดนี้ ซึ่งแต่ละอันมี 1 CPU ในคำขอ โหนดนั้นราวกับว่าจากมุมมองของ Kubernetes CPU หมดและพ็อดเพิ่มเติมที่มีคำขอไม่สามารถ เปิดตัวบนโหนดนี้ หากโหนดทั้งหมด CPU หมด Kubernetes จะเริ่มบอกว่าไม่มีโหนดที่เหมาะสมในคลัสเตอร์ที่จะเรียกใช้พ็อดของคุณเนื่องจาก CPU หมด

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

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

การจัดเก็บข้อมูล

ประเด็นต่อไปของเราเกี่ยวกับการจัดเก็บข้อมูล จะทำอย่างไรกับพวกเขาและโดยทั่วไปแล้วจะทำอย่างไรกับความเพียรใน Kubernetes?

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

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

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

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

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

หากจู่ๆ ตัวเลือกในอุดมคตินี้ไม่เหมาะสม คุณมีแอปพลิเคชันที่คุณไม่ได้เขียน คุณไม่พัฒนา หรือเป็นมรดกที่แย่มาก ไม่สามารถใช้โปรโตคอล S3 ได้ แต่ต้องทำงานกับไดเร็กทอรีในเครื่อง โฟลเดอร์ในเครื่อง ใช้สิ่งที่ง่ายไม่มากก็น้อย ปรับใช้ Kubernetes นั่นคือการฟันดาบ Ceph ทันทีเพื่อทำงานเล็กๆ น้อยๆ บางอย่าง ดูเหมือนว่าเป็นความคิดที่ไม่ดี เพราะแน่นอนว่า Ceph เป็นคนดีและทันสมัย แต่ถ้าคุณไม่เข้าใจจริงๆ ว่าคุณกำลังทำอะไรอยู่ เมื่อคุณใส่อะไรบางอย่างลงบน Ceph คุณจะสามารถนำมันออกไปจากที่นั่นได้อย่างง่ายดายและง่ายดายอีกเลย เพราะอย่างที่คุณทราบ Ceph จัดเก็บข้อมูลไว้ในคลัสเตอร์ในรูปแบบไบนารี และไม่ใช่ในรูปแบบของไฟล์ธรรมดา ดังนั้น หากคลัสเตอร์ Ceph พังกะทันหัน ก็มีแนวโน้มที่สมบูรณ์และสูงที่คุณจะไม่ได้รับข้อมูลจากที่นั่นอีก

เราจะมีหลักสูตรเกี่ยวกับ Ceph คุณก็ทำได้ ทำความคุ้นเคยกับโปรแกรมและส่งใบสมัคร.

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

ประเด็นต่อไปที่ฉันพูดถึงคือต้องทำอย่างไรหากแอปพลิเคชันของคุณสร้างไฟล์บางไฟล์ระหว่างการดำเนินการ ตัวอย่างเช่น เมื่อเริ่มต้น จะสร้างไฟล์คงที่ซึ่งอิงตามข้อมูลบางอย่างที่แอปพลิเคชันได้รับเฉพาะตอนเปิดตัวเท่านั้น สักครู่นะ. หากมีข้อมูลดังกล่าวไม่มากนัก คุณก็ไม่ต้องกังวลเลย เพียงติดตั้งแอปพลิเคชันนี้เพื่อตัวคุณเองและทำงาน คำถามเดียวที่นี่คืออะไรดูสิ บ่อยครั้งมากที่ระบบเก่าทุกประเภท เช่น WordPress และอื่นๆ โดยเฉพาะอย่างยิ่งเมื่อมีการดัดแปลงปลั๊กอินที่ชาญฉลาด นักพัฒนา PHP ที่ชาญฉลาด พวกเขามักจะรู้วิธีสร้างมันเพื่อสร้างไฟล์บางประเภทสำหรับตัวเอง ดังนั้น ไฟล์หนึ่งจะสร้างไฟล์หนึ่งไฟล์ ไฟล์ที่สองจะสร้างไฟล์ที่สอง พวกเขาแตกต่าง. การปรับสมดุลเกิดขึ้นในคลัสเตอร์ Kubernetes ของลูกค้าโดยบังเอิญ ปรากฎว่าพวกเขาไม่รู้ว่าจะทำงานร่วมกันอย่างไร อันหนึ่งให้ข้อมูลหนึ่ง ส่วนอีกอันให้ข้อมูลอื่นแก่ผู้ใช้ นี่คือสิ่งที่คุณควรหลีกเลี่ยง นั่นคือใน Kubernetes ทุกสิ่งที่คุณเปิดตัวรับประกันว่าจะสามารถทำงานได้ในหลายอินสแตนซ์ เพราะ Kubernetes เป็นสิ่งที่เคลื่อนไหวได้ ดังนั้นเขาจึงสามารถย้ายอะไรก็ได้ทุกเมื่อที่ต้องการโดยไม่ต้องถามใครเลย ดังนั้นคุณต้องพึ่งพาสิ่งนี้ ทุกอย่างที่เปิดตัวในอินสแตนซ์เดียวจะล้มเหลวไม่ช้าก็เร็ว ยิ่งจองมากก็ยิ่งดี แต่ฉันขอย้ำอีกครั้งว่าหากคุณมีไฟล์ดังกล่าวอยู่สองสามไฟล์ คุณก็สามารถวางไว้ข้างใต้คุณได้ เพราะไฟล์เหล่านั้นมีน้ำหนักเพียงเล็กน้อย หากมีมากกว่านั้นอีกหน่อยก็ไม่ควรดันเข้าไปในภาชนะ

ฉันอยากจะแนะนำว่ามีสิ่งที่ยอดเยี่ยมเช่นนี้ใน Kubernetes คุณสามารถใช้โวลุ่มได้ โดยเฉพาะมีวอลุ่มประเภท dir ว่าง นั่นคือเพียง Kubernetes จะสร้างไดเร็กทอรีในไดเร็กทอรีบริการบนเซิร์ฟเวอร์ที่คุณเริ่มต้นโดยอัตโนมัติ และพระองค์จะทรงมอบมันให้กับคุณเพื่อให้คุณใช้มันได้ มีจุดสำคัญเพียงจุดเดียว นั่นคือข้อมูลของคุณจะไม่ถูกเก็บไว้ในคอนเทนเนอร์ แต่จะถูกเก็บไว้ในโฮสต์ที่คุณใช้งานอยู่ นอกจากนี้ Kubernetes ยังสามารถควบคุม dirs ว่างดังกล่าวภายใต้การกำหนดค่าปกติ และสามารถควบคุมขนาดสูงสุดและไม่อนุญาตให้เกินขนาดได้ ประเด็นเดียวคือสิ่งที่คุณเขียนใน dir ว่างจะไม่สูญหายระหว่างการรีสตาร์ทพ็อด นั่นคือหากพ็อดของคุณล้มลงโดยไม่ได้ตั้งใจและลุกขึ้นมาอีกครั้ง ข้อมูลใน dir ที่ว่างเปล่าจะไม่ไปไหนเลย เขาสามารถใช้มันได้อีกครั้งเมื่อเริ่มต้นใหม่ และนั่นเป็นเรื่องดี หากพ็อดของคุณออกไปที่ไหนสักแห่ง เขาก็จะไปโดยไม่มีข้อมูลโดยธรรมชาติ นั่นคือทันทีที่พ็อดจากโหนดที่เปิดตัวด้วย dir ว่างเปล่าหายไป dir ที่ว่างเปล่าจะถูกลบออก

มีอะไรดีอีกเกี่ยวกับ dir ที่ว่างเปล่า? ตัวอย่างเช่น สามารถใช้เป็นแคชได้ ลองจินตนาการว่าแอปพลิเคชันของเราสร้างบางสิ่งได้ทันที มอบให้กับผู้ใช้ และทำสิ่งนี้มาเป็นเวลานาน ดังนั้นแอปพลิเคชันจึงสร้างและมอบให้กับผู้ใช้และในขณะเดียวกันก็จัดเก็บไว้ที่ใดที่หนึ่งเพื่อที่ครั้งต่อไปที่ผู้ใช้มาหาสิ่งเดียวกันจะเร็วกว่าที่จะให้สร้างขึ้นทันที Kubernetes สามารถขอให้ dir ว่างเปล่าสร้างในหน่วยความจำได้ ด้วยเหตุนี้แคชของคุณจึงสามารถทำงานได้อย่างรวดเร็ว - ในแง่ของความเร็วในการเข้าถึงดิสก์ นั่นคือคุณมี dir ว่างในหน่วยความจำใน OS จะถูกเก็บไว้ในหน่วยความจำ แต่สำหรับคุณแล้วสำหรับผู้ใช้ภายในพ็อดดูเหมือนว่าเป็นเพียงไดเร็กทอรีในเครื่อง คุณไม่จำเป็นต้องมีแอปเพื่อสอนเวทมนตร์ใดๆ โดยเฉพาะ คุณเพียงแค่นำไฟล์ของคุณไปไว้ในไดเร็กทอรีโดยตรง แต่ในความเป็นจริงแล้วอยู่ในหน่วยความจำบนระบบปฏิบัติการ นี่เป็นคุณสมบัติที่สะดวกมากในแง่ของ Kubernetes

มินิโอมีปัญหาอะไรบ้าง? ปัญหาหลักของ Minio ก็คือเพื่อให้สิ่งนี้ทำงานได้ จะต้องทำงานที่ไหนสักแห่งและต้องมีระบบไฟล์บางประเภท นั่นคือที่เก็บข้อมูล และที่นี่เราพบปัญหาเดียวกันกับที่ Ceph พบ นั่นคือ Minio ต้องเก็บไฟล์ไว้ที่ไหนสักแห่ง มันเป็นเพียงอินเทอร์เฟซ HTTP สำหรับไฟล์ของคุณ ยิ่งไปกว่านั้น ฟังก์ชันการทำงานยังด้อยกว่า S3 ของ Amazon อย่างเห็นได้ชัด ก่อนหน้านี้ไม่สามารถให้สิทธิ์ผู้ใช้ได้อย่างถูกต้อง เท่าที่ฉันรู้ตอนนี้มันสามารถสร้างที่เก็บข้อมูลที่มีการอนุญาตที่แตกต่างกันได้แล้ว แต่สำหรับฉันอีกครั้งดูเหมือนว่าปัญหาหลักคือระบบจัดเก็บข้อมูลพื้นฐานอย่างน้อยที่สุด

Empty dir ในหน่วยความจำส่งผลต่อขีดจำกัดอย่างไร ไม่กระทบถึงขีดจำกัดแต่อย่างใด มันอยู่ในหน่วยความจำของโฮสต์ ไม่ใช่ในหน่วยความจำของคอนเทนเนอร์ของคุณ นั่นคือคอนเทนเนอร์ของคุณไม่เห็น dir ว่างในหน่วยความจำซึ่งเป็นส่วนหนึ่งของหน่วยความจำที่ถูกครอบครอง เจ้าภาพเห็นสิ่งนี้ ดังนั้น จากมุมมองของ kubernetes เมื่อคุณเริ่มใช้สิ่งนี้ เป็นการดีที่จะเข้าใจว่าคุณกำลังอุทิศส่วนหนึ่งของหน่วยความจำของคุณเพื่อล้าง dir ดังนั้นจงเข้าใจว่าหน่วยความจำสามารถหมดได้ไม่เพียงเพราะแอปพลิเคชันเท่านั้น แต่ยังเป็นเพราะมีคนเขียนถึง dirs ที่ว่างเปล่าเหล่านี้ด้วย

ความมีเมฆมาก

และหัวข้อย่อยสุดท้ายคือ Cloudnative คืออะไร เหตุใดจึงจำเป็น? Cloudnativeness เป็นต้น

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

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชันใน Kubernetes

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

เมื่อเร็ว ๆ นี้เรามีกรณีอย่างแท้จริงอีกครั้ง เรามีตัวควบคุมหนึ่งตัวที่คอยตรวจสอบคิว และเมื่อมีงานใหม่ปรากฏในคิวนี้ งานนั้นจะไปที่ Kubernetes และภายใน Kubernetes งานนั้นจะสร้างพ็อดใหม่ มอบงานใหม่ให้กับพ็อดนี้ และภายในกรอบการทำงานของพ็อดนี้ พ็อดจะดำเนินการ ส่งการตอบกลับไปยังตัวควบคุมเอง จากนั้นตัวควบคุมก็ทำอะไรบางอย่างกับข้อมูลนี้ เช่น เพิ่มฐานข้อมูล นั่นคือข้อดีอีกอย่างของการที่แอปพลิเคชันของเราทำงานใน Kubernetes เราสามารถใช้ฟังก์ชัน Kubernetes ในตัวเพื่อขยายและทำให้ฟังก์ชันการทำงานของแอปพลิเคชันของเราสะดวกยิ่งขึ้น นั่นคืออย่าซ่อนเวทย์มนตร์บางอย่างเกี่ยวกับวิธีเปิดแอปพลิเคชันวิธีเปิดพนักงาน ใน Kubernetes คุณเพียงแค่ส่งคำขอในแอปหากแอปพลิเคชันเขียนด้วย Python

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

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

แต่จากประสบการณ์ของฉัน มันเป็นสิ่งที่เจ๋งที่สุดที่ฉันเคยเห็นมาอีกครั้ง เมื่อคลัสเตอร์ Cloudnative ปรับขนาดตามเวลาของวัน เป็นบริการแบ็กเอนด์ที่ผู้คนในแบ็คออฟฟิศใช้ นั่นคือพวกเขามาทำงานเวลา 9 น. เริ่มเข้าสู่ระบบและดังนั้นคลัสเตอร์ Cloudnative ที่มันทำงานอยู่ทั้งหมดก็เริ่มขยายตัวเปิดตัวพ็อดใหม่เพื่อให้ทุกคนที่มาทำงานสามารถทำงานกับแอปพลิเคชันได้ เมื่อพวกเขาออกจากงานเวลา 8 น. หรือ 6 น. คลัสเตอร์ Kubernetes จะสังเกตเห็นว่าไม่มีใครใช้แอปพลิเคชันอีกต่อไปและเริ่มหดตัวลง รับประกันการประหยัดสูงสุดถึง 30 เปอร์เซ็นต์ ตอนนั้นใช้งานได้ใน Amazon ในเวลานั้นไม่มีใครในรัสเซียที่ทำได้ดีขนาดนี้

ฉันจะบอกคุณตรงๆ ประหยัดได้ 30 เปอร์เซ็นต์เพียงเพราะเราใช้ Kubernetes และใช้ประโยชน์จากความสามารถของระบบคลาวด์ ตอนนี้สามารถทำได้ในรัสเซีย แน่นอนว่าฉันจะไม่โฆษณากับใครเลย แต่สมมติว่ามีผู้ให้บริการที่สามารถทำเช่นนี้ได้ เพียงกดปุ่มเพียงครั้งเดียว

มีประเด็นสุดท้ายที่ฉันอยากจะดึงดูดความสนใจของคุณเช่นกัน เพื่อให้แอปพลิเคชันของคุณโครงสร้างพื้นฐานของคุณเป็นแบบ Cloudnative ในที่สุดคุณควรเริ่มปรับแนวทางที่เรียกว่าโครงสร้างพื้นฐานเป็นโค้ดในที่สุด นั่นคือ หมายความว่าแอปพลิเคชันของคุณหรือโครงสร้างพื้นฐานของคุณจำเป็นต้องมีในลักษณะเดียวกับ รหัส อธิบายแอปพลิเคชันของคุณ ตรรกะทางธุรกิจของคุณในรูปแบบของรหัส และใช้งานมันเป็นโค้ด กล่าวคือ ทดสอบ ใช้งาน จัดเก็บใน git ใช้ CICD กับมัน

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

ประเด็นทั้งหมดนี้พูดคุยกันโดยละเอียดได้ที่ หลักสูตรวิดีโอ Kubernetes: Junior, Basic, Mega. โดยการคลิกลิงก์นี้ คุณจะสามารถทำความคุ้นเคยกับโปรแกรมและเงื่อนไขต่างๆ ได้ สิ่งที่สะดวกคือคุณสามารถเชี่ยวชาญ Kubernetes ได้โดยเรียนจากที่บ้านหรือที่ทำงานวันละ 1-2 ชั่วโมง

ที่มา: will.com

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