巢狀容器 —— 在 Podman 容器內構建並執行 Buildah
去年聖誕節,筆者送給妻子一套俄羅斯套娃。它們由一個木偶組成,每個木偶開啟後是另外一個更小的木偶,直到最小那個出現。這個概念讓我想到了巢狀容器。
我想我或許可以嘗試用 Podman 來構建自己的巢狀容器,我可以在容器中基於 Buildah 做開發,也可以繼續建立 Buildah 容器和映像。一旦建立了 Podman 容器,就可以將它移到任意支援 Podman 的 Linux 系統上。然後使用 Buildah 進行開發。本文中我將詳細介紹整個過程。
環境準備
本文是在一個全新安裝的 Fedora 29 虛擬機器上進行的,系統上安裝了最新版本的 Podman 和 container-selinux ,安裝命令為:dnf -y install podman container-selinux --enablerepo updates-testing
。相應版本是 Podman v1.1.2 和 container-selinux 2.85-1.
不管是容器,還是容器中的容器都要用到 fuse-overlayfs,當嘗試將其相應目錄安裝在一起時會有很多麻煩。因此,第一步應該為容器建立一個目錄,這裡我們將其命名為 /var/lib/mycontainer
# mkdir /var/lib/mycontainer
建立 Podman 容器
接下來我建立瞭如下的 Dockerfile ,主要操作包括拉取 Fedora、設定 GOPATH、安裝 Buildah 依賴,使用 git 克隆 buildah 專案到 /root/buildah
目,最後更新 /etc/container/storage.conf
檔案,主要是去掉 mount_program 的註釋:
# FILE=~/Dockerfile.cinc # /bin/cat <<EOM >$FILE FROM fedora:latest ENV GOPATH=/root/buildah RUN dnf -y install \ make \ golang \ bats \ btrfs-progs-devel \ device-mapper-devel \ glib2-devel \ gpgme-devel \ libassuan-devel \ libseccomp-devel \ ostree-devel \ git \ bzip2 \ go-md2man \ runc \ fuse-overlayfs \ fuse3 \ containers-common; \ mkdir /root/buildah; \ git clone https://github.com/containers/buildah /root/buildah/src/github.com/containers/buildah RUN sed -i -e 's|#mount_program = "/usr/bin/fuse-overlayfs"|mount_program = "/usr/bin/fuse-overlayfs"|' /etc/containers/storage.conf EOM
接下來我們使用該 Dockerfile 建立一個映象( 請注意行末不容易發現的句號),該命令執行完需要 5 到 10 分鐘之久,而且即將結束時看起來像假死一樣,請耐心等待,你可以趁著這個時間去喝杯茶。
# podman build -t buildahimage -f ~/Dockerfile.cinc .
接下來是一個很重的過程,我們建立了一個 Podman 容器用來做 Buildah 開發。下面命令建立一個名為 buildahctr
的容器,並將宿主 mycontainer
安裝到容器的 containers
目錄,該容器會與宿主主機網路隔離,關閉標籤和 seccomp 限制,最後執行一些指令碼讓容器啟動並執行。
# podman run --detach --name=buildahctr --net=host --security-opt label=disable --security-opt seccomp=unconfined --device /dev/fuse:rw -v /var/lib/mycontainer:/var/lib/containers:Z buildahimage sh -c 'while true ;do wait; done'
Buildah 開發
棒極了,現在我們已經有一個運行了 Fedora 的容器,接下來我們可以在容器內開始編譯和安裝 Buildah 。命令如下:
# podman exec -it buildahctr /bin/sh
現在我們已經在容器內了,接下來是標準的 make、git 和執行 buildah。(請注意接下來的 5 個命令我們是在提示符 sh-4.4#
下執行的,為了簡化複製貼上我已經刪了很多提示資訊)
sh-4.4# cd /root/buildah export GOPATH=`pwd` cd /root/buildah/src/github.com/containers/buildah make make install sh-4.4# buildah from alpine alpine-working-container sh-4.4# buildah images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/alpine latest 5cb3aa00f899 9 days ago 5.79 MB
到此為止我們已經在 Podman 容器中編譯、安裝和執行 Buildah 了。
接下來我們將快速的調整 Buildah 原始碼並看看這些變化是否生效。請用 vi 或者你喜歡的編輯器修改 cmd/buildah/images.go
. 搜尋 outputHeader()
函式 (大約 219 行) ,你將找到這麼一行程式碼 format := "table {{.Name}}\t{{.Tag}}\t"
. 刪除單詞 “table” ,改成 format := "{{.Name}}\t{{.Tag}}\t”
. 儲存檔案並退出,然後再次執行 make
和 make install
。
sh-4.4# vi cmd/buildah/images.go sh-4.4# make sh-4.4# make install
現在再次執行 buildah images
, 你將看到所有的輸出行為跟開啟 --quiet
引數的效果一樣,而且不顯示錶頭:
sh-4.4# buildah images docker.io/library/alpine latest 5cb3aa00f899 9 days ago 5.79 MB
在 Podman 容器中執行 buildah 容器
接下來是最有趣的事情。我們將來看看是否可以在 Podman 容器中執行 Buildah 容器。接下來我們需要做一些簡單工作來列出 / 目錄內容。
sh-4.4# buildah from --name myalpine alpine myalpine sh-4.4# buildah run --isolation=chroot myalpine ls / bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
便攜的 Buildah 開發環境
如果你已順利完成上述步驟,你就可以在 Podman 容器中做 Buildah 開發了。這個容器同時還可以構建並執行其他容器。這裡我使用的是 Buildah,但其實也可以使用 Podman 來構建內部容器。無論選擇何種內部工具,現在我們都擁有了一個包含其他容器的容器,就好像前面我們提到的套娃。而且我也可以將這個容器提交到 Quay.io 和其他容器註冊網站,並從這些網站拉取容器映象執行到另外的 Fedora 機器或者其他 Linux 平臺上。這樣我們也就獲得了一個便攜的 Buildah 開發環境。
希望這篇文章可以讓你學習到如何使用 Podman 和 Buildah 建立一個更靈活的開發環境。
P.S. 在此過程中不需要執行任何守護程序,沒有對系統做任何破壞。
本文翻譯自:https://developers.redhat.com/blog/2019/04/04/build-and-run-buildah-inside-a-