เริ่มบริการ systemd ภายใน chroot


38

ด้วยสคริปต์เริ่มต้น (หรือด้วย openrc) ฉันสามารถเรียกใช้บริการจากรูทการติดตั้งอื่นได้เสมอ
แต่เมื่อฉันวิ่งchroot /somepath/to_root /usr/bin/systemctl start someserviceฉันได้:

Running in chroot, ignoring request.

มีวิธีบังคับให้ systemd เปิดใช้บริการหรือไม่?

อัปเดต:
ฉันลืมที่จะพูดว่าระบบโฮสต์ของฉันเรียกใช้สคริปต์ init หรือ openrc แต่ไม่เคย systemd และฉันใช้ chroot เพื่อแก้ไขปัญหาระบบ Unix ที่ไม่สามารถแม้แต่จะเปิดตัวเชลล์ขั้นต่ำ


1
ฉันยังต้องใช้บริการเป็น chroot มันเคยทำงานก่อน openrc2 ดูเหมือนว่าเป็นไปไม่ได้ตอนนี้ (
neofutur

คุณกำลังพยายามแก้ไขปัญหาที่ผิด หากคุณมี OpenRC คุณต้องเปลี่ยนบริการ systemd เป็นบริการ OpenRC ไม่มีทางที่จะเป็นไปได้
Daniel B

@DanielB: ไม่! คุณเคยได้ยิน systemrescuecd ไหม?
2284570

ไม่ฉันยังไม่เห็นความเกี่ยวข้องกับคำถามของคุณ
Daniel B

คำตอบ:


29

ปัญหาที่เป็นที่รู้จักกันดีใน systemd distros (Arch Linux, OpenSUSE, Fedora)

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

นี่ก็หมายความว่าเมื่อฉันเรียก systemctl จากภายใน chroot มันไม่เกี่ยวข้องว่าฉันอยู่ใน chroot สภาพแวดล้อมที่จะได้รับการสืบทอดยังคงเป็น PID 1 ไม่ใช่ของฉันในปัจจุบัน แต่มันแย่กว่านี้: เนื่องจากซ็อกเก็ตการสื่อสารอยู่ภายใน / run / systemd กระบวนการใน chroot จะไม่สามารถพูดคุยกับระบบ init ได้!

ดังนั้นคุณจะไปเกี่ยวกับ chroot'ing ใน systemd distros อย่างไร

  1. หากสิ่งที่คุณต้องการจะทำคือมีภาชนะลินุกซ์หน้านี้ Arch วิกิพีเดียจะบอกคุณวิธีการตั้งค่าภาชนะลินุกซ์ในเวลาน้อยกว่า 30 systemd-nspawnวินาทีขอบคุณ

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


ฉันค้นหาsystemd-nspawnแต่ฉันไม่สามารถเรียกใช้ และไม่ใช่สิ่งนี้ไม่ได้มีไว้สำหรับคอนเทนเนอร์เนื่องจากบริการจำเป็นต้องใช้ทั้งโฮสต์และสถาปัตยกรรมเป้าหมาย
user2284570

2
ฉันไม่เคยใช้ systemd ในรูทระบบโฮสต์ ในกรณีของฉันฉันไม่สามารถผสม systemd กับ openrc
user2284570

1
@TwoD ที่จะไม่ทำงาน วิ่งsystemd-nspawnล้มเหลวด้วย "ไม่ทำงานบนระบบ systemd" นอกเสียจากโฮสต์จะใช้ systemd เช่นกัน
hvd

1
@TwoD และฉันตอบเพราะมันฟังดูไม่เป็นแบบนั้นเลย :) "ฉันไม่สามารถเรียกใช้" เป็นสิ่งที่แปลกที่จะพูดว่าถ้าคุณมีปัญหาในการค้นหาไฟล์ปฏิบัติการซึ่งเป็นสาเหตุที่ฉันสงสัยว่าปัญหาคือสิ่งที่ฉันใส่ในความคิดเห็นของฉัน: การเรียกใช้จะให้ข้อความแสดงข้อผิดพลาดนั้น ไม่มีประโยชน์อะไรเลย แต่ถึงแม้ว่ามันจะเปิดออกปัญหาจริง ๆ แล้วเป็นที่ที่จะหาsystemd-nspawnแล้วชี้ไปที่รากใหม่จะไม่ช่วย โฮสต์นั้นมีอยู่แล้ว (เพราะมันทำงานอยู่ systemd) ซึ่งในกรณีนี้สามารถใช้เวอร์ชันโฮสต์ได้หรือโฮสต์ไม่มีโฮสต์อยู่ แต่เวอร์ชันรูทใหม่จะไม่ทำงาน
hvd

