กลยุทธ์การอัพเดทอัตโนมัติของซอฟต์แวร์ / เฟิร์มแวร์


9

ฉันมีโครงการขนาดกลางแล้วตอนนี้ใกล้จะสิ้นสุด "เฟสต้นแบบที่ขับเคลื่อนด้วยคาเฟอีนแบบเลอะเทอะสำหรับการสาธิตลูกค้า" และเปลี่ยนเป็นเฟส "คิดเกี่ยวกับอนาคต" โครงการประกอบด้วยอุปกรณ์ที่ใช้ Linux พร้อมซอฟต์แวร์และเฟิร์มแวร์และเว็บเซิร์ฟเวอร์การบริหารส่วนกลาง 10 ต้นแบบที่มีอยู่ในปัจจุบันการผลิตคาดว่าจะอยู่ในลำดับต่ำ 1,000

การไม่ได้มีความเชี่ยวชาญในการอัปเดตอัตโนมัติและเป็นระยะเวลาสั้น ๆ ฉันได้เปิดตัวการปรับใช้ซอฟต์แวร์ / กลยุทธ์การอัพเดทอัตโนมัติอย่างรวดเร็วและตรงไปตรงมามันแย่มาก ปัจจุบันประกอบด้วยดังต่อไปนี้:

  • git repo โฮสต์ (GitLab) ที่มีสาขารีลีสการผลิต (หมายเหตุแหล่งที่มาของเว็บเซิร์ฟเวอร์นั้นอยู่ใน repo เดียวกันนี้รวมถึงสิ่งอื่น ๆ อีกสองสามรายการ)
  • ปุ่ม "ปรับใช้การอัปเดต" บนเว็บอินเตอร์เฟสที่:
    1. ดึงเวอร์ชันล่าสุดจากสาขารีลีสการผลิตไปยังพื้นที่ repo ท้องถิ่นและคัดลอกไปยังพื้นที่จัดเตรียมชั่วคราว
    2. รันสคริปต์การฆ่าเชื้อ (เก็บไว้ใน repo) ในพื้นที่จัดเตรียมเพื่อลบไฟล์ต้นฉบับที่ไม่เกี่ยวข้อง (เช่นแหล่งเซิร์ฟเวอร์, แหล่งเฟิร์มแวร์ ฯลฯ ) และไฟล์. git
    3. เขียนแฮช git ปัจจุบันไปยังไฟล์ในแพ็คเกจการอัพเดท (จุดประสงค์จะชัดเจนด้านล่าง)
    4. หากทุกอย่างเป็นไปด้วยดีมันจะบีบอัดไฟล์และทำให้พร้อมที่จะให้บริการโดยเขียนทับแพ็กเกจ gzipped ก่อนหน้าด้วยไฟล์ชื่อเดียวกันจากนั้นลบพื้นที่จัดเตรียม
    5. โปรดทราบว่าขณะนี้มีซอฟต์แวร์อุปกรณ์ปัจจุบันสองสำเนาบนเซิร์ฟเวอร์ซึ่งคาดว่าจะซิงค์: repo git ภายในเต็มรูปแบบในสาขาการผลิตล่าสุดและแพคเกจ gzipped ที่พร้อมใช้งานซึ่งตอนนี้สันนิษฐานว่าเป็นตัวแทนของ รุ่นเดียวกัน
  • ซอฟต์แวร์ในอุปกรณ์นั้นมีอยู่ในไดเรกทอรีชื่อ/opt/example/currentซึ่งเป็น symlink ของซอฟต์แวร์รุ่นปัจจุบัน
  • ฟังก์ชั่นอัพเดทอัตโนมัติบนอุปกรณ์ที่บู๊ต:
    1. ตรวจสอบการมีdo_not_updateไฟล์และไม่มีการดำเนินการเพิ่มเติมหากมีอยู่ (สำหรับอุปกรณ์ dev ดูด้านล่าง)
    2. อ่านแฮชการคอมมิชชันปัจจุบันจากไฟล์ข้อความที่กล่าวถึงข้างต้น
    3. ทำให้คำร้องขอ HTTP ไปยังเซิร์ฟเวอร์โดยใช้แฮชนั้นเป็นพารามิเตอร์เคียวรี เซิร์ฟเวอร์จะตอบกลับด้วย 304 (แฮชเป็นเวอร์ชันปัจจุบัน) หรือจะให้บริการแพ็คเกจการอัพเดต gzipped
    4. ติดตั้งแพ็คเกจการอัพเดทหากได้รับมา/opt/exampleโดย:
      1. stageสกัดการปรับปรุงซอฟต์แวร์โฟลเดอร์ข้อมูลที่ชื่อ
      2. การรันสคริปต์หลังการติดตั้งจากแพ็คเกจการอัปเดตที่ทำสิ่งต่าง ๆ เช่นทำการเปลี่ยนแปลงในท้องถิ่นที่จำเป็นสำหรับการอัปเดตนั้นเป็นต้น
      3. คัดลอกโฟลเดอร์ปัจจุบันของซอฟต์แวร์รูทไปที่previous(ลบที่มีอยู่previousก่อนหากมี)
      4. คัดลอกstageโฟลเดอร์ไปที่latest(ลบที่มีอยู่latestก่อนถ้ามี)
      5. การสร้างความมั่นใจcurrentsymlink latestไปชี้ไปที่
      6. การรีบูตอุปกรณ์ (หากมีการอัพเดตเฟิร์มแวร์จะถูกนำไปใช้ในการรีบูต)

