Avviare un servizio systemd all'interno di chroot


38

Con gli script init (o con openrc) potrei sempre eseguire servizi da una diversa root di installazione.
ma quando corro chroot /somepath/to_root /usr/bin/systemctl start someserviceho ottenuto:

Running in chroot, ignoring request.

C'è un modo per forzare l'esecuzione del servizio da parte di systemd?

Aggiornamento:
ho dimenticato di dire che il mio sistema host esegue script di init o openrc, ma mai systemd, e che uso chroot per risolvere i problemi dei sistemi Unix che non possono nemmeno avviare una shell minima.


1
Ho anche bisogno di eseguire i servizi in un chroot, ha sempre funzionato prima di openrc2, ora sembra impossibile; (
neofutur,

Stai cercando di risolvere il problema sbagliato. Se si dispone di OpenRC, è necessario convertire il servizio systemd in un servizio OpenRC. Non c'è davvero modo di evitarlo.
Daniel B

@DanielB: NO! Hai mai sentito parlare di systemrescuecd?
user2284570

No. Inoltre, non vedo come si collega alla tua domanda.
Daniel B,

Risposte:


29

Un problema ben noto nelle distribuzioni di sistema (Arch Linux, OpenSUSE, Fedora).

Systemd sostituisce sysvinit e offre un grande vantaggio. In sysvinit, quando chiedi a un servizio di avviarsi, eredita il contesto di esecuzione della persona che invoca lo script, che include variabili di ambiente, ulimits e così via. Al contrario Systemd migliora su questo notificando un demone, che avvierà il servizio in un ambiente ben definito, sano e costante, dove ovviamente le prestazioni dei servizi sono molto più facili da prevedere, poiché l'ambiente è sempre lo stesso.

Ciò implica che, quando chiamo systemctl dall'interno del chroot, è irrilevante che io sia all'interno di chroot, l'ambiente che verrà ereditato è ancora quello del PID 1, non quello attuale. Ma c'è di peggio: dato che i socket di comunicazione sono collocati in / run / systemd, un processo in un chroot non sarà nemmeno in grado di parlare con il sistema init!

Quindi, come fai a fare chroot in distrazioni sistemate?

  1. Se tutto ciò che vuoi fare è avere un contenitore Linux, questa pagina Wiki Arch ti spiegherà come impostare un contenitore Linux in meno di 30 secondi, grazie a systemd-nspawn.

  2. Se invece vuoi davvero un ambiente chroot, questa bellissima e cristallina pagina Web ti fornirà due soluzioni funzionanti (la seconda è una versione modificata di quella offerta al punto 1).


Ho cercato systemd-nspawnma non posso eseguirlo. E No, questo non è per un contenitore poiché il servizio deve essere utilizzato sia dall'host che dall'architettura di destinazione.
user2284570,

2
Che non uso mai systemd nella mia radice del sistema host. Nel mio caso non posso mescolare systemd con openrc.
user2284570

1
@DueD Non funzionerà. L'esecuzione systemd-nspawnnon riesce con "Non in esecuzione su un sistema systemd". a meno che l'host non stia utilizzando anche systemd.
hvd,

1
@DwoD E ho risposto perché non mi sembra affatto così. :) "Non riesco a eseguirlo" è una cosa strana da dire se hai problemi a trovare l'eseguibile, motivo per cui sospetto che il problema sia quello che ho inserito nel mio commento: eseguirlo dà quel messaggio di errore e non non fare nulla di utile. Ma anche se si scopre che il problema era davvero dove trovare systemd-nspawn, quindi indicare la nuova radice non aiuta. O l'host lo ha già (perché è in esecuzione systemd), nel qual caso la versione host può essere utilizzata, oppure l'host non ce l'ha, ma la nuova versione di root non funzionerà.
hvd,

1
systemdrifiuterà di correrechroot
Erkin Alp Güney

4

systemd ignora solo i "servizi", quindi eseguo manualmente i comandi daemon.

