Salah satu topik yang paling banyak ditanyakan kepada orang-orang yang mengerjakan teknologi container upstream adalah menjalankan Podman dalam container. Sebagian besar secara historis terkait dengan Docker in Docker (DIND), tetapi sekarang, orang juga ingin menjalankan Podman in Podman (PINP) atau Podman in Docker (PIND).
Tetapi Podman dapat dijalankan dengan berbagai cara, rootful dan rootless. Kami berakhir dengan orang-orang yang ingin menjalankan berbagai kombinasi Podman root dan rootless:
- Podman Berakar dalam Podman Berakar
- Podman Tanpa Root di dalam Podman Root
- Podman Berakar dalam Podman Tanpa Root
- Podman Tanpa Root di dalam Podman Tanpa Root
Anda mendapatkan gambarannya.
Blog ini akan mencoba membahas setiap kombinasi, dimulai dengan diskusi tentang hak istimewa. Kita akan mulai dengan skenario PINP di sini di bagian satu. Di bagian kedua dari seri ini, kita akan membahas dasar yang sama tetapi melakukannya dalam konteks Kubernetes. Pastikan untuk membaca kedua artikel tersebut untuk gambaran yang lengkap.
Mesin kontainer memerlukan hak istimewa
Untuk menjalankan mesin container seperti Podman di dalam container, hal pertama yang perlu Anda pahami adalah Anda memerlukan hak istimewa yang cukup banyak.
- Kontainer memerlukan beberapa UID. Sebagian besar gambar kontainer membutuhkan lebih dari satu UID agar berfungsi. Misalnya, Anda mungkin memiliki gambar dengan sebagian besar file yang dimiliki oleh root, tetapi beberapa dimiliki oleh pengguna apache (UID=60).
- Mesin penampung memasang sistem file dan menggunakan klon panggilan sistem untuk membuat ruang nama pengguna.
Catatan:Anda mungkin memerlukan versi Podman yang lebih baru. Contoh di blog ini dijalankan dengan Podman 3.2.
Gambar pengujian kami
Untuk contoh di blog ini, kita akan menggunakan quay.io/podman/stable
image, yang dibuat dengan ide untuk menemukan cara terbaik untuk menjalankan Podman dalam sebuah wadah. Anda dapat memeriksa bagaimana kami membuat gambar ini dari Dockerfile dan containers.conf
gambar di repo github.com.
# stable/Dockerfile
#
# Build a Podman container image from the latest
# stable version of Podman on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=podman
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM registry.fedoraproject.org/fedora:latest
# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*
RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf
RUN chown podman:podman -R /home/podman
# chmod containers.conf and adjust storage.conf to enable Fuse storage.
RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock
ENV _CONTAINERS_USERNS_CONFIGURED=""
Mari kita periksa Dockerfile.
FROM registry.fedoraproject.org/fedora:latest
# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*
Pertama tarik fedora terbaru, lalu perbarui ke paket terbaru. Perhatikan itu menginstal ulang shadow-utils
, karena ada masalah yang diketahui di shadow-utils
instal pada gambar Fedora di mana filecaps
di newsubuid
dan newsubgid
tidak diatur. Menginstal ulang shadow-utils
memperbaiki masalah. Selanjutnya, instal Podman serta fuse-overlayfs
. Kami tidak menginstal container-selinux
karena tidak diperlukan di dalam wadah.
RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;
Selanjutnya saya membuat pengguna podman
dan atur /etc/subuid
dan /etc/subgid
file untuk menggunakan 5000 UID. Ini digunakan untuk mengatur User Namespace dalam wadah. 5000 adalah angka yang berubah-ubah dan berpotensi terlalu kecil. Kami memilih nomor ini karena lebih kecil dari 65k yang dialokasikan untuk pengguna tanpa root. Jika Anda hanya menjalankan container sebagai root, 65k akan menjadi angka yang lebih baik.
VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers
Karena kita dapat menjalankan container rootfull dan rootless dengan gambar ini, kita membuat dua volume. Rootfull Podman menggunakan /var/lib/containers
untuk penyimpanan kontainernya dan rootless menggunakan /home/podman/.local/share/containers
. Overlay overlay sering ditolak oleh kernel, jadi ini menciptakan volume non overlay untuk digunakan di dalam container.
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf
Saya telah mengonfigurasi dua containers.conf
file untuk memastikan container berjalan lebih mudah di setiap mode.
Gambar diatur untuk dijalankan dengan fuse-overlayf secara default. Dalam kasus tertentu, Anda dapat menjalankan sistem file overlay kernel untuk mode rootful, dan Anda akan segera dapat melakukannya dalam mode rootless. Namun, untuk saat ini, kami menggunakan fuse-overlayf sebagai penyimpanan kontainer kami di dalam kontainer. Orang lain telah menggunakan driver penyimpanan VFS, tetapi ini tidak seefisien itu.
Bendera --privileged
Cara termudah untuk menjalankan Podman di dalam wadah adalah dengan menggunakan --privileged
bendera.
Podman Root dalam Podman root dengan --privileged
# podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8-minimal" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull registry.access.redhat.com/ubi8:latest...
Getting image source signatures
Copying blob sha256:a591faa84ab05242a17131e396a336da172b0e1ec66d921c9f130b7c4c24586d
Copying blob sha256:76b9354adec626b01ffb0faae4a217cebd616661fd90c4b54ba4415f53392fb8
Copying config sha256:dc080723f596f2407300cca2c19a17accad89edcf39f7b8b33e6472dd41e30f1
Writing manifest to image destination
Storing signatures
hello
Untuk menghemat waktu, karena saya akan melakukan banyak eksperimen, saya membuat direktori di host saya ./mycontainers
, yang akan saya volume mount ke dalam wadah untuk digunakan dan tidak perlu menarik gambar setiap kali.
# podman run --privileged -v ./mycontainers:/var/lib/containers quay.io/podman/stable podman run ubi8 echo hello
hello
Podman Rootless di Podman root dengan --privileged
quay.io/podman/stable
gambar diatur dengan podman pengguna yang dapat Anda gunakan untuk menjalankan container tanpa root.
# podman run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello
Perhatikan dalam kasus ini, Podman yang berjalan di dalam container berjalan sebagai pengguna podman . Ini karena Podman dalam container menggunakan namespace pengguna untuk membuat container terbatas di dalam container yang diistimewakan.
Menjalankan Podman tanpa root di Docker dengan --privileged
Mirip dengan rootful Podman, Anda juga dapat menjalankan Podman rootless di dalam Docker dengan --privileged
pilihan.
# docker run --privileged quay.io/podman/stable podman run ubi8 echo hello
Podman Tanpa Root dengan Docker
# docker run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello
Bisakah kita melakukannya dengan lebih aman?
Perhatikan bahwa meskipun kita menjalankan container luar --privileged
di atas, wadah bagian dalam berjalan dalam mode terkunci. Podman tanpa akar yang berjalan di dalam wadah benar-benar terkunci dan akan sangat sulit untuk melarikan diri. Mengingat itu, saya bukan penggemar menggunakan --privileged
bendera. Saya yakin kita bisa melakukan yang lebih baik dari sudut pandang keamanan.
Berjalan tanpa --privileged flag
Mari kita lihat bagaimana kita dapat menghapus --privileged
tandai untuk keamanan yang lebih baik.
Podman Root dalam Podman root tanpa --privileged
# podman run --cap-add=sys_admin,mknod --device=/dev/fuse --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello
Kita dapat menghilangkan --privileged
tandai dari Podman rootful tetapi masih harus menonaktifkan beberapa fitur keamanan agar Podman rootful di dalam wadah berfungsi.
- Kemampuan:
--cap-add=sys_admin,mknod
Kita perlu menambahkan dua kemampuan Linux.- CAP_SYS_ADMIN diperlukan agar Podman berjalan sebagai root di dalam wadah untuk memasang sistem file yang diperlukan.
- CAP_MKNOD diperlukan agar Podman berjalan sebagai root di dalam wadah untuk membuat perangkat di
/dev
. (Perhatikan bahwa Docker mengizinkan ini secara default).
- Perangkat:
--device /dev/fuse
flag harus menggunakan fuse-overlayf di dalam container. Opsi ini memberitahu Podman pada host untuk menambahkan/dev/fuse
ke container sehingga Podman dalam container dapat menggunakannya. - Nonaktifkan SELinux:
--security-opt label=disable
option memberitahu Podman host untuk menonaktifkan pemisahan SElinux untuk container. SELinux tidak mengizinkan proses dalam container untuk memasang semua sistem file yang diperlukan untuk berjalan di dalam container.
Podman Root di Docker tanpa --privileged
# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=unconfined --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello
- Catatan Docker tidak mendukung
--cap-add
perintah, jadi saya harus menambahkan sys_admin dan mknod secara terpisah - Masih diperlukan
--device /dev/fuse
, karena default container adalah/dev/fuse
- Docker selalu membuat volume bawaan seperti yang dimiliki oleh root:root, jadi kita perlu membuat volume yang akan dipasang untuk Podman dalam wadah agar dapat digunakan untuk penyimpanan.
- Seperti biasa, saya perlu menonaktifkan pemisahan SELinux
- Juga perlu menonaktifkan
seccomp
, karena Docker memilikiseccomp
. yang sedikit lebih ketat kebijakan dari Podman. Anda bisa menggunakan kebijakan keamanan Podman dengan menggunakan--seccomp=/usr/share/containers/seccomp.json
# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=/usr/share/containers/seccomp.json --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello
Podman Rootless di Podman root tanpa --privileged
Jalankan non -wadah istimewa dengan Podman di dalamnya menggunakan pengguna non-root menggunakan ruang nama pengguna.
# podman run --user podman --security-opt label=disable --security-opt unmask=ALL --device /dev/fuse -ti quay.io/podman/stable podman run -ti docker.io/busybox echo hello
hello
- Perhatikan bahwa tidak seperti rooful dalam kasus rootful sebelumnya, kita tidak perlu menambahkan kemampuan keamanan berbahaya sys_admin dan mknod
- Dalam hal ini, saya menjalankan dengan
--user podman
, yang secara otomatis menyebabkan Podman di dalam wadah berjalan di dalam ruang nama pengguna - Masih menonaktifkan SELinux karena memblokir pemasangan
- Masih membutuhkan
--device /dev/fuse
untuk menggunakan fuse-overlayf di dalam container
Podman-remote di Podman rootful dengan soket Podman bocor dari host
# podman run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi
Dalam hal ini, kami membocorkan /run
direktori dari Host ke dalam wadah. Ini memungkinkan podman --remote
untuk berkomunikasi dengan soket Podman di host dan memulai container di OS host. Ini sering bagaimana orang mengeksekusi Docker Di Docker, terutama build Docker. Anda juga dapat menjalankan build Podman dengan cara ini dan memanfaatkan gambar yang sebelumnya ditarik ke sistem.
Perhatikan, bagaimanapun, ini sangat tidak aman. Proses di dalam container dapat sepenuhnya mengambil alih mesin host.
- Anda masih perlu menonaktifkan pemisahan SELinux karena SELinux akan memblokir proses kontainer agar tidak menggunakan soket yang bocor di
/run
. podman --remote
flag ditambahkan untuk memberi tahu Podman agar bekerja dalam mode jarak jauh. Perhatikan bahwa Anda juga dapat menginstalpodman-remote
dapat dieksekusi ke dalam wadah dan gunakan ini.
[ Memulai container? Lihat kursus gratis ini. Menyebarkan aplikasi kemas:Tinjauan teknis. ]
Podman-remote di Docker dengan soket Podman bocor dari host
# docker run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi
Contoh yang sama berfungsi untuk wadah Docker.
Contoh ini menunjukkan container yang terkunci sepenuhnya—selain SELinux yang dinonaktifkan—dengan soket Podman yang bocor ke dalam container. SELinux akan memblokir akses ini, sebagaimana mestinya.
# /bin/podman run --security-opt=label=disable -v /run/podman:/run/podman quay.io/podman/stable podman --remote run alpine echo hi
hi
Podman Rootless dengan Podman rootful dalam container
$ podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
..
hello
Podman Tanpa Root menjalankan Podman Tanpa Root
$ podman run --security-opt label=disable --user podman --device /dev/fuse quay.io/podman/stable podman run alpine echo hello
Pemikiran terakhir
Sekarang Anda memiliki beberapa konteks untuk Podman dalam opsi Podman, menggunakan mode rootful dan rootless. dalam berbagai kombinasi. Anda juga memiliki pemahaman yang lebih baik tentang hak istimewa yang diperlukan dan pertimbangan seputar --privileged
bendera.
Bagian kedua dalam seri ini membahas penggunaan Podman dan Kubernetes. Artikel ini mencakup wilayah yang serupa tetapi dalam konteks Kubernetes.
[ Ingin menguji kemampuan sysadmin Anda? Ikuti penilaian keterampilan hari ini. ]