นอกจากนี้ยังมีปัญหาการปรับใช้เริ่มต้นบนอุปกรณ์ที่สร้างขึ้นใหม่ อุปกรณ์นี้ใช้การ์ด SD ในปัจจุบัน (มีชุดของปัญหาอยู่นอกขอบเขตที่นี่) ดังนั้นกระบวนการนี้ประกอบด้วย:

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

นอกจากนี้ฉันต้องการการสนับสนุนสำหรับอุปกรณ์การพัฒนา สำหรับอุปกรณ์การพัฒนา:

  • repo git ท้องถิ่นเต็มจะถูกเก็บไว้ในอุปกรณ์
  • currentจุด symlink ไปไดเรกทอรีการพัฒนา
  • มีdo_not_updateไฟล์ในตัวเครื่องซึ่งป้องกันไม่ให้ตัวอัพเดตอัตโนมัติระเบิดรหัสการพัฒนาด้วยการอัพเดทการผลิต

ตอนนี้ขั้นตอนการปรับใช้มีวัตถุประสงค์ในทางทฤษฎีที่จะ:

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

อย่างไรก็ตามมีตันของปัญหาที่เกิดขึ้นในการปฏิบัติ:

  • รหัสเว็บเซิร์ฟเวอร์อยู่ใน repo เดียวกันกับรหัสอุปกรณ์และเซิร์ฟเวอร์มี repo git ในพื้นที่ที่ฉันเรียกใช้ รหัสเซิร์ฟเวอร์เว็บล่าสุดไม่ได้อยู่ในสาขาเดียวกันกับรหัสอุปกรณ์ล่าสุด โครงสร้างไดเรกทอรีมีปัญหา เมื่อปุ่ม "ปรับใช้การอัปเดต" ดึงเวอร์ชันล่าสุดออกมาจากสาขาการผลิตปุ่มนั้นจะดึงเข้าไปในไดเรกทอรีย่อยของรหัสเซิร์ฟเวอร์ ซึ่งหมายความว่าเมื่อฉันปรับใช้กับเซิร์ฟเวอร์ตั้งแต่เริ่มต้นฉันต้อง "seed" ไดเรกทอรีย่อยนี้ด้วยตนเองโดยการจับสาขาการผลิตอุปกรณ์ลงในนั้นเพราะอาจเกิดจากข้อผิดพลาดของผู้ใช้คอมไพล์ในส่วนของฉันถ้าฉันไม่พยายามปรับใช้ ดึงรหัสอุปกรณ์จากสาขาเว็บเซิร์ฟเวอร์ของไดเรกทอรีหลัก ฉันคิดว่าสิ่งนี้สามารถแก้ไขได้ด้วยการทำให้พื้นที่การแสดงละครไม่ใช่ไดเรกทอรีย่อยของ repo git ในเครื่องของเซิร์ฟเวอร์
  • เว็บเซิร์ฟเวอร์ในปัจจุบันไม่ได้รักษาแฮชคอมไพล์ของซอฟต์แวร์อุปกรณ์อย่างต่อเนื่อง ในการเริ่มต้นเซิร์ฟเวอร์มันจะทำซ้ำgit rev-parse HEADในซอฟต์แวร์อุปกรณ์ภายในเครื่องเพื่อเรียกแฮชปัจจุบัน ด้วยเหตุผลที่ฉันไม่สามารถสรุปได้ว่านี่เป็นสาเหตุของข้อผิดพลาดทางตรรกะมากมายที่ฉันจะไม่อธิบายที่นี่พอเพียงเพื่อบอกว่าบางครั้งการรีสตาร์ทสกรูของเซิร์ฟเวอร์ขึ้นโดยเฉพาะถ้าเซิร์ฟเวอร์ใหม่และไม่มีการผลิต repo สาขาถูกดึงแล้ว ฉันจะแบ่งปันแหล่งที่มาสำหรับตรรกะนั้นอย่างมีความสุขหากได้รับการร้องขอ แต่โพสต์นี้จะยาวขึ้น
  • หากสคริปต์การทำให้ถูกสุขลักษณะ (ฝั่งเซิร์ฟเวอร์) ล้มเหลวด้วยเหตุผลบางอย่างแสดงว่าเซิร์ฟเวอร์ถูกทิ้งให้อยู่กับ repo ที่ทันสมัย ​​แต่แพ็คเกจการอัพเดทที่ไม่ซิงค์ / ขาดหายไปจึงgit rev-parse HEADจะส่งคืนแฮชที่ไม่ตรงกับสิ่งที่เกิดขึ้นจริง ส่งไปยังอุปกรณ์และปัญหาที่นี่จะต้องแก้ไขด้วยตนเองในบรรทัดคำสั่งเซิร์ฟเวอร์ นั่นคือเซิร์ฟเวอร์ไม่ทราบว่าแพคเกจโปรแกรมปรับปรุงนั้นไม่ถูกต้อง แต่จะถือว่าเป็นเช่นนั้นโดยสุจริต เมื่อรวมกับจุดก่อนหน้านี้ทำให้เซิร์ฟเวอร์มีความเปราะบางอย่างยิ่งในทางปฏิบัติ
  • หนึ่งในปัญหาที่ใหญ่ที่สุดคือ : ขณะนี้ไม่มี daemon ตัวอัปเดตแยกกันทำงานอยู่บนอุปกรณ์ เนื่องจากภาวะแทรกซ้อนที่กำลังรอการเข้าถึงอินเทอร์เน็ตไร้สายเพื่อมาและแฮกเกอร์ในนาทีสุดท้ายมันเป็นซอฟต์แวร์ควบคุมอุปกรณ์หลักที่ตรวจสอบและอัปเดตอุปกรณ์ ซึ่งหมายความว่าหากเวอร์ชันที่ทดสอบไม่ดีทำให้เกิดการผลิตและซอฟต์แวร์ควบคุมไม่สามารถเริ่มทำงานได้อุปกรณ์ทั้งหมดที่มีอยู่จะถูกปิดกั้นเพราะมันไม่สามารถอัปเดตตัวเองได้อีกต่อไป นี่จะเป็นฝันร้ายที่แท้จริงในการผลิต ข้อตกลงเดียวกันสำหรับอุปกรณ์เดียวหากสูญเสียพลังงานในเวลาที่โชคร้าย
  • ปัญหาที่สำคัญอื่น ๆ คือ : ไม่มีการสนับสนุนสำหรับการปรับปรุงที่เพิ่มขึ้น หากอุปกรณ์บอกว่าไม่ได้เปิดอยู่ครู่หนึ่งแล้วในครั้งต่อไปที่มีการอัพเดตอุปกรณ์จะข้ามรุ่นที่วางจำหน่ายจำนวนมากอุปกรณ์จะต้องสามารถทำการอัปเดตที่ข้ามเวอร์ชั่นได้โดยตรง ผลที่ตามมาของการปรับใช้นี้มีการปรับปรุงเป็นฝันร้ายของการทำให้แน่ใจว่าการปรับปรุงใด ๆ ที่สามารถนำมาใช้ด้านบนของรุ่นที่ผ่านมาที่กำหนดใด ๆ นอกจากนี้เนื่องจากแฮช git ใช้เพื่อระบุเวอร์ชันมากกว่าหมายเลขเวอร์ชันการเปรียบเทียบโดยย่อของเวอร์ชันเพื่อช่วยในการอัปเดตที่เพิ่มขึ้นจึงไม่สามารถทำได้ในขณะนี้
  • ข้อกำหนดใหม่ที่ฉันไม่สนับสนุนในปัจจุบันคือจะมีตัวเลือกการกำหนดค่าต่ออุปกรณ์ (คู่คีย์ / ค่า) ที่ต้องกำหนดค่าในฝั่งเซิร์ฟเวอร์การดูแลระบบ ฉันไม่รังเกียจที่จะให้บริการตัวเลือกต่ออุปกรณ์เหล่านี้กลับไปยังอุปกรณ์ในคำขอ HTTP เดียวกับการอัปเดตซอฟต์แวร์ ทำให้มันเป็นคำขอ HTTP แยกต่างหากเสมอ
  • มีความซับซ้อนเล็กน้อยเนื่องจากความจริงที่ว่ามีฮาร์ดแวร์สองรุ่น (และอื่น ๆ ในอนาคต) อยู่ เวอร์ชันปัจจุบันของฮาร์ดแวร์ถูกจัดเก็บเป็นตัวแปรสภาพแวดล้อมในภาพ SD เริ่มต้น (ไม่สามารถระบุตัวเองได้) และซอฟต์แวร์ทั้งหมดได้รับการออกแบบให้เข้ากันได้กับอุปกรณ์ทุกรุ่น เลือกอัพเดตเฟิร์มแวร์ตามตัวแปรสภาพแวดล้อมนี้และชุดอัพเดทประกอบด้วยเฟิร์มแวร์สำหรับฮาร์ดแวร์ทุกรุ่น ฉันสามารถอยู่กับสิ่งนี้ได้แม้ว่ามันจะเป็นเรื่องเล็กน้อย
  • ขณะนี้ไม่มีวิธีอัปโหลดการอัปเดตไปยังอุปกรณ์ด้วยตนเอง (เรื่องสั้นสั้น ๆ อุปกรณ์เหล่านี้มีอะแดปเตอร์ไร้สายสองตัวในตัวหนึ่งตัวสำหรับเชื่อมต่อกับอินเทอร์เน็ตและอีกตัวในโหมด AP ที่ผู้ใช้ใช้เพื่อกำหนดค่าอุปกรณ์ในอนาคต ฉันตั้งใจจะเพิ่มฟังก์ชั่น "อัปเดตซอฟต์แวร์" ลงในเว็บอินเตอร์เฟสของอุปกรณ์) นี่ไม่ใช่เรื่องใหญ่ แต่มีผลกระทบกับวิธีการติดตั้งการปรับปรุงบางอย่าง
  • กลุ่มของความผิดหวังอื่น ๆ และความไม่มั่นคงทั่วไป

