Podman yang diberikan diinstal pada sistem linux dan unit systemd bernama baz.service:
# /etc/systemd/system/baz.service
[Service]
ExecStart=/usr/bin/podman run --rm --tty --name baz alpine sh -c 'while true; do date; sleep 1; done'
ExecStop=/usr/bin/podman stop baz
Dan layanan baz.ser dimulai:
# systemctl daemon-reload
# systemctl start baz.service
Kemudian ketika saya memeriksa status unit saya tidak melihat sh
atau sleep
proses di /system.slice/baz.service cgroup
# systemctl status baz
● baz.service
Loaded: loaded (/etc/systemd/system/baz.service; static; vendor preset: enabl
Active: active (running) since Sat 2019-08-10 05:50:18 UTC; 14s ago
Main PID: 16910 (podman)
Tasks: 9
Memory: 7.3M
CPU: 68ms
CGroup: /system.slice/baz.service
└─16910 /usr/bin/podman run --rm --tty --name baz alpine sh -c while
# ...
Saya mengharapkan untuk melihat sh
dan sleep
anak - anak dalam status baz.service saya karena saya telah mendengar orang-orang dari redhat mengatakan podman menggunakan model fork-exec tradisional.
Jika podman melakukan fork dan exec, maka bukankah proses saya sh
dan sleep
menjadi anak-anak podman dan berada dalam kelompok yang sama dengan proses podman asli?
Saya berharap dapat menggunakan systemd dan podman untuk dapat mengelola wadah saya tanpa anak-anak pergi ke orang tua yang berbeda dan melarikan diri dari unit ssystemd baz.service saya.
Melihat output dari ps
saya dapat melihat itu sh
dan sleep
sebenarnya adalah anak-anak dari proses yang berbeda yang disebut conmon
. Saya tidak yakin dari mana conmon berasal, atau bagaimana itu dimulai tetapi systemd tidak menangkapnya.
# ps -Heo user,pid,ppid,comm
# ...
root 17254 1 podman
root 17331 1 conmon
root 17345 17331 sh
root 17380 17345 sleep
Dari outputnya jelas bahwa unit baz.service saya tidak mengelola conmon -> sh -> sleep chain.
- Bagaimana podman berbeda dari model server klien buruh pelabuhan?
- Apa perbedaan antara podman podman dengan isi docker?
Mungkin mereka berdua runtimes kontainer dan dockerd
daemon adalah apa yang orang ingin singkirkan.
Jadi mungkin buruh pelabuhan itu seperti:
- daemon dockerd
- buruh pelabuhan cli
- berisi runtime kontainer
Dan podman seperti:
- podman cli
- runtime wadah conmon
Jadi mungkin podman menggunakan model fork exec tradisional tapi itu bukan podman cli yang forking dan exec, itu proses pemanggilan.
Saya bingung.
sumber
Jawaban:
Seluruh ide di belakang
podman
adalah untuk menjauh dari arsitektur terpusat dengan pengawas super kuat (misalnyadockerd
), di mana daemon terpusat adalah satu titik kegagalan. Bahkan ada tagar tentang ini - " #nobigfatdaemons ".Bagaimana cara menghindari manajemen kontainer terpusat? Anda menghapus daemon utama tunggal (lagi,
dockerd
) dan mulai wadah secara mandiri (pada akhir hari, wadah hanya proses, sehingga Anda tidak perlu daemon untuk memijahkannya).Namun, Anda masih membutuhkan cara untuk itu
stdout
danstderr
dari wadah;wait(2)
menggunakan PID 1 penampung;Untuk tujuan ini, setiap wadah podman masih diawasi oleh daemon kecil, yang disebut
conmon
(dari "monitor kontainer"). Perbedaannya dengan daemon Docker adalah bahwa daemon ini sekecil mungkin (periksa ukuran kode sumber ), dan daemon ini dihasilkan per-kontainer. Jikaconmon
untuk satu kontainer macet, sisa sistem tetap tidak terpengaruh.Selanjutnya, bagaimana wadah itu akan melahirkan?
Mempertimbangkan bahwa pengguna mungkin ingin menjalankan wadah di latar belakang, seperti dengan Docker,
podman run
proses bercabang dua kali dan hanya kemudian dijalankanconmon
:Proses tengah antara
podman run
danconmon
(yaitu induk langsung dariconmon
- dalam contoh di atas adalah PID 8484) akan keluar danconmon
akan diperbaiki olehinit
, sehingga menjadi daemon yang dikelola sendiri. Setelah ini,conmon
juga memotong runtime (egrunc
) dan, akhirnya, runtime mengeksekusi entrypoint penampung (eg/bin/sh
).Ketika wadah berjalan,
podman run
tidak lagi diperlukan dan dapat keluar, tetapi dalam kasus Anda tetap online, karena Anda tidak meminta untuk melepaskan dari wadah.Selanjutnya,
podman
gunakan cgroup untuk membatasi wadah. Ini berarti bahwa ia menciptakan cgroup baru untuk wadah baru dan memindahkan proses di sana . Dengan aturan cgroup, proses tersebut mungkin hanya anggota dari satu cgroup pada suatu waktu, dan menambahkan proses ke beberapa cgroup menghapusnya dari cgroup lain (di mana sebelumnya) dalam hierarki yang sama. Jadi, ketika wadah dimulai, tata letak akhir cgroup terlihat seperti berikut:podman run
tetap di cgroupbaz.service
, dibuat olehsystemd
,conmon
proses ditempatkan di cgroup sendiri, dan proses kemasukan ditempatkan di cgroup mereka sendiri:Catatan: PID 13075 di atas sebenarnya adalah sebuah
sleep 1
proses, yang muncul setelah kematian PID 13043.Semoga ini membantu.
sumber
stdout
/stderr
stream - lagi,podman
memiliki wadah dan menangkap aliran dari proses kemas.systemd
memiliki layanan dan menangkap aliran proses utama layanan (dalam kasus Anda,systemd
sebenarnya menangkapstdout
/stderr
daripodman run
proses). Ini berfungsi persis seperti seharusnya, karenaconmon
menangkap aliran wadah,podman run
menempelconmon
,systemd
menangkap aliranpodman run
, jadi, akhirnya, semua log dari wadah ditangkapsystemd
, dan Anda melihatnyasystemctl status baz.service
.