Quindi invece di

service sshd start

Io uso

/usr/sbin/sshd -D &

Questo non funziona per tutti i servizi. Alcuni richiedono di essere avviati come parte dell'avvio del servizio di sistema come Xorg.
user2284570

startxfunzionerà per Xorg.
Erkin Alp Güney,

@ ErkinAlpGüney: non in chroot ... A causa di Dbus.
user2284570

4

Diversi anni dopo devo ammettere che esiste solo una soluzione alla maggior parte dei problemi pratici di Systemd. Perché l'errore è Systemd stesso

Sono davvero stufo di Systemd poiché ho avuto problemi che non ho mai affrontato con cose come Upstart o Openrc:

  • L'applicazione di un kernel che richiede il supporto di cgroups (invece di essere resa facoltativa ma abilitata per impostazione predefinita all'interno di un file di configurazione) anche per sistemi embedded con solo 24 Mb di RAM e nessuna memoria scrivibile.
  • Nonostante la pretesa di essere modulare, in fase di esecuzione l'inferno delle dipendenze lo rende un forte oggetto divino: vuoi avviare un singolo refs4 rootfs? Non è possibile perché molti programmi richiedono ciò systemd-udevdche richiede systemd-initche richiede il systemd-bootpacchetto che non può essere installato contemporaneamente, grub2né in grado di leggere le immagini del kernel da una partizione reiser4.
  • Vuoi connetterti a Internet tramite la connessione Bluetooth? Se non funziona con il tuo telefono Samsung Java Me, non puoi eseguire gli script e il software della riga di comando che in precedenza funzionavano manualmente a causa di networkd.
  • Anche se riconosco il problema più grande è se stai costruendo e mantenendo la tua distribuzione Linux: il modulo init systemd stesso ha così tante dipendenze che non puoi proporre di scegliere un altro sistema init attraverso diversi pacchetti di installazione.
  • Buona fortuna per la visualizzazione dei registri se non riesci a eseguire il chroot nel tuo sistema o se hai eseguito l'aggiornamento da libdb4.8 (mentre almeno, nel peggiore dei casi Microsoft ha i suoi file di registro in formato XML) .

L'unica soluzione:

Systemd è un complesso inconsistente per la risoluzione di problemi: come alsa invece di ossv4. Quindi, se hai qualcosa che usa systemd, cancella tutti i dati:

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

e installa qualcosa che non lo usa affatto mentre risolve i problemi di SysV Init come Gentoo con Openrc.
Per quanto riguarda la mia domanda, systemd crea cose come il registro di Windows®: se una parte di esso viene rovinata, allora è finita.


3
Riconosci che la progettazione di qualcosa può davvero impedire di ottenere una risposta in modo che la risposta passi a qualcosa che funziona . E che questa è una vera risposta.
user2284570

1
Ho avuto la stessa opinione, ora sono un po 'più equilibrato. Systemd ha il vantaggio enorme di poter davvero uccidere ciò che dovrebbe essere ucciso . È perché tiene traccia di tutti i processi secondari biforcati con la funzione cgroup del kernel. Nessuno degli strumenti più vecchi può farlo. Inoltre, ti ricordi anche la merda degli script in /etc/init/*.sh?I, ma oggi è solo un brutto ricordo per me. I file di servizio systemd sono chiare e lunghe circa 10 linee di configurazioni . Script non lunghi 200 righe . Questi enormi vantaggi hanno il systemd, sono d'accordo che tutte le altre funzionalità sono svantaggiose.
Peter dice di reintegrare Monica il

A proposito, ho votato la tua risposta perché, oltre ai suoi vantaggi, esattamente questo tipo di critica, esattamente in questo tono è ciò che lo sviluppo del sistema richiede di migliorare. Ad esempio, ho appena provato ad avviare un postgresql in un chroot e ho dovuto schivare il mio sistema di root per farlo. Molte, molte cose schifose sono ancora lì, giusto.
Peter dice di reintegrare Monica il