ดังนั้น ... นั่นเป็นเวลานาน แต่คำถามของฉันยังคงเป็นเช่นนี้:

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

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


2
เนื่องจากอุปกรณ์ของคุณใช้ Linux ฉันขอแนะนำให้คุณพิจารณาใช้หนึ่งในผู้จัดการแพ็คเกจ Linux ที่อยู่ที่นั่น (apt, yum, rpm เป็นต้น) ในขั้นตอนแรกให้ตรวจสอบว่าการติดตั้งฐาน Linux ของคุณยังไม่มีมาหรือไม่
Bart van Ingen Schenau

คุณสามารถให้แนวคิดเกี่ยวกับขนาดของระบบได้หรือไม่? เรากำลังพูดถึง MB หรือ GB?
lbenini

MB; แพคเกจอัปเดตเมื่อ gzipped โดยทั่วไปแล้วจะมีขนาด 1-2MB
Jason C

คำตอบ:


1

คุณช่วยกรุณาให้ข้อมูลเพิ่มเติมเกี่ยวกับการกระจาย Linux, bootloader และสถาปัตยกรรม (x86, ARM, MIPS?) ที่ใช้งานอยู่หรือไม่?

ฉันจะพยายามเดาทางใดทางหนึ่งและหวังว่าจะพาคุณไปในทิศทางที่ถูกต้อง

