เหตุใดจึงแนะนำให้เรียกใช้กระบวนการเดียวเท่านั้นในคอนเทนเนอร์


79

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

ทำไมกฎนี้ถึงมีอยู่? ทำไมไม่เรียกใช้ ntp, nginx, uwsgi และกระบวนการอื่น ๆ ในคอนเทนเนอร์เดียวที่ต้องมีกระบวนการทั้งหมดเพื่อให้ทำงานได้?

โพสต์บล็อกที่กล่าวถึงกฎนี้:


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

@ J.Doe มันอาจจะไม่เป็นไร คอนเทนเนอร์แตกต่างจาก VMs มีปัญหาเล็ก ๆ หลายอย่างแม้แต่สำหรับแอปพลิเคชันขนาดเล็ก - สำหรับการเปิดตัวขององค์กรมันจะเป็นโครงการสองปีทำให้ทุกอย่างทำงานในคอนเทนเนอร์ในตอนแรก
Evgeny

คำตอบ:


65

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

  • การขยายภาชนะบรรจุในแนวนอนนั้นง่ายกว่ามากหากแยกภาชนะบรรจุเป็นฟังก์ชันเดียว ต้องการคอนเทนเนอร์อาปาเช่อื่นหรือไม่ หมุนขึ้นหนึ่งที่อื่น อย่างไรก็ตามถ้าคอนเทนเนอร์อาปาเช่ของฉันมี DB, cron และชิ้นส่วนอื่น ๆ ของฉันอยู่ด้วย
  • การมีฟังก์ชั่นเดียวต่อคอนเทนเนอร์ช่วยให้สามารถนำคอนเทนเนอร์กลับมาใช้ใหม่ได้อย่างง่ายดายสำหรับโครงการหรือวัตถุประสงค์อื่น ๆ
  • นอกจากนี้ยังทำให้สามารถพกพาและคาดการณ์ได้มากขึ้นสำหรับ devs ที่จะดึงส่วนประกอบจากการผลิตไปจนถึงการแก้ไขปัญหาในเครื่องแทนที่จะเป็นสภาพแวดล้อมแอปพลิเคชันทั้งหมด
  • การติดตั้ง / อัปเกรด (ทั้งระบบปฏิบัติการและแอปพลิเคชัน) สามารถทำได้ในลักษณะที่แยกและควบคุมได้มากขึ้น การเล่นกลหลายบิตและบ็อบในภาชนะของคุณไม่เพียง แต่สร้างภาพที่ใหญ่ขึ้นเท่านั้น แต่ยังเชื่อมโยงส่วนประกอบเหล่านี้เข้าด้วยกัน เหตุใดจึงต้องปิดแอปพลิเคชัน X และ Y เพื่ออัปเกรด Z
    • ข้างต้นถือเป็นจริงสำหรับการปรับใช้รหัสและการย้อนกลับ
  • ฟังก์ชันแบ่งออกเป็นหลายคอนเทนเนอร์ช่วยให้มีความยืดหยุ่นมากขึ้นจากมุมมองด้านความปลอดภัยและการแยก คุณอาจต้องการแยกบริการ (หรือต้องการ) ในระดับเครือข่ายไม่ว่าจะเป็นทางกายภาพหรือภายในเครือข่ายซ้อนทับเพื่อรักษาท่าทางความปลอดภัยที่แข็งแกร่งหรือปฏิบัติตามสิ่งต่างๆเช่น PCI
  • ปัจจัยเล็ก ๆ น้อย ๆ อื่น ๆ เช่นการจัดการกับ stdout / stderr และการส่งบันทึกไปยังบันทึกภาชนะเก็บภาชนะเป็นชั่วคราวที่สุด

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


1
ถึงกระนั้นก็ดูเหมือนอาร์กิวเมนต์ระดับต่ำกับกระทู้พอดีที่นี่ ... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
jeffmcneill

ยอดเยี่ยมคำตอบที่ครอบคลุม!
Rob Wells

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

27

มีการฆ่าภาชนะ "สองกระบวนการ" ไม่กี่วันที่ผ่านมามีบางจุดปวดสำหรับฉันซึ่งทำให้ฉันใช้สองภาชนะแทนสคริปต์หลามซึ่งเริ่มสองกระบวนการ:

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

นี่ควรเป็นคำตอบที่ยอมรับได้
ClintM

ตกลง ในขณะที่มีคำตอบอื่น ๆ อีกด้วยประเด็นสำคัญประเด็นสำคัญคือการจัดการ PID ของนักเทียบท่า 1
Brett Wagner

13

คำแนะนำมาจากเป้าหมายและการออกแบบการจำลองเสมือนระดับระบบปฏิบัติการ

