1. 程式人生 > >巢狀容器 —— 在 Podman 容器內構建並執行 Buildah

巢狀容器 —— 在 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-