การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

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

บทความนี้เป็นการทับศัพท์ประเภทหนึ่ง การแสดง ที่งาน HighLoad+ 2018

การสร้างกระบวนการเปลี่ยนดิสก์

ก่อนอื่นตัวเลขบางส่วน

OK เป็นบริการขนาดใหญ่ที่มีผู้ใช้หลายล้านคน ให้บริการโดยเซิร์ฟเวอร์ประมาณ 7 เครื่องซึ่งตั้งอยู่ในศูนย์ข้อมูล 4 แห่ง เซิร์ฟเวอร์มีดิสก์มากกว่า 70 แผ่น หากคุณวางซ้อนกัน คุณจะได้หอคอยที่สูงกว่า 1 กม.

ฮาร์ดไดรฟ์เป็นส่วนประกอบเซิร์ฟเวอร์ที่ล้มเหลวบ่อยที่สุด ด้วยปริมาณดังกล่าว เราจะต้องเปลี่ยนดิสก์ประมาณ 30 แผ่นต่อสัปดาห์ และขั้นตอนนี้กลายเป็นกิจวัตรที่ไม่น่าพอใจนัก

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

เหตุการณ์

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

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

ก่อนหน้านี้ดิสก์มีการเปลี่ยนแปลงอย่างไร

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

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

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

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

นอกจากนี้ วิศวกรไม่สามารถจัดลำดับความสำคัญได้อย่างถูกต้อง เนื่องจากเขาไม่รู้อะไรเลยเกี่ยวกับวัตถุประสงค์ของเซิร์ฟเวอร์เฉพาะหรือการกระจายข้อมูลระหว่างไดรฟ์

ขั้นตอนการเปลี่ยนใหม่

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

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

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

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

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

ก่อนหน้านี้มันเป็นเช่นนี้:

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

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

เรายังเพิ่มสถานะ พร้อม. ตั๋วจะถูกโอนไปหลังจากเปลี่ยนดิสก์ นั่นคือทุกอย่างเสร็จสิ้นแล้ว แต่ HW/SW RAID ได้รับการซิงโครไนซ์บนเซิร์ฟเวอร์ อาจใช้เวลานานพอสมควร

หากผู้ดูแลระบบมีส่วนร่วมในงาน โครงการก็จะซับซ้อนขึ้นเล็กน้อย

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

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

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

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

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

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

บทเรียนที่ได้รับเมื่อสร้างเวิร์กโฟลว์

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

ระบบอัตโนมัติของการเปลี่ยนดิสก์

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

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

การตั้งค่าสวนสัตว์

ก่อนที่เราจะพูดถึงบอท เรามาดูสวนสัตว์แห่งการติดตั้งของเรากันก่อน ประการแรก เป็นเพราะโครงสร้างพื้นฐานของเรามีขนาดมหึมา ประการที่สอง เราพยายามเลือกการกำหนดค่าฮาร์ดแวร์ที่เหมาะสมที่สุดสำหรับแต่ละบริการ เรามีโมเดล RAID ฮาร์ดแวร์ประมาณ 20 รุ่น ซึ่งส่วนใหญ่เป็น LSI และ Adaptec แต่ก็มี HP และ DELL ในเวอร์ชันที่แตกต่างกันด้วย คอนโทรลเลอร์ RAID แต่ละตัวมียูทิลิตีการจัดการของตัวเอง ชุดคำสั่งและการออกคำสั่งอาจแตกต่างกันไปในแต่ละเวอร์ชันสำหรับคอนโทรลเลอร์ RAID แต่ละตัว ในกรณีที่ไม่ได้ใช้ HW-RAID ก็อาจใช้ mdraid ได้

เราทำการติดตั้งใหม่เกือบทั้งหมดโดยไม่มีการสำรองข้อมูลบนดิสก์ เราพยายามที่จะไม่ใช้ฮาร์ดแวร์และซอฟต์แวร์ RAID อีกต่อไป เนื่องจากเราสำรองข้อมูลระบบของเราที่ระดับศูนย์ข้อมูล ไม่ใช่เซิร์ฟเวอร์ แต่แน่นอนว่ามีเซิร์ฟเวอร์รุ่นเก่าจำนวนมากที่ต้องได้รับการสนับสนุน

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

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