หากที่เป็น distro Yocto ตามที่มี U-Boot ผมอยากแนะนำการดูที่mender.ioหรือswupdate โครงการเหล่านี้ดูเหมือนจะเหมาะสมกับเกณฑ์ดี เป้าหมายหลักของพวกเขาคือเพื่อให้แน่ใจว่าการปรับปรุงอะตอม

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

Mender มีเครื่องมือมากมายรวมถึง daemon (และสคริปต์ systemd จำนวนมาก) ที่เขียนใน Go ซึ่งจะช่วยยกภาระนี้จากไหล่ของคุณ โครงการนี้ใช้งานง่ายกับ Yocto (ให้ meta-layer สำหรับอุปกรณ์หลายอย่างที่ควรปรับให้เข้ากับกรณีและรูปแบบพาร์ติชั่นของคุณได้ง่ายพวกเขามีโซลูชั่นพร้อมใช้งานมากมายสำหรับ SOCs ยอดนิยมเช่นกัน) . ในกรณีที่คุณไม่ใช้ Yocto คุณสามารถดูโพสต์นี้ซึ่งจะอธิบายขั้นตอนที่คุณต้องทำเพื่อที่จะใช้กับ distros ที่ไม่ใช้ Yocto

swupdate นั้นยอดเยี่ยมเช่นกัน แต่ดูเหมือนว่าเป็นความพยายามของชายคนหนึ่งจาก DENX (องค์กรหลัง U-Boot) ดูเหมือนว่าเป็นผู้ใหญ่เช่นกัน

