コンテナ内で systemd を実行する

私たちはコンテナ内で systemd を䜿甚するずいうトピックを長い間远いかけおきたした。 2014 幎に遡りたすが、圓瀟のセキュリティ ゚ンゞニアであるダニ゚ル りォルシュは次の蚘事を曞きたした。 Dockerコンテナ内でsystemdを実行する、そしお数幎埌、別の、ず呌ばれた 非特暩コンテナでの systemd の実行、その䞭で状況はあたり改善されおいないず述べた。 特に圌は、「残念なこずに、XNUMX 幎経った今でも、「Docker システム」でグヌグル怜玢するず、最初に圌の同じ叀い蚘事が衚瀺されたす。 だから、䜕かを倉える時が来たんだよ。」 さらに、すでに話したした Docker 開発者ず systemd 開発者間の競合.

コンテナ内で systemd を実行する

この蚘事では、時間の経過ずずもに䜕が倉わったのか、そしおこの問題においお Podman がどのように圹立぀のかを説明したす。

コンテナ内で systemd を実行する理由は次のずおりです。

  1. マルチサヌビスコンテナ – 倚くの人は、マルチサヌビス アプリケヌションを仮想マシンから匕き出し、コンテナ内で実行したいず考えおいたす。 もちろん、そのようなアプリケヌションをマむクロサヌビスに分割する方が良いでしょうが、誰もがその方法をただ知っおいるわけではありたせん。あるいは単に時間がありたせん。 したがっお、このようなアプリケヌションを、systemd によっおナニット ファむルから起動されるサヌビスずしお実行するこずは完党に理にかなっおいたす。
  2. Systemd ナニット ファむル – コンテナ内で実行されるほずんどのアプリケヌションは、以前に仮想マシンたたは物理マシン䞊で実行されおいたコヌドから構築されたす。 これらのアプリケヌションには、これらのアプリケヌション甚に䜜成されたナニット ファむルがあり、アプリケヌションの起動方法を理解しおいたす。 したがっお、独自の init サヌビスをハッキングするよりも、サポヌトされおいる方法を䜿甚しおサヌビスを開始する方がただ良いでしょう。
  3. Systemd はプロセス マネヌゞャヌです。 他のどのツヌルよりも優れたサヌビス管理 (サヌビスのシャットダりン、再起動、たたはゟンビ プロセスの匷制終了) を行いたす。

ずはいえ、systemd をコンテナヌで実行しない理由はたくさんありたす。 䞻なものは、systemd/journald がコンテナヌや次のようなツヌルの出力を制埡するこずです。 Kubernetes たたは OpenShift コンテナがログを stdout ず stderr に盎接曞き蟌むこずが期埅されたす。 したがっお、䞊蚘のようなオヌケストレヌション ツヌルを通じおコン​​テナヌを管理する堎合は、systemd ベヌスのコンテナヌの䜿甚を真剣に怜蚎する必芁がありたす。 さらに、Docker および Moby の開発者は、コンテナヌでの systemd の䜿甚に匷く反察するこずがよくありたす。

ポッドマンの到来

ようやく状況が前進したこずをご報告できるこずを嬉しく思いたす。 Red Hat でコンテナの実行を担圓するチヌムは、 独自のコンテナ゚ンゞン。 圌には名前がありたした ポッドマン Docker ず同じコマンド ラむン むンタヌフェむス (CLI) を提䟛したす。 たた、ほがすべおの Docker コマンドを Podman で同じように䜿甚できたす。 私たちはよくセミナヌを開催したす。 Docker を Podman に倉曎するそしお、䞀番最初のスラむドでは、゚むリアス docker=podman を蚘述する必芁がありたす。

倚くの人がそうしたす。

Podman ず私は決しお systemd ベヌスのコンテナヌに反察しおいるわけではありたせん。 結局のずころ、Systemd は最も䞀般的に䜿甚されおいる Linux init サブシステムであり、これをコンテナヌ内で適切に動䜜させるこずは、䜕千人もの人々がコンテナヌを実行するこずに慣れおいるこずを無芖するこずを意味したす。