เราเลือก Ansible เนื่องจากไม่มีตัวแทน ไม่จำเป็นต้องเตรียมโครงสร้างพื้นฐาน เป็นการเริ่มต้นอย่างรวดเร็ว นอกจากนี้ยังเขียนด้วยภาษา Python ซึ่งเป็นที่ยอมรับเป็นมาตรฐานภายในทีม

โครงการทั่วไป

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

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible
แอปพลิเคชัน DiskoBot ซึ่งเขียนด้วยภาษา Python จะสำรวจ Jira เป็นระยะเพื่อหาตั๋วใหม่ สังเกตเห็นว่ามีตั๋วอยู่ระหว่างดำเนินการใหม่ปรากฏขึ้น เธรดที่เกี่ยวข้องจะถูกทริกเกอร์ ซึ่งเปิดตัว Playbook ใน Ansible (ซึ่งจะทำสำหรับแต่ละสถานะใน Jira) ในกรณีนี้ Launch2change จะถูกเปิดใช้งาน

Ansible ถูกส่งไปยังโฮสต์ ลบดิสก์ออกจากการหมุน และรายงานสถานะไปยังแอปพลิเคชันผ่านการโทรกลับ

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible
จากผลลัพธ์ บอทจะโอนตั๋วไปยังพร้อมที่จะเปลี่ยนแปลงโดยอัตโนมัติ วิศวกรได้รับการแจ้งเตือนและไปเปลี่ยนดิสก์ หลังจากนั้นเขาก็โอนตั๋วไปที่ Changed

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible
ตามรูปแบบที่อธิบายไว้ข้างต้น ตั๋วจะกลับไปที่บอทซึ่งเปิดตัว Playbook อื่น ไปที่โฮสต์ และทำให้ดิสก์หมุน บอทปิดตั๋ว ไชโย!

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible
ตอนนี้เรามาพูดถึงส่วนประกอบบางส่วนของระบบกัน

ดิสโคบอท

แอปพลิเคชั่นนี้เขียนด้วยภาษา Python มันเลือกตั๋วจาก Jira ตาม JQL ขึ้นอยู่กับสถานะของตั๋ว ส่วนหลังจะไปที่ตัวจัดการที่เกี่ยวข้อง ซึ่งจะเปิด Playbook Ansible ที่สอดคล้องกับสถานะ

JQL และช่วงเวลาการโพลถูกกำหนดไว้ในไฟล์คอนฟิกูเรชันแอปพลิเคชัน

jira_states:
  investigate:
    jql: '… status = Open and "Disk Size" is EMPTY'
    interval: 180

  inprogress:
    jql: '…  and "Disk Size" is not EMPTY and "Device Name" is not EMPTY'
 
  ready:
    jql: '… and (labels not in ("dbot_ignore") or labels is EMPTY)'
    interval: 7200

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

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

หาก Playbook ล้มเหลว Jira จะกำหนดป้ายกำกับ dbot_failed เพื่อให้สามารถแยกออกในภายหลัง

การทำงานร่วมกันกับ Ansible

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

นอกจากนี้ใน Ansible ผ่านทาง *extra_vars* ชื่อของอุปกรณ์บล็อก สถานะของตั๋ว รวมถึง callback_url ซึ่งมีรหัสปัญหา - ใช้สำหรับการโทรกลับใน HTTP

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

นี่คือตัวอย่างของงานที่ใช้การโทรกลับ HTTP

เราได้รับผลลัพธ์ของการดำเนินการ playbooks โดยใช้ callaback มีสองประเภท:

  • ปลั๊กอินโทรกลับ Ansibleโดยจะให้ข้อมูลเกี่ยวกับผลลัพธ์ของการดำเนินการ Playbook อธิบายถึงงานที่เปิดตัว เสร็จสมบูรณ์หรือไม่สำเร็จ การโทรกลับนี้จะถูกเรียกเมื่อ Playbook เล่นเสร็จแล้ว
  • โทรกลับ HTTP เพื่อรับข้อมูลขณะเล่น Playbook ในงาน Ansible เราดำเนินการคำขอ POST/GET ไปยังแอปพลิเคชันของเรา