นอกจากนี้ยังมี Ubuntu Snappy ฉันไม่ได้มีประสบการณ์ใด ๆ และฉันไม่สามารถแสดงความคิดเห็นอย่างมีความสามารถเกี่ยวกับสิ่งนี้ได้ แนวคิดคือจัดส่งแอพใน "snaps" ในตัวเอง จากสิ่งที่ฉันเข้าใจนี่เป็นวิธีแก้ปัญหาของคุณแทบจะไม่ได้เนื่องจากมันไม่เป็นระบบ

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

ตามความเป็นจริงดูเหมือนว่าแนวโน้มในปัจจุบันคือการใช้ Docker (แม้ในระบบฝังตัว) และเพื่อน ๆ ผ่าน APT / YUM ยุคสุดท้ายอาจทำให้ยากมากที่จะรับรองความมั่นคง


นี่เยี่ยมมากฉันไม่แน่ใจว่าฉันไม่ได้สังเกตคำตอบนี้อย่างไร ฉันจะให้ข้อมูลที่ร้องขอเร็ว ๆ นี้โครงการนั้นถูกเลื่อนออกไปชั่วคราวและกลับมาทำงานต่อเมื่อวานนี้ดังนั้นฉันเพิ่งจะกลับมานั่งบนหลังม้าและปัญหานี้เป็นอันดับที่ 1
Jason C
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.