การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

สวัสดีทุกคน! ฉันชื่อพาเวล อกาเล็ตสกี้ ฉันทำงานเป็นหัวหน้าทีมในทีมที่พัฒนาระบบจัดส่งของ Lamoda ในปี 2018 ฉันได้พูดในการประชุม HighLoad++ และวันนี้ฉันอยากจะนำเสนอสำเนารายงานของฉัน

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

การปรับใช้แอปพลิเคชันไปยัง VM

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

เหตุใดจึงทำเช่นนี้?

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

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

เราเห็นข้อดีอะไรบ้างจากทั้งหมดนี้?

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

แต่เรายังเห็นข้อบกพร่องหลายประการในทั้งหมดนี้:

  1. นอกจากสภาพแวดล้อมการผลิต สภาพแวดล้อมการพัฒนาแล้ว ยังมีสภาพแวดล้อมอื่นๆ ตัวอย่างเช่น qa และก่อนการผลิต ตอนนั้นเรามีเซิร์ฟเวอร์มากมายและบริการประมาณ 60 รายการ ด้วยเหตุนี้จึงมีความจำเป็น สำหรับแต่ละบริการ ให้รักษาเวอร์ชันล่าสุดไว้ เครื่องเสมือน ยิ่งไปกว่านั้น หากคุณต้องการอัปเดตไลบรารีหรือติดตั้งการขึ้นต่อกันใหม่ คุณต้องดำเนินการนี้ในทุกสภาพแวดล้อม คุณยังจำเป็นต้องซิงโครไนซ์เวลาที่คุณจะปรับใช้แอปพลิเคชันเวอร์ชันใหม่ถัดไปของคุณกับเวลาที่ Devops ดำเนินการตั้งค่าสภาพแวดล้อมที่จำเป็น ในกรณีนี้ เป็นเรื่องง่ายที่จะตกอยู่ในสถานการณ์ที่สภาพแวดล้อมของเราจะแตกต่างไปบ้างในทุกสภาพแวดล้อมในคราวเดียว ตัวอย่างเช่น ในสภาพแวดล้อม QA จะมีไลบรารีบางเวอร์ชัน และในสภาพแวดล้อมการใช้งานจริงก็จะมีไลบรารีที่แตกต่างกัน ซึ่งจะทำให้เกิดปัญหาได้
  2. ความยากลำบากในการอัปเดตการอ้างอิง ใบสมัครของคุณ. มันไม่ได้ขึ้นอยู่กับคุณ แต่ขึ้นอยู่กับทีมอื่น กล่าวคือจากทีมงาน Devops ที่ดูแลเซิร์ฟเวอร์ คุณต้องให้งานที่เหมาะสมแก่พวกเขาและคำอธิบายสิ่งที่คุณต้องการทำ
  3. ในเวลานั้น เรายังต้องการแบ่งเสาหินขนาดใหญ่ขนาดใหญ่ที่เรามีออกเป็นบริการเล็กๆ ที่แยกจากกัน เนื่องจากเราเข้าใจว่าจะมีบริการเหล่านี้เพิ่มมากขึ้นเรื่อยๆ ในเวลานั้น เรามีมากกว่า 100 รายการแล้ว สำหรับบริการใหม่แต่ละรายการจำเป็นต้องสร้างเครื่องเสมือนใหม่แยกต่างหากซึ่งจำเป็นต้องได้รับการบำรุงรักษาและปรับใช้ด้วย นอกจากนี้คุณไม่จำเป็นต้องมีรถยนต์หนึ่งคัน แต่อย่างน้อยสองคัน สิ่งที่เพิ่มเข้ามาทั้งหมดนี้คือสภาพแวดล้อม QA สิ่งนี้ทำให้เกิดปัญหาและทำให้การสร้างและรันระบบใหม่ยากขึ้น กระบวนการที่ซับซ้อน มีราคาแพง และยาวนาน

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

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

เปลี่ยนไปใช้ Nomad

Nomad เป็นผลิตภัณฑ์ของ HashiCorp พวกเขายังมีชื่อเสียงในด้านโซลูชันอื่นๆ:

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

"กงสุล" เป็นเครื่องมือในการค้นหาบริการ

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

"คนเร่ร่อน" ช่วยให้คุณสามารถปรับใช้เครื่องเสมือนภายในเครื่องหรือในระบบคลาวด์ผ่านไฟล์การกำหนดค่าเฉพาะ

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

คุณต้องมีอะไรบ้างในการปรับใช้ระบบของคุณกับ Nomad

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

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

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

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

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

เมื่อบริการ Nomad ถูกปรับใช้กับคลัสเตอร์ของคุณแล้ว จะมีลักษณะเช่นนี้

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

การเปลี่ยนแปลงนี้มีค่าใช้จ่ายเท่าไรในแง่ของทรัพยากรมนุษย์?

การเปลี่ยนผ่านของบริษัททั้งหมดมาเป็น Nomad ใช้เวลาประมาณ 5-6 เดือน เราดำเนินการแบบบริการต่อบริการ แต่ดำเนินการอย่างรวดเร็ว แต่ละทีมต้องสร้างคอนเทนเนอร์ของตนเองสำหรับบริการ

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

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

เหตุผลในการละทิ้งชนเผ่าเร่ร่อน