ตัวแปรจะถูกส่งผ่านการเรียกกลับ HTTP ที่กำหนดไว้ระหว่างการดำเนินการ Playbook และเราต้องการบันทึกและใช้ในการเรียกใช้ครั้งต่อๆ ไป เราเขียนข้อมูลนี้เป็น sqlite

นอกจากนี้เรายังแสดงความคิดเห็นและเปลี่ยนสถานะตั๋วผ่านการโทรกลับ HTTP

โทรกลับ HTTP

# Make callback to Diskobot App
# Variables:
#    callback_post_body: # A dict with follow keys. All keys are optional
#       msg: If exist it would be posted to Jira as comment
#       data: If exist it would be saved in Incident.variables
#       desire_state: Set desire_state for incident
#       status: If exist Proceed issue to that status

  - name: Callback to Diskobot app (jira comment/status)
    uri:
      url: "{{ callback_url }}/{{ devname }}"
      user: "{{ diskobot_user }}"
      password: "{{ diskobot_pass }}"
      force_basic_auth: True
      method: POST
      body: "{{ callback_post_body | to_json }}"
      body_format: json
    delegate_to: 127.0.0.1

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

และนี่คือตัวอย่างจาก Playbook ซึ่งเราส่งออกดิสก์จากอุปกรณ์ MD:

  # Save mdadm configuration
  - include: common/callback.yml
    vars:
      callback_post_body:
        status: 'Ready to change'
        msg: "Removed disk from mdraid {{ mdadm_remove_disk.msg | comment_jira }}"
        data:
          mdadm_data: "{{ mdadm_remove_disk.removed }}"
          parted_info: "{{ parted_info | default() }}"
    when:
      - mdadm_remove_disk | changed
      - mdadm_remove_disk.removed

งานนี้โอนตั๋ว Jira ไปที่สถานะ "พร้อมเปลี่ยน" และเพิ่มความคิดเห็น นอกจากนี้ ตัวแปร mdam_data ยังจัดเก็บรายการอุปกรณ์ md ที่ถูกลบดิสก์ออก และ parted_info จะจัดเก็บการถ่ายโอนข้อมูลพาร์ติชันจากการแยกส่วน

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

โหมดตรวจสอบ Ansible

มันน่ากลัวที่จะเปิดระบบอัตโนมัติ ดังนั้นเราจึงตัดสินใจเปิด Playbooks ทั้งหมดในโหมดนี้
วิ่งแห้งซึ่ง Ansible ไม่ได้ดำเนินการใดๆ บนเซิร์ฟเวอร์ แต่จำลองเท่านั้น

การเปิดตัวดังกล่าวจะดำเนินการผ่านโมดูลการโทรกลับแยกต่างหาก และผลลัพธ์ของการดำเนินการ Playbook จะถูกบันทึกไว้ใน Jira เป็นความคิดเห็น

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

ประการแรก ทำให้สามารถตรวจสอบการทำงานของบอทและ Playbooks ได้ ประการที่สอง เพิ่มความมั่นใจของผู้ดูแลระบบต่อบอท

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

นอกจากนี้ ปุ่มนี้ยังใช้เพื่อรีสตาร์ท Playbook หากเกิดข้อขัดข้อง

โครงสร้างเพลย์บุ๊ค

ฉันได้กล่าวไปแล้วว่าบอทจะเปิดตัว playbooks ที่แตกต่างกันขึ้นอยู่กับสถานะของตั๋ว Jira

ประการแรก การจัดทางเข้าง่ายกว่ามาก
ประการที่สอง ในบางกรณีก็จำเป็นจริงๆ

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

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

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

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

การสืบสวน.yml

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

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