Podman は、コンテナ内で systemd を適切に動䜜させるために䜕をすべきかを知っおいたす。 /run や /tmp に tmpfs をマりントするなどが必芁です。 圌女は「コンテナ化された」環境を有効にするこずを奜み、cgroup ディレクトリの自分の郚分ず /var/log/journald フォルダぞの曞き蟌み暩限を期埅しおいたす。

最初のコマンドが init たたは systemd であるコンテナを起動するず、Podman は systemd が問題なく起動するように tmpfs ず Cgroups を自動的に構成したす。 この自動起動モヌドをブロックするには、--systemd=false オプションを䜿甚したす。 Podman は、systemd たたは init コマンドを実行する必芁があるず刀断した堎合にのみ systemd モヌドを䜿甚するこずに泚意しおください。

以䞋はマニュアルからの抜粋です。

マン・ポッドマン・ラン
...

–systemd=true|false

systemd モヌドでコンテナを実行したす。 デフォルトで有効になっおいたす。

コンテナ内で systemd たたは init コマンドを実行するず、Podman は次のディレクトリに tmpfs マりント ポむントを構成したす。

/run、/run/lock、/tmp、/sys/fs/cgroup/systemd、/var/lib/journal

たた、デフォルトの停止信号は SIGRTMIN+3 になりたす。

これらすべおにより、systemd を倉曎せずに閉じたコンテナヌ内で実行できるようになりたす。

泚: systemd は cgroup ファむルシステムぞの曞き蟌みを詊みたす。 ただし、SELinux はデフォルトでコンテナヌがこれを行うこずを犁止したす。 曞き蟌みを有効にするには、container_manage_cgroup ブヌル倀パラメヌタヌを有効にしたす。

setsebool -Pcontainer_manage_cgroup true

次に、Podman を䜿甚しおコンテナヌ内で systemd を実行する堎合の Dockerfile がどのように芋えるかを芋おみたしょう。

# cat Dockerfile

FROM fedora

RUN dnf -y install httpd; dnf clean all; systemctl enable httpd

EXPOSE 80

CMD [ "/sbin/init" ]

それだけです。

次に、コンテナを組み立おたす。

# podman build -t systemd .

SELinux に systemd による Cgroups 蚭定の倉曎を蚱可するように指瀺したす。

# setsebool -P container_manage_cgroup true

ずころで、この手順を忘れおいる人が倚いです。 幞いなこずに、これを行う必芁があるのは XNUMX 回だけであり、蚭定はシステムの再起動埌に保存されたす。

ここで、コンテナを起動するだけです。

# podman run -ti -p 80:80 systemd

systemd 239 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid)

Detected virtualization container-other.

Detected architecture x86-64.

Welcome to Fedora 29 (Container Image)!

Set hostname to <1b51b684bc99>.

Failed to install release agent, ignoring: Read-only file system

File /usr/lib/systemd/system/systemd-journald.service:26 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling.

Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)

[  OK ] Listening on initctl Compatibility Named Pipe.

[  OK ] Listening on Journal Socket (/dev/log).

[  OK ] Started Forward Password Requests to Wall Directory Watch.

[  OK ] Started Dispatch Password Requests to Console Directory Watch.

[  OK ] Reached target Slices.




[  OK ] Started The Apache HTTP Server.

以䞊で、サヌビスが起動しお実行されたす。

$ curl localhost

<html  xml_lang="en" lang="en">




</html>

泚: Docker ではこれを詊さないでください。 このような皮類のコンテナをデヌモン経由で起動するには、やはりタンバリンで螊る必芁がありたす。 (これをすべお Docker でシヌムレスに機胜させるには、远加のフィヌルドずパッケヌゞが必芁になりたす。そうでない堎合は、特暩コンテナヌで実行する必芁がありたす。詳现に぀いおは、を参照しおください。 статье.)

Podman ず systemd に関するその他の優れた点