เราได้ประโยชน์อะไรบ้างจากการเปลี่ยนไปใช้ Nomad และ Docker และอื่นๆ

  1. เรา โดยมีเงื่อนไขที่เท่าเทียมกัน สำหรับทุกสภาพแวดล้อม ในการพัฒนา สภาพแวดล้อม QA ก่อนการผลิต การผลิต อิมเมจคอนเทนเนอร์เดียวกันจะถูกนำมาใช้โดยมีการขึ้นต่อกันที่เหมือนกัน ดังนั้น คุณแทบไม่มีโอกาสที่สิ่งที่จะเกิดขึ้นในการใช้งานจริงจะไม่ใช่สิ่งที่คุณทดสอบก่อนหน้านี้ในเครื่องหรือในสภาพแวดล้อมการทดสอบของคุณ
  2. เราก็พบว่ามันเพียงพอแล้ว ง่ายต่อการเพิ่มบริการใหม่. จากมุมมองของการใช้งาน ระบบใหม่ใดๆ ก็ตามจะเปิดตัวได้ง่ายมาก เพียงไปที่พื้นที่เก็บข้อมูลที่เก็บการกำหนดค่า เพิ่มการกำหนดค่าอื่นสำหรับระบบของคุณที่นั่น เท่านี้ก็เรียบร้อย คุณสามารถปรับใช้ระบบของคุณกับการใช้งานจริงโดยไม่ต้องใช้ความพยายามเพิ่มเติมจาก Devops
  3. ทั้งหมด ไฟล์การกำหนดค่า ในที่เก็บข้อมูลทั่วไปแห่งเดียว ปรากฏว่าอยู่ระหว่างการตรวจสอบ. ในขณะที่เราปรับใช้ระบบของเราโดยใช้เซิร์ฟเวอร์เสมือน เราใช้ Ansible ซึ่งการกำหนดค่าอยู่ในพื้นที่เก็บข้อมูลเดียวกัน อย่างไรก็ตาม สำหรับนักพัฒนาส่วนใหญ่ การทำงานด้วยจะยากขึ้นเล็กน้อย ปริมาณการกำหนดค่าและโค้ดที่คุณต้องเพิ่มเพื่อใช้บริการนี้มีจำนวนน้อยลงมาก นอกจากนี้ Devops ยังสามารถแก้ไขหรือเปลี่ยนแปลงได้ง่ายมาก ในกรณีที่มีการเปลี่ยนไปใช้ Nomad เวอร์ชันใหม่ พวกเขาสามารถรับและอัปเดตไฟล์ปฏิบัติการทั้งหมดที่อยู่ในที่เดียวกันเป็นกลุ่มได้

แต่เรายังพบข้อเสียหลายประการ:

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

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

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

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

การเปลี่ยนไปใช้ Kubernetes

ฉันจะบอกคุณเล็กน้อยเกี่ยวกับแนวคิดพื้นฐานของ Kubernetes และความแตกต่างจาก Nomad

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

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

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

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

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

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

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

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

แนวคิดพื้นฐานในพวงมาลัย

หางเสือเป็น ผู้จัดการแพ็คเกจ สำหรับ Kubernetes มันคล้ายกับวิธีการทำงานของผู้จัดการแพ็คเกจในภาษาการเขียนโปรแกรมมาก ช่วยให้คุณสามารถจัดเก็บบริการที่ประกอบด้วย เช่น การปรับใช้ nginx, การปรับใช้ php-fpm, การกำหนดค่าสำหรับ Ingress, configmaps (นี่คือเอนทิตีที่อนุญาตให้คุณตั้งค่า env และพารามิเตอร์อื่น ๆ สำหรับระบบของคุณ) ในรูปแบบของ so- เรียกว่าแผนภูมิ ในเวลาเดียวกันกับหางเสือ ทำงานบน Kubernetes. นั่นคือนี่ไม่ใช่ระบบบางประเภทที่ยืนหยัด แต่เป็นเพียงบริการอื่นที่เปิดตัวภายในคิวบ์ คุณโต้ตอบกับมันผ่าน API ผ่านคำสั่งคอนโซล ความสะดวกและสวยงามคือ แม้ว่าหางเสือจะพังหรือคุณถอดมันออกจากคลัสเตอร์ บริการของคุณจะไม่หายไป เนื่องจากหางเสือทำหน้าที่เพื่อสตาร์ทระบบเท่านั้น Kubernetes เองจะเป็นผู้รับผิดชอบประสิทธิภาพและสถานะของบริการ

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

Helm เพิ่มแนวคิดอีกสองสามอย่างให้เรา

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

ความคุ้มค่า คือตัวแปรที่คุณต้องการใช้เพื่อสร้างการกำหนดค่าจากเทมเพลต

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

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

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

ในทางปฏิบัติ เราตัดสินใจที่จะทำสิ่งที่แตกต่างไปจากที่เราทำกับ Nomad เล็กน้อย หากใน Nomad ทั้งการกำหนดค่าการปรับใช้และตัวแปร n ที่จำเป็นในการปรับใช้บริการของเราถูกจัดเก็บไว้ในที่เก็บข้อมูลเดียว ที่นี่เราจึงตัดสินใจแบ่งพวกมันออกเป็นสองที่แยกกัน พื้นที่เก็บข้อมูล “ปรับใช้” จะจัดเก็บเฉพาะตัวแปร n ที่จำเป็นสำหรับการปรับใช้ และพื้นที่เก็บข้อมูล “หางเสือ” จะจัดเก็บการกำหนดค่าหรือแผนภูมิ

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

สิ่งนี้ให้อะไรเราบ้าง?

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

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

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

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

ผลการวิจัย

บริการ Kubernetes ดูเหมือนจะซับซ้อนกว่า Nomad

การปรับใช้แอปพลิเคชันกับ VM, Nomad และ Kubernetes

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

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

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

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

ที่มา: will.com

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