เมื่อทราบชื่ออุปกรณ์บล็อกแล้วเราจะรวบรวมข้อมูลเกี่ยวกับประเภทและขนาดของดิสก์จากนั้นเพื่อกรอกข้อมูลในฟิลด์ในจิรา นอกจากนี้เรายังลบข้อมูลเกี่ยวกับผู้จำหน่าย รุ่น เฟิร์มแวร์ ID, SMART และแทรกทั้งหมดนี้ลงในความคิดเห็นในตั๋ว Jira ผู้ดูแลระบบและวิศวกรไม่จำเป็นต้องค้นหาข้อมูลนี้อีกต่อไป 🙂

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

เตรียม2change.yml

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

ในกรณีที่ง่ายที่สุด เรากำลังพูดถึงการถอดดิสก์ออกจาก HW/MD RAID

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

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

เปลี่ยน.yml

หลังจากเปลี่ยนดิสก์แล้ว เราจะตรวจสอบความพร้อมใช้งานของมันก่อน

วิศวกรไม่ได้ติดตั้งไดรฟ์ใหม่เสมอไป ดังนั้นเราจึงเพิ่มการตรวจสอบค่า SMART ที่ตรงใจเรา

เรากำลังดูคุณสมบัติอะไรบ้าง?จำนวนส่วนที่จัดสรรใหม่ (5) < 100
จำนวนส่วนที่รอดำเนินการปัจจุบัน (107) == 0

หากไดรฟ์ไม่ผ่านการทดสอบ วิศวกรจะได้รับแจ้งให้เปลี่ยนไดรฟ์อีกครั้ง หากทุกอย่างเป็นไปตามลำดับ ไฟแบ็คไลท์จะดับลง มีการทำเครื่องหมาย และหมุนแผ่นดิสก์

พร้อม.yml

กรณีที่ง่ายที่สุด: การตรวจสอบการซิงโครไนซ์การโจมตี HW/SW หรือการสิ้นสุดการซิงโครไนซ์ข้อมูลในแอปพลิเคชัน

แอปพลิเคชัน API

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

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

บทเรียนที่ได้รับจาก Ansible

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

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

- name: Blink disk
  become: True
  register: locate_action
  disk_locate:
      locate: '{{ locate }}'
      devname: '{{ devname }}'
      ids: '{{ locate_ids | default(pd_id) | default(omit) }}'

หากตรรกะบางอย่างยากต่อการนำไปใช้ใน Playbooks เราจะย้ายมันไปไว้ในโมดูลหรือตัวกรอง Ansible สคริปต์สามารถเขียนด้วยภาษา Python หรือภาษาอื่น ๆ ได้

เขียนได้ง่ายและรวดเร็ว ตัวอย่างเช่นโมดูลแบ็คไลท์ของดิสก์ตามตัวอย่างที่แสดงด้านบนประกอบด้วย 265 บรรทัด

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

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

การเปลี่ยนดิสก์อัตโนมัติด้วย Ansible

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

หากคุณต้องการทำซ้ำประสบการณ์ของเรากับ Ansible API โปรดคำนึงถึงสองสิ่งต่อไปนี้:

  • Playbook_executor และ playbooks โดยทั่วไปไม่สามารถให้การหมดเวลาได้ มีการหมดเวลาในเซสชัน ssh แต่ไม่มีการหมดเวลาใน Playbook หากเราพยายามยกเลิกการต่อเชื่อมดิสก์ที่ไม่มีอยู่ในระบบอีกต่อไป Playbook จะทำงานอย่างไม่มีที่สิ้นสุด ดังนั้นเราจึงต้องรวมการเปิดตัวมันไว้ใน wrapper ที่แยกต่างหากและฆ่ามันโดยหมดเวลา
  • Ansible ทำงานบนกระบวนการที่แยกออกมา ดังนั้น API จึงไม่ปลอดภัยสำหรับเธรด เรารัน Playbooks ทั้งหมดของเราแบบเธรดเดียว

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

แต่ตอนนี้เรากำลังเริ่มประสบปัญหาอื่น: ผู้ดูแลระบบใหม่บางคนไม่ทราบวิธีเปลี่ยนไดรฟ์ 🙂

ที่มา: will.com

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