1
systemdจะปฏิเสธไม่ให้เข้าร่วมchroot
Erkin Alp Güney

4

systemd ละเว้น "บริการ" เท่านั้นดังนั้นฉันเพียงแค่เรียกใช้คำสั่ง daemon ด้วยตนเอง

ดังนั้นแทนที่จะ

service sshd start

ฉันใช้

/usr/sbin/sshd -D &

สิ่งนี้ใช้ไม่ได้กับบริการทั้งหมด บางคนต้องมีการเริ่มต้นเป็นส่วนหนึ่งของบริการเริ่มต้นระบบเช่น Xorg
2284570

startxXorgจะทำงานให้
Erkin Alp Güney

@ ErkinAlpGüney: ไม่ได้อยู่ที่ chroot …เพราะ Dbus
user2284570

4

หลายปีที่ผ่านมาฉันต้องยอมรับว่ามีทางออกเดียวที่จะแก้ปัญหาในทางปฏิบัติของ Systemd ส่วนใหญ่ เพราะข้อผิดพลาดคือ Systemd ตัวเอง

ฉันเบื่อหน่ายกับ Systemd จริงๆเพราะฉันมีปัญหาที่ฉันไม่เคยเผชิญกับสิ่งต่าง ๆ เช่น Upstart หรือ Openrc:

  • การบังคับใช้เคอร์เนลที่ต้องการการสนับสนุนกลุ่ม cg (แทนที่จะเป็นทางเลือก แต่เปิดใช้งานโดยค่าเริ่มต้นภายในไฟล์ปรับแต่ง) แม้สำหรับระบบฝังตัวที่มี RAM เพียง 24Mbและไม่มีที่เก็บข้อมูลที่เขียนได้
  • แม้จะมีการอ้างว่าเป็นแบบแยกส่วน แต่ตอนนี้นรกที่พึ่งพานั้นทำให้มันเป็นวัตถุเทพเจ้าที่แข็งแกร่ง: ต้องการบูตผ่านรูต reiser4 เดี่ยวหรือไม่ มันเป็นไปไม่ได้เพราะหลาย ๆ โปรแกรมต้องการsystemd-udevdสิ่งที่ต้องการsystemd-initซึ่งจำเป็นต้องมีsystemd-bootแพ็คเกจที่ไม่สามารถติดตั้งได้ในเวลาเดียวกันมากกว่าgrub2หรือไม่สามารถอ่านภาพเคอร์เนลจากพาร์ติชั่น reiser4
  • ต้องการเชื่อมต่ออินเทอร์เน็ตผ่าน dialup Bluetooth หรือไม่ ถ้ามันไม่ได้ทำงานกับ Java ME networkdโทรศัพท์ซัมซุงของคุณแล้วคุณจะไม่สามารถเรียกใช้สคริปต์และซอฟต์แวร์บรรทัดคำสั่งที่ทำงานก่อนหน้านี้ด้วยตนเองเพราะ
  • แม้ว่าฉันจะรู้ว่าปัญหาที่ใหญ่ที่สุดคือถ้าคุณกำลังสร้างและบำรุงรักษาลีนุกซ์ลีนุกซ์ของคุณเอง, แต่ตัวโมดูล systemd init นั้นมีการพึ่งพามากจนคุณไม่สามารถเสนอให้เลือกระบบเริ่มต้นอื่นผ่านแพ็คเกจการติดตั้งที่แตกต่างกัน.
  • โชคดีสำหรับการดูบันทึกถ้าคุณไม่สามารถ chroot ในระบบของคุณหรือถ้าคุณปรับรุ่นจาก libdb4.8 (ในขณะที่อย่างน้อยในกรณีที่เลวร้ายที่สุดไมโครซอฟท์มีล็อกไฟล์ของมันในรูปแบบ XML)

