หลายวันก่อน ฉันได้เผยแพร่คู่มือฉบับยาวและละเอียดเกี่ยวกับ Docker ซึ่งเป็นเทคโนโลยีการจำลองเสมือนระดับระบบปฏิบัติการที่ใช้ LXC ซึ่งมีวิธีการจัดเตรียมแอปพลิเคชันแบบคอนเทนเนอร์ที่รวดเร็ว น้ำหนักเบา และปลอดภัย น่ารัก.
ตอนนี้ หนึ่งในปัญหาที่เราพบเมื่อทดสอบบริการแรกของเรา SSH และ Apache คือการควบคุมบริการเหล่านี้ เราไม่มีสคริปต์ init หรือ systemd ภายในคอนเทนเนอร์ และพูดตามตรง เราอาจไม่ต้องการมัน แต่เราต้องการกลไกบางอย่างในการเริ่มต้น หยุด และอะไรก็ตามที่ไม่ใช่บริการของเรา แนะนำ Supervisord ดังนั้นบทช่วยสอนนี้ โปรดปฏิบัติตามฉัน.
สรุปผู้บังคับบัญชา
Supervisord คือระบบควบคุมกระบวนการที่ออกแบบมาเพื่อตรวจสอบและควบคุมกระบวนการ มันไม่ได้มีเป้าหมายที่จะแทนที่ init แต่จะสรุปกระบวนการภายในเฟรมเวิร์กของมันเอง และสามารถเริ่มต้นได้ในเวลาบูตเหมือนที่เราต้องการ ไม่มีเหตุผลที่จะต้องลงลึกเกี่ยวกับซอฟต์แวร์ ณ จุดนี้
การตั้งค่าหัวหน้างาน
โดยพื้นฐานแล้ว Supervisord คือโมดูลหลาม สามารถติดตั้งได้โดยใช้ easy_install ซึ่งเป็นส่วนหนึ่งของ setuptools ซึ่งเป็นส่วนเสริมของแพ็คเกจ Python distutils ใช่ มันค่อนข้างซับซ้อนในตอนนี้ โชคดีที่ลีนุกซ์ส่วนใหญ่มาพร้อมกับ easy_install รวมถึง CentOS ซึ่งเป็นแพลตฟอร์มทดสอบของเราในวันนี้
ในการดำเนินการ เราจะต้องติดตั้ง Supervisord ภายในคอนเทนเนอร์ จากนั้น เราจะส่งอิมเมจและใช้เป็นพื้นฐานสำหรับงานสร้างของเรา ซึ่งจะรวมถึงบริการต่างๆ เช่น SSH และ Apache ที่กล่าวถึงข้างต้น หากคุณพยายามติดตั้ง Supervisord บนโฮสต์ของคุณ คุณควรจะทำได้สำเร็จโดยไม่มีปัญหา:
easy_install หัวหน้างาน
ตามหาหัวหน้างาน
อ่าน https://pypi.python.org/simple/supervisor/
คู่ที่ดีที่สุด:หัวหน้างาน 3.1.3
กำลังดาวน์โหลด https://pypi.python.org/packages/source/s/supervisor/
หัวหน้างาน-3.1.3.tar.gz#md5=aad263c4fbc070de63dd354864d5e552
ผู้ควบคุมการประมวลผล-3.1.3.tar.gz
การเขียน /tmp/easy_install-vbOcMG/supervisor-3.1.3/setup.cfg
เรียกใช้ Supervisor-3.1.3/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vbOcMG/supervisor-3.1.3/egg-dist-tmp-i96mIs
คำเตือน:ไม่พบไฟล์ที่รวมไว้ก่อนหน้านี้ที่ตรงกับ '*' ภายใต้ไดเร็กทอรี 'docs/.build'
การเพิ่ม Supervisor 3.1.3 ไปยังไฟล์ easy-install.pth
การติดตั้งสคริปต์ echo_supervisord_conf ไปยัง /usr/bin
การติดตั้งสคริปต์ pidproxy ที่ /usr/bin
การติดตั้งสคริปต์ Supervisorctl ไปที่ /usr/bin
การติดตั้งสคริปต์ควบคุมไปยัง /usr/bin
ติดตั้งแล้ว
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg
การประมวลผลการพึ่งพาสำหรับหัวหน้างาน
กำลังค้นหา meld3>=0.6.5
อ่าน https://pypi.python.org/simple/meld3/
คู่ที่ดีที่สุด:meld3 1.0.2
กำลังดาวน์โหลด https://pypi.python.org/packages/source/m/meld3/
meld3-1.0.2.tar.gz#md5=3ccc78cd79cffd63a751ad7684c02c91
กำลังประมวลผล meld3-1.0.2.tar.gz
การเขียน /tmp/easy_install-wnhLVS/meld3-1.0.2/setup.cfg
วิ่ง meld3-1.0.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-wnhLVS/meld3-1.0.2/egg-dist-tmp-Lp88cX
ไม่ได้ตั้งค่าสถานะ zip_safe; กำลังวิเคราะห์เนื้อหาที่เก็บถาวร...
การเพิ่ม meld3 1.0.2 ไปยังไฟล์ easy-install.pth
ติดตั้งแล้ว /usr/lib/python2.7/site-packages/meld3-1.0.2-py2.7.egg
เสร็จสิ้นการประมวลผลการอ้างอิงสำหรับหัวหน้างาน
ภายในคอนเทนเนอร์ คุณจะได้รับข้อผิดพลาด เนื่องจากเฟรมเวิร์ก Python ที่เพิ่มลงในคอนเทนเนอร์นั้นไม่สมบูรณ์ และโมดูลบางส่วนขาดหายไป
# easy_install หัวหน้างาน
Traceback (การโทรครั้งล่าสุดล่าสุด):
ไฟล์ "/usr/bin/easy_install" บรรทัดที่ 5 ใน <โมดูล>
จาก pkg_resources นำเข้า load_entry_point
ImportError:ไม่มีโมดูลชื่อ pkg_resources
ซึ่งหมายความว่าเราจะต้องตั้งค่า easy_install:
ด้วยตนเอง
wget https://bitbucket.org/pypa/setuptools/raw/ ->
-> bootstrap/ez_setup.py -O - | หลาม
การกำหนดค่าหัวหน้างาน
ขั้นตอนต่อไปคือการสร้างการกำหนดค่าสำหรับคอนเทนเนอร์ เราสามารถสร้างไฟล์บนโฮสต์ จากนั้นเราจะคัดลอกลงในอิมเมจของเราในระหว่างกระบวนการสร้างโดยใช้คำสั่ง COPY ใน Dockerfile ของเรา
สำเนา ./supervisord.conf /etc/supervisord.conf
การกำหนดค่าจะเป็นดังนี้:
[หัวหน้างาน]
โนดาเอมอน=จริง
[โปรแกรม:sshd]
command=/usr/sbin/sshd -D
[โปรแกรม:httpd]
command=/bin/bash -c "exec /usr/sbin/httpd -DFOREGROUND"
เรามีอะไรที่นี่? คู่วงเล็บเหลี่ยมแต่ละคู่กำหนดส่วน สำหรับ Supervisor เอง เรากำหนดไว้ว่าควรเริ่มต้นในเบื้องหน้ามากกว่า daemonize เอง ซึ่งจะหมายถึงการกลายเป็นบริการเบื้องหลัง
สำหรับโปรแกรมชื่อ sshd เรารันคำสั่งที่เกี่ยวข้อง โดยพื้นฐานแล้วรัน SSHD อยู่เบื้องหลัง สำหรับโปรแกรมชื่อ httpd เราเริ่มต้นเซิร์ฟเวอร์ในเบื้องหน้า ในเชลล์แยกต่างหาก มีตัวเลือกอื่น ๆ มากมาย แต่ในขณะนี้ นี่เป็นขั้นต่ำสุดที่เราต้องดำเนินการกับหัวหน้างาน
การเรียกใช้คอนเทนเนอร์ &การแก้ไขปัญหา
หลังจากที่เราสร้างอิมเมจและเรียกใช้แล้ว หัวหน้างานควรเข้ามาเริ่มกระบวนการของเรา แต่ก่อนอื่น เรามาจัดการกับข้อผิดพลาดทั่วไปบางประการกันก่อน สิ่งหนึ่งที่คุณอาจเห็นคือ:
นักเทียบท่ารัน -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
Supervisord กำลังทำงานในฐานะ root และกำลังค้นหาไฟล์การกำหนดค่าในตำแหน่งเริ่มต้น (รวมถึงไดเร็กทอรีการทำงานปัจจุบัน) คุณอาจต้องการระบุอาร์กิวเมนต์ "-c" ที่ระบุพาธสัมบูรณ์ไปยังไฟล์คอนฟิกูเรชันเพื่อความปลอดภัยที่ดีขึ้น
'หัวหน้างานกำลังทำงานในฐานะรูทและกำลังค้นหา'
ข้อผิดพลาด:ไม่พบไฟล์กำหนดค่าที่เส้นทางเริ่มต้น (/usr/etc/supervisord.conf, /usr/supervisord.conf, Supervisord.conf, etc/supervisord.conf, /etc/supervisord.conf); ใช้ตัวเลือก -c เพื่อระบุไฟล์ปรับแต่งที่พาธอื่น
หากต้องการความช่วยเหลือ ให้ใช้ /usr/bin/supervisord -h
หากคุณระบุเส้นทางที่ไม่ถูกต้องสำหรับไฟล์ Supervisord.conf หรือใช้ชื่อที่ไม่ถูกต้อง บริการจะไม่สามารถเรียกใช้ได้ คุณจะต้องแก้ไขคำสั่ง COPY สร้างภาพใหม่และเริ่มต้นใหม่ จากนั้น ข้อผิดพลาดถัดไปที่คุณอาจพบคือ:
# นักเทียบท่ารัน -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
Supervisord กำลังทำงานในฐานะ root และกำลังค้นหาไฟล์การกำหนดค่าในตำแหน่งเริ่มต้น (รวมถึงไดเร็กทอรีการทำงานปัจจุบัน) คุณอาจต้องการระบุอาร์กิวเมนต์ "-c" ที่ระบุพาธสัมบูรณ์ไปยังไฟล์คอนฟิกูเรชันเพื่อความปลอดภัยที่ดีขึ้น
'หัวหน้างานกำลังทำงานในฐานะรูทและกำลังค้นหา'
372 CRIT Supervisor ทำงานในฐานะรูท (ไม่มีผู้ใช้ในไฟล์ปรับแต่ง)
375 INFO Supervisord ขึ้นต้นด้วย pid 1
378 INFO กลับกลายเป็น:'httpd' ด้วย pid 9
381 INFO กลับกลายเป็น:'sshd' ด้วย pid 10
602 INFO ออกแล้ว:httpd (สถานะออก 1 ไม่คาดหวัง)
606 INFO กลับกลายเป็น:'httpd' ด้วย pid 11
606 INFO สำเร็จ:sshd เข้าสู่สถานะ RUNNING กระบวนการยังคงอยู่นานกว่า 1 วินาที (startsecs)
671 INFO ออกแล้ว:httpd (สถานะออก 1 ไม่คาดหวัง)
676 INFO กลับกลายเป็น:'httpd' ด้วย pid 12
742 INFO ออกแล้ว:httpd (สถานะออก 1 ไม่คาดหวัง)
749 INFO กลับกลายเป็น:'httpd' ด้วย pid 13
825 INFO ออกแล้ว:httpd (สถานะออก 1 ไม่คาดหวัง)
826 INFO ยอมแพ้:httpd เข้าสู่สถานะ FATAL มีการลองเริ่มใหม่หลายครั้งเกินไปเร็วเกินไป
ยอมแพ้:httpd เข้าสู่สถานะ FATAL มีการลองเริ่มต้นใหม่เร็วเกินไป
สิ่งที่เรามีคือเธรด Apache ออกจากการทำงาน บังคับให้ Supervisor ลองเริ่มต้นใหม่อีกครั้ง และในที่สุดก็ล้มเลิก ซึ่งนำเราไปสู่สถานะที่ร้ายแรง คอนเทนเนอร์ของเราค่อนข้างไร้ประโยชน์ ณ จุดนี้
ในที่นี้ วิธีแก้ปัญหาคือแก้ไขไฟล์ Supervisord.conf และแนะนำคำสั่งเพิ่มเติมในส่วนโปรแกรม httpd ซึ่งจะจัดการกับกระบวนการวางไข่ในลักษณะที่สละสลวยยิ่งขึ้น
[โปรแกรม:httpd]
สตาร์ทเซค =0
รีสตาร์ทอัตโนมัติ =เท็จ
command=/bin/bash -c "exec /usr/sbin/httpd -DFOREGROUND"
เราได้เพิ่ม startecs =0 และ autorestart =false คำสั่งแรกบอกเราว่า:
จำนวนวินาทีทั้งหมดที่โปรแกรมจำเป็นต้องทำงานต่อไปหลังจากเริ่มต้นระบบเพื่อพิจารณาการเริ่มต้นที่สำเร็จ หากโปรแกรมไม่คงอยู่เป็นเวลาหลายวินาทีหลังจากเริ่มทำงาน แม้ว่าจะออกด้วยรหัสทางออกที่คาดไว้ (ดูรหัสทางออก) การเริ่มต้นระบบจะถือว่าล้มเหลว
อันที่สองหมายความว่า Supervisord จะไม่จัดการการรีสตาร์ทเธรดของ Apache และสิ่งเหล่านี้จะถูกจัดการโดยเว็บเซิร์ฟเวอร์เอง เนื่องจากจะจัดการกับคำขอ HTTP ที่เข้ามา
อาจเป็นเท็จ คาดไม่ถึง หรือจริงอย่างใดอย่างหนึ่ง หากเป็นเท็จ กระบวนการจะไม่เริ่มต้นใหม่โดยอัตโนมัติ หากไม่คาดคิด กระบวนการจะเริ่มต้นใหม่เมื่อโปรแกรมออกด้วยรหัสออกที่ไม่ใช่รหัสออกที่เกี่ยวข้องกับการกำหนดค่ากระบวนการนี้ (ดูรหัสออก) หากเป็น "จริง" กระบวนการจะเริ่มต้นใหม่โดยไม่มีเงื่อนไขเมื่อออกจากระบบ โดยไม่คำนึงถึงรหัสการออก
ตอนนี้เราสามารถลองเรียกใช้คอนเทนเนอร์อีกครั้ง จำปัญหา /run/httpd ที่เราพบในคู่มือต้นฉบับได้หรือไม่ หากไม่มีไดเร็กทอรี /run คุณจะเห็นข้อความต่อไปนี้:
นักเทียบท่ารัน -ti -p 22 -p 80 image-3:latest
/usr/lib/python2.7/site-packages/supervisor-3.1.3-py2.7.egg/
Supervisord กำลังทำงานในฐานะ root และกำลังค้นหาไฟล์การกำหนดค่าในตำแหน่งเริ่มต้น (รวมถึงไดเร็กทอรีการทำงานปัจจุบัน) คุณอาจต้องการระบุอาร์กิวเมนต์ "-c" ที่ระบุพาธสัมบูรณ์ไปยังไฟล์คอนฟิกูเรชันเพื่อความปลอดภัยที่ดีขึ้น
'หัวหน้างานกำลังทำงานในฐานะรูทและกำลังค้นหา'
913 CRIT Supervisor ทำงานในฐานะรูท (ไม่มีผู้ใช้ในไฟล์ปรับแต่ง)
916 INFO Supervisord ขึ้นต้นด้วย pid 1
919 INFO กลับกลายเป็น:'httpd' ด้วย pid 8
921 INFO กลับกลายเป็น:'sshd' ด้วย pid 9
079 INFO สำเร็จ:httpd เข้าสู่สถานะ RUNNING กระบวนการค้าง> มากกว่า 0 วินาที (startsecs)
105 INFO ออกแล้ว:httpd (สถานะออก 0; คาดไว้)
120 INFO เก็บเกี่ยว pid ที่ไม่รู้จัก 10
122 INFO สำเร็จ:sshd เข้าสู่สถานะ RUNNING กระบวนการค้าง> มากกว่า 1 วินาที (startsecs)
ณ จุดนี้ คุณต้องเชื่อมต่อ (แนบหรือเรียกใช้เชลล์ BASH) กับคอนเทนเนอร์ ตรวจสอบบันทึก และพยายามทำความเข้าใจว่าทำไมบริการไม่ทำงานตามที่คาดไว้
การทดสอบที่ประสบความสำเร็จ
และเมื่อเราจัดการทุกอย่างเรียบร้อยแล้ว:
สรุป
นี่เป็นบทช่วยสอนที่ค่อนข้างโง่ แต่มันได้แนะนำเครื่องมือที่มีประโยชน์อีกอย่างในคลังแสงของเรา ซึ่งตอนนี้เราสามารถใช้ควบคุมบริการภายในคอนเทนเนอร์ได้อย่างแข็งแกร่งและสวยงาม โดยไม่ต้องติดตั้งเฟรมเวิร์กที่ซับซ้อนและมีราคาแพงอย่าง systemd นอกจากนี้ยังสอนเพิ่มเติมเกี่ยวกับ Docker วิธีทำงานและแก้ไขปัญหาและอื่น ๆ
Supervisord นั้นไม่จำเป็นนัก เพราะเราสามารถเรียกใช้กระบวนการ sshd และ httpd ของเราได้โดยไม่ต้องใช้กระบวนการนี้ แต่บางคนอาจชอบวิธีนี้ โดยเฉพาะอย่างยิ่งหากพวกเขาต้องเริ่มและเริ่มบริการใหม่ค่อนข้างบ่อย ไม่ว่าจะด้วยวิธีใด การทำความคุ้นเคยกับยูทิลิตีจะช่วยสร้างความเข้าใจและความมั่นใจในกลไกของ Docker ฉันหวังว่าคุณจะพบว่าคู่มือนี้มีประโยชน์ และโปรดส่งคำขอของคุณเกี่ยวกับสิ่งที่เราควรสำรวจต่อไป
ไชโย