@peterh: sfortunatamente non tutti lo condividono intendo al punto di eliminare i post. Non si tratta di SysV init contro Systemd ma più di cose come Openrc o persino Upstart (che consente script di avvio brevi e avvio di servizio parallelo). Almeno ho imparato una cosa: Darwin è principalmente il ᴏꜱ di Apple ™ Windows è is il design di Microsoft e Linux è gestito principalmente da red hat. Sebbene SysV init sia più lento non ti limita a ciò che puoi fare in fase di esecuzione.
user2284570

Gli script di @peterh Services sono anche molto chiari quando si utilizza Openrc. Il problema con cgroup su Systemd è che questa non è un'opzione che impedisce a Systemd di eseguire cose come Darwin o NetBSD.
user2284570

3

No. I servizi vengono eseguiti da systemd (pid 1), non direttamente da systemctl (che invia solo una richiesta di avvio) e poiché systemd viene eseguito al di fuori del chroot, lo stesso vale per il servizio.

Anche se tecnicamente potrebbe essere possibile implementarlo (facendo in modo che systemctl passi in qualche modo la sua radice a systemd), è improbabile che accada poiché esiste già uno strumento per la creazione di container completi ( systemd-nspawn /somepath/to_root). Tuttavia, puoi sempre contattare la mailing list .


1
Bene, ma devo usare systemctl poiché il mio sistema host usa oepnrc. Voglio una soluzione completamente indipendente
user2284570,

3
Fangherò ulteriormente le acque dicendo: Psst! Menzione RootDirectory=anche dal momento che sei pericolosamente a corto di voti. (-:
JdeBP,

@JdeBP: Qual è la differenza (in termini di risultati) tra la variabile RootDirectorye il chrootcomando?
user2284570

@grawity: Quindi quale append se pid 1è init?
user2284570

1

Di fronte a questo problema, una volta provato a far apparire la rete in modalità di salvataggio usando la configurazione di rete da chroot. Finalmente questo funziona per me:

service --skip-redirect <service> restart

o:

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

Bello. Funziona solo con i servizi compatibili con Init legacy (non funzionerà per il networking nel rawhide Fedora) . Come ho detto nella mia risposta, la vera soluzione è rovinare tutto ciò che usa systemd.
user2284570

0

Se stai avviando un servizio inetd con l'attivazione del socket, prendi in considerazione l'avvio di stunnel invece con un file di configurazione che specifica sia un chroot che il tuo binario come destinazione di avvio in stile inetd.

Nota che potresti avere problemi con SELINUX. Su un sistema Oracle Linux 7.1, ho dovuto "chcon -v --type = stunnel_etc_t" su tutti i file che stunnel doveva leggere.

Sarà necessario utilizzare la crittografia TLS sul lato client del socket (ovvero un altro stunnel con "client = yes" nella configurazione). Fammi sapere se vuoi maggiori dettagli su questo.


no riguarda cose come d-bus. Lo faccio per diagnosticare problemi sul chroot target.
user2284570

-1

È possibile utilizzare il nohupcomando per avviare i servizi in chroot. Per iniziare il httpdservizio, ad esempio, lo faccio in questo modo.

nohup httpd /dev/null &

per fermarlo pkill httpd


Che dire di servizi come Dbus che possono essere avviati solo dallo script binario systemd installato?
user2284570

È possibile avviare tali servizi dalla sua directory con il comando start.
ellooku,

Che è un collegamento simbolico contro systemctl. Quindi non funziona.
user2284570,

Lo faccio sempre su Fedora in esecuzione sul mio Android. Forse non so quale sia il tuo problema.
ellooku,

La conseguenza è questo messaggio: Running in chroot, ignoring request.. Non penso che tu lo faccia sempre, anche se chroot. In effetti, lo script di avvio richiede systemd.
user2284570,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.