ตู้คอนเทนเนอร์ได้รับการออกแบบมาเพื่อแยกกระบวนการสำหรับผู้อื่นโดยให้userpaceและระบบไฟล์ของตัวเอง
นี่คือวิวัฒนาการเชิงตรรกะchrootซึ่งได้จัดทำระบบไฟล์แยกขั้นตอนต่อไปคือการแยกกระบวนการจากคนอื่น ๆ เพื่อหลีกเลี่ยงการเขียนทับหน่วยความจำและอนุญาตให้ใช้ทรัพยากรเดียวกัน (เช่นพอร์ต TCP 8080 เช่นจากหลายกระบวนการโดยไม่มีความขัดแย้ง

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

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

นี่คือรายการที่ไม่ครบถ้วนสมบูรณ์ของการปรับแต่ง / ข้อผิดพลาดอย่างหนักที่ฉันสามารถนึกได้:

  • การจัดการบันทึก

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

  • ระวังกระบวนการซอมบี้

    หากหนึ่งในกระบวนการของคุณในคอนเทนเนอร์ล้มเหลว supervisord อาจไม่สามารถล้างค่า childs ในสถานะ zombie และโฮสต์ init จะไม่ได้รับสืบทอด เมื่อคุณหมดจำนวนของ pids ที่มีอยู่ (2 ^ 22 ดังนั้นประมาณ 4 ล้าน) สิ่งต่าง ๆ จะล้มเหลว

  • แยกความกังวล

    หากคุณเรียกใช้สองสิ่งที่แยกกันเช่นเซิร์ฟเวอร์ apache และ logstash ภายในคอนเทนเนอร์เดียวกันซึ่งอาจช่วยให้การจัดการบันทึกง่ายขึ้น แต่คุณต้องปิด apache เพื่ออัปเดต logstash (ในความเป็นจริงคุณควรใช้ไดรเวอร์การบันทึกของ Docker) มันจะเป็นการหยุดที่สง่างามที่รอให้เซสชันปัจจุบันสิ้นสุดหรือไม่? หากเป็นการหยุดที่สง่างามอาจใช้เวลานานและใช้เวลานานในการหมุนเวอร์ชั่นใหม่ หากคุณทำการฆ่าคุณจะส่งผลกระทบต่อผู้ใช้สำหรับผู้จัดส่งบันทึกและควรหลีกเลี่ยง IMHO

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


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

1
คุณยังไม่ได้อธิบายถึงประเภทของการปรับแต่งที่คุณมีในใจ และคุณยังไม่ได้ทำกรณีที่ tweaking นี้ทำงานได้ดีกว่าการตั้งค่าหลายภาชนะ ลองมาตัวอย่างที่เป็นรูปธรรม: คุณมักจะเห็นภาพนักเทียบท่าสำเร็จรูปที่มี supervisord ที่ใช้กระบวนการหลักบางอย่างและกระบวนการเสริมบางอย่าง การตั้งค่านี้ง่ายมาก เนื้อหาง่ายเหมือนการแยกภาชนะ เช่นแอป & ผู้ส่งบันทึก ฉันเชื่อว่าความรับผิดชอบของคุณเป็นสิ่งที่ยืนยันได้ว่าทำไมมันถึงไม่เป็นเช่นนั้น
Assaf Lavie

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

1
ที่น่าสนใจ ... ดูเหมือนว่าเรามีความคิดเห็นที่เหมือนกัน (เหมือนกัน) ในเรื่องนี้ บางทีคุณควรเพิกเฉยในกรณีนี้เพราะมันมาจากใครบางคนที่ต้องการได้รับตรา Critic ... และตัดสินใจที่จะใช้คำตอบของคุณเพื่อให้ได้ป้ายนี้ ...
Pierre.Vriens

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

6

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

มีหลายกรณีที่ต้องใช้หลายกระบวนการในคอนเทนเนอร์เดียวตราบใดที่ทั้งสองกระบวนการสนับสนุนฟังก์ชันโมดูลาร์เดียว


2

กระบวนการที่ฉันจะเรียกว่าเป็นบริการที่นี่1 บริการ ~ 1 บริการถ้าบริการใด ๆ ของฉันล้มเหลวฉันจะหมุนตู้คอนเทนเนอร์นั้นตามลำดับและภายในไม่กี่วินาทีทุกอย่างจะกลับมาอีกครั้ง ดังนั้นจะไม่มีการอ้างอิงใด ๆ ระหว่างบริการ วิธีปฏิบัติที่ดีที่สุดคือให้มีขนาดตู้คอนเทนเนอร์ของคุณน้อยกว่า 200 MB และสูงสุด 500 MB (ยกเว้นตู้คอนเทนเนอร์ที่เป็น Windows มากกว่า 2 GB) มิฉะนั้นจะมีลักษณะคล้ายกับเครื่องเสมือนไม่ใช่แค่ประสิทธิภาพเพียงพอ นอกจากนี้ยังคำนึงถึงพารามิเตอร์บางประการเช่นการปรับขนาดฉันจะทำให้บริการของฉันมีความยืดหยุ่นการปรับใช้อัตโนมัติ ฯลฯ ได้อย่างไร

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

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