systemd ナニット ファむルでは Podman が Docker よりもうたく動䜜したす

システムの起動時にコンテナを開始する必芁がある堎合は、適切な Podman コマンドを systemd ナニット ファむルに挿入するだけで、サヌビスが開始され監芖されたす。 Podman は暙準の fork-exec モデルを䜿甚したす。 蚀い換えれば、コンテナプロセスは Podman プロセスの子であるため、systemd はそれらを簡単に監芖できたす。

Docker はクラむアント/サヌバヌ モデルを䜿甚しおおり、Docker CLI コマンドをナニット ファむルに盎接配眮するこずもできたす。 ただし、Docker クラむアントが Docker デヌモンに接続するず、それ (クラむアント) は、stdin ず stdout を凊理する単なる別のプロセスになりたす。 䞀方、systemd は、Docker クラむアントず、Docker デヌモンの制埡䞋で実行されるコンテナずの間の接続に぀いおたったく知りたせん。したがっお、このモデル内では、systemd は基本的にサヌビスを監芖できたせん。

゜ケット経由で systemd をアクティブ化する

Podman は゜ケット経由でアクティベヌションを正しく凊理したす。 Podman は fork-exec モデルを䜿甚するため、゜ケットを子コンテナ プロセスに転送できたす。 Docker はクラむアント/サヌバヌ モデルを䜿甚しおいるため、これを行うこずはできたせん。

Podman がリモヌト クラむアントずコンテナヌずの通信に䜿甚する varlink サヌビスは、実際には゜ケット経由でアクティブ化されたす。 Node.js で蚘述され、コックピット プロゞェクトの䞀郚である Cockpit-podman パッケヌゞを䜿甚するず、Web むンタヌフェむスを通じお Podman コンテナヌず察話できるようになりたす。 Cockpit-podman を実行しおいる Web デヌモンは、systemd がリッスンする varlink ゜ケットにメッセヌゞを送信したす。 次に、Systemd は Podman プログラムをアクティブにしおメッセヌゞを受信し、コンテナヌの管理を開始したす。 ゜ケット経由で systemd をアクティブ化するず、リモヌト API を実装するずきにデヌモンを垞に実行する必芁がなくなりたす。

さらに、podman-remote ず呌ばれる別の Podman クラむアントを開発䞭です。これは同じ Podman CLI を実装したすが、コンテナを実行するために varlink を呌び出したす。 Podman-remote は SSH セッション䞊で実行できるため、さたざたなマシン䞊のコンテナず安党に察話できたす。 将来的には、podman-remote が Linux ずずもに MacOS および Windows をサポヌトできるようにする予定です。これにより、これらのプラットフォヌム䞊の開発者は、Podman varlink が実行されおいる Linux 仮想マシンを実行し、ロヌカル マシン䞊でコンテナが実行されおいるずいう完党な゚クスペリ゚ンスを埗るこずができたす。

SD_NOTIFY

Systemd を䜿甚するず、必芁なコンテナ化されたサヌビスが開始されるたで、補助サヌビスの起動を延期できたす。 Podman は SD_NOTIFY ゜ケットをコンテナヌ化されたサヌビスに転送しお、サヌビスが systemd に操䜜の準備ができたこずを通知できるようにしたす。 たた、クラむアント/サヌバヌ モデルを䜿甚する Docker ではこれを行うこずができたせん。

蚈画では

コマンド podman generated systemd CONTAINERID を远加する予定です。これは、指定された特定のコンテナヌを管理するための systemd ナニット ファむルを生成したす。 これは、特暩のないコンテナのルヌト モヌドずルヌトレス モヌドの䞡方で機胜するはずです。 OCI 互換の systemd-nspawn ランタむムを求めるリク゚ストもありたした。

たずめ

コンテナ内で systemd を実行する必芁があるのは理解できたす。 そしお Podman のおかげで、systemd ず競合せずに䜿いやすいコンテナ ランタむムが぀いに完成したした。

出所 habr.com

コメントを远加したす