m.yoshida
2023年12月8日 15時32分
お世話になっております。
systemctlを使用すると
System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
と表示されプロセスを確認すると確かにPID1でないので動作しません
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 188 44 pts/0 Ss 06:23 0:00 /run/podman-ini root 2 0.0 0.4 2772 2224 pts/0 S 06:23 0:00 /bin/bash root 3 0.0 0.3 5092 1876 pts/0 R+ 06:24 0:00 ps aux
変更する方法ありますでしょうか?
コメント
koga
アットマークテクノの古賀です。
m.yoshidaさん:
>systemctlを使用すると
System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
>と表示されプロセスを確認すると確かにPID1でないので動作しません
systemctl が存在しているということで、Debian コンテナに systemd パッケージをインストールしていらっしゃる状態なのでしょうね。
>変更する方法ありますでしょうか?
at_ohsawa:
>具体的にはsystemctlで何をしたいですか?
おそらくですが、以下の投稿で質問していらした、sshd や postgresql などのサービス/デーモンを、コンテナ起動時に自動起動するために systemd を利用しようと思い、systemctl を使ってみた、ということだろうかと想像しています。
https://armadillo.atmark-techno.com/forum/armadillo/18059
m.yoshidaさん、この想像で違っていたら、ごめんなさい。
>systemctlコマンドはinitであるsystemdに対して制御を行うためのコマンドですが、
>そもそもコンテナの中にはinitは居ないので、実行したいサービスがあるなら、単に
>コマンドとしてコンテナのrunで実行します。
m.yoshida さんが作成されたコンテナには、たぶん、/lib/systemd/systemd は systemd パッケージのインストールにより存在しているものの、/sbin/init が存在していない状態だと思います。
その場合は、次のようにすれば、コンテナ起動時に systemd が init として実行され、systemctl で有効に設定したサービスを自動起動させることができます。ただし、「コンテナに入れて動かすものを必要最小限に保つべし」というセキュリティの観点からの推奨ポリシーで考えれば、コンテナ起動時に自動起動したいサービスを、個別に明示起動する設定をコンテナに加える方が良いと思います。
以下、systemd を init としてコンテナ起動時に実行させる方法です:
1.) コンテ内で、/sbin/init から /lib/systemd/systemd へのシンボリックリンクを作る
# ln -s /lib/systemd/systemd /sbin/init
2.) (1) で変更したコンテナ内容を podman commit で保存する。
3.) (3) で保存したコンテナイメージからコンテナを生成する際に、podman run の引数を次のようにする:
3-1.) --systemd=true の指定を追加
3-2.) 実行コマンドとして /sbin/init を指定
3-3.) -it を指定しない(-d での起動にする)
これにより、(3) で生成したコンテナ内では、PID: 1 のプロセスとして init(: 実体は systemd)が起動しますので、systemctl を実行できるようになります。
podman exec -it <コンテナ名> /bin/bash でコンテナ内のシェルを起動して、systemctl を使い、コンテナ起動時に自動起動されるサービスを有効化すれば、その後、コンテナを podman stop & podman start で起動し直すと、有効化したサービスが起動するはずです。
なお、systemctl でサービスの有効化を設定した後、再度 podman commit でコンテナ変更内容をイメージに保存してください。そうしておけば、イメージからコンテナを生成し直しても、サービスの有効化設定が保持されます。
コンテナ内での systemd の実行については、以下の Blog が参考になると思います:
How to run systemd in a container
https://developers.redhat.com/blog/2019/04/24/how-to-run-systemd-in-a-c…
Podman - systemd in containers
https://blog.while-true-do.io/podman-systemd-in-containers/
また、コンテナの動作の仕組みや、コンテナ運用上でのセキュリティの考え方などについて、以下の本は参考書籍として良いと思います:
Container Security: Fundamental Technology Concepts That Protect Containerized Applications
https://www.amazon.co.jp/gp/product/1492056707
いかがでしょうか?もし参考になりましたら幸いです。
m.yoshida
アットマークテクノ 古賀様
ご回答ありがとうございます。
(製品をA6EではなくA6で登録してしまったため、気が付くのおくれました。)
回答遅れてすいません。
> おそらくですが、以下の投稿で質問していらした、sshd や postgresql などのサービス/デーモンを、コンテナ起動時に自動起動するために systemd を利用しようと思い、systemctl を使ってみた、ということだろうかと想像しています。
> https://armadillo.atmark-techno.com/forum/armadillo/18059
> m.yoshidaさん、この想像で違っていたら、ごめんなさい。
ご認識の通りです。systemdでサービスの自動起動できないか検討していました。
上記のURLで紹介していただきましたが、他にも動作させたいサービスもあるので、systemdを使用したいとおてます。
> 1.) コンテ内で、/sbin/init から /lib/systemd/systemd へのシンボリックリンクを作る
>
> # ln -s /lib/systemd/systemd /sbin/init >
>
> 2.) (1) で変更したコンテナ内容を podman commit で保存する。
>
> 3.) (3) で保存したコンテナイメージからコンテナを生成する際に、podman run の引数を次のようにする:
> 3-1.) --systemd=true の指定を追加
> 3-2.) 実行コマンドとして /sbin/init を指定
> 3-3.) -it を指定しない(-d での起動にする)
>
> これにより、(3) で生成したコンテナ内では、PID: 1 のプロセスとして init(: 実体は systemd)が起動しますので、systemctl を実行できるようになります。
> podman exec -it <コンテナ名> /bin/bash でコンテナ内のシェルを起動して、systemctl を使い、コンテナ起動時に自動起動されるサービスを有効化すれば、その後、コンテナを podman stop & podman start で起動し直すと、有効化したサービスが起動するはずです。
→(3)コンテナコミットしてイメージ化後コンテナ作成時下記のエラーがでました。
コンテナは作成してるみたいです。修正点ありますでしょうか?
podman run --name=コンテナ名 --systemd=true -d イメージ名 /sbin/init Error: crun: open executable: Operation not permitted: OCI permission denied
> なお、systemctl でサービスの有効化を設定した後、再度 podman commit でコンテナ変更内容をイメージに保存してください。そうしておけば、イメージからコンテナを生成し直しても、サービスの有効化設定が保持されます。
> コンテナ内での systemd の実行については、以下の Blog が参考になると思います:
>
> How to run systemd in a container
> https://developers.redhat.com/blog/2019/04/24/how-to-run-systemd-in-a-c…
>
> Podman - systemd in containers
> https://blog.while-true-do.io/podman-systemd-in-containers/
>
> また、コンテナの動作の仕組みや、コンテナ運用上でのセキュリティの考え方などについて、以下の本は参考書籍として良いと思います:
>
> Container Security: Fundamental Technology Concepts That Protect Containerized Applications
> https://www.amazon.co.jp/gp/product/1492056707
>
> いかがでしょうか?もし参考になりましたら幸いです。
上記も確認してみます。情報共有していただいてありがとうございます。
at_shinya.koga
アットマークテクノの古賀です。
m.yoshidaさん:
>ご回答ありがとうございます。
>(製品をA6EではなくA6で登録してしまったため、気が付くのおくれました。)
>回答遅れてすいません。
あ、いえいえ。
>>おそらくですが、以下の投稿で質問していらした、sshd や postgresql などの
>>サービス/デーモンを、コンテナ起動時に自動起動するために systemd を利用
>>しようと思い、systemctl を使ってみた、ということだろうかと想像しています。
>> https://armadillo.atmark-techno.com/forum/armadillo/18059
>>m.yoshidaさん、この想像で違っていたら、ごめんなさい。
>
>
>ご認識の通りです。systemdでサービスの自動起動できないか検討していました。
了解しました。
>上記のURLで紹介していただきましたが、他にも動作させたいサービスもあるので、systemdを使用したいとおてます。
これについても、了解です。
>>1.) コンテ内で、/sbin/init から /lib/systemd/systemd へのシンボリックリンクを作る
# ln -s /lib/systemd/systemd /sbin/init
>>
>>2.) (1) で変更したコンテナ内容を podman commit で保存する。
>>
>>3.) (3) で保存したコンテナイメージからコンテナを生成する際に、podman run の
>>引数を次のようにする:
>> 3-1.) --systemd=true の指定を追加
>> 3-2.) 実行コマンドとして /sbin/init を指定
>> 3-3.) -it を指定しない(-d での起動にする)
>>
>>これにより、(3) で生成したコンテナ内では、PID: 1 のプロセスとして
>>init(: 実体は systemd)が起動しますので、systemctl を実行できるようになります。
…
>→(3)コンテナコミットしてイメージ化後コンテナ作成時下記のエラーがでました。
>コンテナは作成してるみたいです。修正点ありますでしょうか?
>
podman run --name=コンテナ名 --systemd=true -d イメージ名 /sbin/init Error: crun: open executable: Operation not permitted: OCI permission denied
こちらで試していた環境では問題ありませんが、もしかすると、systemd パッケージをインストールした際。パーミッションを追加する必要があったかも知れません。
そちらの状況を再現できるか試そうと思い、コンテナ内の /sbin/init のシンボリックリンク先である /lib/systemd/systemd の実行パーミッションを 'chmod -x' で削ってコンテナイメージを保存して、保存したコンテナイメージから podman run でコンテナを生成・起動しようとしたところ、同じエラーになりました。
状況確認のため、以下のことを行ってみてください:
(1) 上記エラーが出た後、作成されたコンテナは、"Created" 状態になっていると思います(podman ps -a で見てみてください)。そのコンテナは不要なので、podman rm で削除してください。
(2) 以下のコマンドを実行して、/bin/bash を対話実行するコンテナを新たに生成してください:
# podman run --name=コンテナ名 --systemd=true -it イメージ名 /bin/bash
(3) コンテナの /bin/bash が起動したら、次のコマンドを実行し、/sbin/init と、シンボリックリンク先を見てみてください:
ls -l /sbin/init ls -l /lib/systemd/systemd
/lib/systemd/sytemd の実行パーミッションが欠けている場合は、chmod +x で追加した後、変更したコンテナ内容をイメージに保存し直して、
再度以下のコマンドを実行してみてくださいませ:
podman run --name=コンテナ名 --systemd=true -d イメージ名 /sbin/init
m.yoshida
解決遅れて申し訳ありません。
> (1) 上記エラーが出た後、作成されたコンテナは、"Created" 状態になっていると思います(podman ps -a で見てみてください)。そのコンテナは不要なので、podman rm で削除してください。
>
> (2) 以下のコマンドを実行して、/bin/bash を対話実行するコンテナを新たに生成してください:
>
> # podman run --name=コンテナ名 --systemd=true -it イメージ名 /bin/bash >
>
> (3) コンテナの /bin/bash が起動したら、次のコマンドを実行し、/sbin/init と、シンボリックリンク先を見てみてください:
>
> ls -l /sbin/init > > ls -l /lib/systemd/systemd >
>
上記対応して
$ls -l /sbin/init lrwxrwxrwx 1 root root /sbin/init -> /lib/systemd/system $ ls -l /lib/systemd/system total 884
上記コマンドの結果total 884と表示して実行権限をどれに付与していいか不明でしたので、改めて新規でイメージ作成して
(3)で作成することができました。
自動起動させる場合は、 /etc/atmark/containers/のconfigファイルの設定はどのようにすればよろしでしょうか?
set_image イメージ名 set_commnd /sbin/init
上記でよろしいでしょうか?
よろしくお願いいたします。
at_shinya.koga
アットマークテクノの古賀です。
m.yoshidaさん:
>解決遅れて申し訳ありません。
>>(1) 上記エラーが出た後、作成されたコンテナは、"Created" 状態になっていると思います(
>>podman ps -a で見てみてください)。そのコンテナは不要なので、podman rm で削除してください。
>>
>>(2) 以下のコマンドを実行して、/bin/bash を対話実行するコンテナを新たに生成してください:
# podman run --name=コンテナ名 --systemd=true -it イメージ名 /bin/bash
>>
>>(3) コンテナの /bin/bash が起動したら、次のコマンドを実行し、/sbin/init と、シンボリックリンク先を見てみてください:
ls -l /sbin/init ls -l /lib/systemd/systemd
>
>上記対応して
$ls -l /sbin/init lrwxrwxrwx 1 root root /sbin/init ->/lib/systemd/system $ ls -l /lib/systemd/system total 884
>上記コマンドの結果total 884と表示して実行権限をどれに付与していいか不明でしたので、
ということですが、
$ls -l /sbin/init lrwxrwxrwx 1 root root /sbin/init ->/lib/systemd/system
となっていて、/sbin/init のシンボリックリンク先が、/lib/systemd/systemd ではなく、/lib/systemd/system ディレクトリになっていたようですね。
>改めて新規でイメージ作成して
>(3)で作成することができました。
イメージを作成し直してやり直された際には、パスが正しかったのだろうと思います。
>自動起動させる場合は、 /etc/atmark/containers/のconfigファイルの設定はどのようにすればよろしでしょうか?
>
set_image イメージ名 set_commnd /sbin/init
>
>上記でよろしいでしょうか?
はい。これでよいです。
シンボリックリンクの /sbin/init を作成せず、set_command で /lib/systemd/systemd を直接指定しても大丈夫だと思います。
m.yoshida
at_ohsawa
2023年12月8日 19時27分
具体的にはsystemctlで何をしたいですか?
systemctlコマンドはinitであるsystemdに対して制御を行うためのコマンドですが、
そもそもコンテナの中にはinitは居ないので、実行したいサービスがあるなら、単に
コマンドとしてコンテナのrunで実行します。
もしくはコンテナの外のホストOS(ABOS)のinitを制御したいのであれば
(これはコンテナがアップデートサービスを破壊できる程度に権限を持つため
システムを停止させることが可能になるため推奨しません。)
ABOS側のinitはsystemdではなくopenrcなのでsystemcrlではなく
rc-status等のコマンドを使うことになります。
後者はできれば実施してほしくないので、用途をおしえてください。