ทางออกเดียว:

Systemd เป็นสิ่งที่ไม่จำเป็นในการแก้ปัญหาเช่น alsa แทนที่จะเป็น ossv4 ดังนั้นหากคุณมีสิ่งที่ใช้ systemd เพียงแค่ล้างข้อมูลทั้งหมด:

dd if=/dev/urandom of=/dev/dm−0 bs=1M

และติดตั้งสิ่งที่ไม่ได้ใช้งานเลยในขณะที่แก้ไขปัญหาของ SysV Init เช่น Gentoo ด้วย Openrc
ที่เกี่ยวข้องกับคำถามของฉัน systemd ทำให้สิ่งต่าง ๆ เช่นการลงทะเบียนWindows®: ถ้าส่วนหนึ่งของมันถูกทำให้เมาขึ้น


3
โปรดทราบว่าการออกแบบบางสิ่งสามารถป้องกันไม่ให้ได้รับคำตอบจริงๆเพื่อให้คำตอบคือเปลี่ยนไปใช้สิ่งที่ใช้งานได้ และนี่คือคำตอบที่แท้จริง
user2284570

1
ฉันมีความคิดเห็นแบบเดียวกันตอนนี้ฉันอยู่ในมุมมองที่สมดุลมากขึ้นเล็กน้อย Systemd มีข้อได้เปรียบที่ยิ่งใหญ่มากซึ่งมันสามารถฆ่าสิ่งที่ควรถูกฆ่าได้ มันเป็นเพราะมันติดตามกระบวนการย่อยที่แยกทั้งหมดด้วยคุณสมบัติเคอร์เนล cgroup ไม่มีเครื่องมือรุ่นเก่าที่สามารถทำเช่นนั้นได้ นอกจากนี้คุณจำอึของสคริปต์ใน /etc/init/*.sh?I ได้เช่นกัน แต่วันนี้มันเป็นเพียงความทรงจำที่แย่สำหรับฉัน แฟ้มบริการ systemd มีความชัดเจนและประมาณ 10 เส้นยาวconfigs ไม่ได้ 200 สายยาวสคริปต์ ข้อได้เปรียบที่ยิ่งใหญ่เหล่านี้มี systemd ฉันยอมรับว่าคุณสมบัติอื่น ๆ ทั้งหมดมีข้อเสีย
เตอร์กล่าวคืนสถานะโมนิก้า

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

@ peterh: น่าเสียดายที่ไม่ใช่ทุกคนที่แบ่งปันฉันหมายถึงจุดลบโพสต์ สิ่งนี้ไม่เกี่ยวกับ SysV init กับ Systemd แต่เพิ่มเติมจากสิ่งต่าง ๆ เช่น Openrc หรือแม้แต่ Upstart (ซึ่งอนุญาตให้ใช้สคริปต์เริ่มต้นระบบสั้นรวมถึงการเริ่มบริการแบบขนาน) อย่างน้อยฉันได้เรียนรู้สิ่งหนึ่ง: ดาร์วินส่วนใหญ่เป็นᴏꜱของ Apple ™ Windows คือᴏꜱของ Microsoft และการออกแบบ Linux ส่วนใหญ่ทำงานโดยหมวกสีแดง แม้ว่า SysV init จะช้ากว่า แต่ก็ไม่ได้ จำกัด คุณในสิ่งที่คุณสามารถทำได้ในขณะใช้งานจริง
user2284570

สคริปต์ @peterh Services นั้นชัดเจนมากเมื่อคุณใช้ Openrc ปัญหาเกี่ยวกับ cgroup บน Systemd ไม่ใช่ตัวเลือกที่ป้องกันการทำงานของ Systemd เช่น Darwin หรือ NetBSD
2284570

3

ไม่บริการจะดำเนินการโดย systemd (pid 1) ไม่ใช่โดย systemctl โดยตรง (ซึ่งส่งการร้องขอเริ่มต้นเท่านั้น) และเนื่องจาก systemd ทำงานนอก chroot ดังนั้นบริการจะทำเช่นนั้น

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


1
ดี แต่ฉันต้องใช้ systemctl เนื่องจากระบบโฮสต์ของฉันใช้ oepnrc ฉันต้องการโซลูชันอิสระเต็มรูปแบบ
user2284570

3
ฉันจะทำน้ำโคลนมากขึ้นอีกโดยพูดว่า: Psst! พูดถึงRootDirectory=เช่นกันเนื่องจากคุณเป็นอันตรายอย่างมากจาก upvotes (-:
JdeBP

@JdeBP: อะไรคือความแตกต่าง (ในแง่ของผลลัพธ์) ระหว่างตัวแปรRootDirectoryและchrootคำสั่ง?
2284570

@grawity: ถ้าอย่างนั้นpid 1จะผนวกอะไรกัน
user2284570

1

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

service --skip-redirect <service> restart

หรือ:

SYSTEMCTL_SKIP_REDIRECT=_ /etc/init.d/<service> restart

ดี แต่มันจะทำงานเฉพาะกับมรดกบริการที่รองรับ Init (จะไม่ทำงานสำหรับเครือข่ายใน Fedora หนัง) ดังที่ฉันพูดในคำตอบของฉันทางออกที่แท้จริงคือการทำให้ทุกอย่างที่ใช้ systemd หมดไป
2284570

0

หากคุณกำลังเรียกใช้บริการ inetd-style ด้วยการเปิดใช้งานซ็อกเก็ตให้ลองเรียกใช้ stunnel แทนด้วยไฟล์การกำหนดค่าที่ระบุทั้ง chroot และไบนารีของคุณเป็นเป้าหมายการเปิดตัวแบบ inetd

โปรดทราบว่าคุณอาจมีปัญหา SELINUX ในระบบ Oracle Linux 7.1 ฉันต้อง "chcon -v --type = stunnel_etc_t" ในไฟล์ทั้งหมดที่ต้อง stunnel เพื่ออ่าน

คุณจะต้องใช้การเข้ารหัส TLS ในฝั่งไคลเอ็นต์ของซ็อกเก็ต (เช่น stunnel อื่นด้วย "client = yes" ในการกำหนดค่า) แจ้งให้เราทราบหากคุณต้องการรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้


ไม่มันเกี่ยวกับสิ่งต่าง ๆ เช่น d-bus ฉันทำเพื่อวินิจฉัยปัญหาใน chroot เป้าหมาย
2284570

-1

คุณสามารถใช้nohupคำสั่งเพื่อเริ่มบริการใน chroot เพื่อเริ่มhttpdบริการเช่นฉันทำเช่นนี้

nohup httpd /dev/null &

เพื่อหยุดมัน pkill httpd


บริการเช่น Dbus นั้นสามารถเริ่มได้โดยสคริปต์ไบนารี systemd ที่ติดตั้งไว้เท่านั้น
2284570

คุณสามารถเริ่มบริการดังกล่าวจากไดเรกทอรีด้วยคำสั่งเริ่มต้น
ellooku

ซึ่งเป็น symlink ต่อ systemctl ดังนั้นจึงไม่ทำงาน
2284570

ฉันทำสิ่งนี้ตลอดเวลาที่ Fedora ทำงานบน Android ฉันอาจไม่รู้ว่าปัญหาของคุณคืออะไร
ellooku

Running in chroot, ignoring request.ผลที่ตามมาคือข้อความนี้: ฉันไม่คิดว่าคุณจะทำมันตลอดเวลาแม้ว่า chroot อันที่จริงสคริปต์เริ่มต้นนั้นต้องการ systemd
2284570
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.