將容器運行時解耦為單獨的工具元件有什麼好處? 特別是,這些工具可以開始組合起來,以便它們可以相互保護。
許多人被在其中建造容器化 OCI 鏡像的想法所吸引
這就是為什麼人們不斷嘗試在容器中運行 Buildah。 簡而言之,我們創建了
調整
這些映像是從 Dockerfiles 建置的,可以在 Buildah 儲存庫的資料夾中找到
在這裡我們將看看
# stable/Dockerfile
#
# Build a Buildah container image from the latest
# stable version of Buildah on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=buildah
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM fedora:latest
# Don't include container-selinux and remove
# directories used by dnf that are just taking
# up space.
RUN yum -y install buildah fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.*
# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf
我們使用容器內的程序,而不是在主機 Linux 核心層級實現的 OverlayFS
podman run --device /dev/fuse quay.io/buildahctr ...
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock
接下來我們建立一個目錄用於額外儲存。
# Set up environment variables to note that this is
# not starting with user namespace and default to
# isolate the filesystem with chroot.
ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot
最後,透過使用 BUILDAH_ISOLATION 環境變量,我們告訴 Buildah 容器預設以 chroot 隔離運行。 這裡不需要額外的隔熱層,因為我們已經在容器中工作了。 為了讓 Buildah 建立自己的命名空間分隔的容器,需要 SYS_ADMIN 權限,這需要放寬容器的 SELinux 和 SECCOMP 規則,這與我們從安全容器建立的偏好相反。
在容器內運行 Buildah
上面討論的 Buildah 容器鏡像圖可讓您靈活地改變啟動此類容器的方法。
速度與安全
電腦安全始終是製程速度和周圍保護程度之間的折衷。 在組裝容器時,這種說法也是正確的,所以下面我們將考慮這個折衷的選擇。
上面討論的容器映像將其儲存在 /var/lib/containers 中。 因此,我們需要將內容掛載到這個資料夾中,而如何掛載將極大地影響建構容器鏡像的速度。
讓我們考慮三個選項。
選項1。 如果需要最大程度的安全性,那麼對於每個容器,您可以為容器/映像建立自己的資料夾,並透過磁碟區掛載將其連接到容器。 此外,將上下文目錄放置在容器本身的 /build 資料夾中:
# mkdir /var/lib/containers1
# podman run -v ./build:/build:z -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable
buildah -t image1 bud /build
# podman run -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable buildah push image1 registry.company.com/myuser
# rm -rf /var/lib/containers1
安全。 在這樣的容器中運行的Buildah 具有最大的安全性:它不會被授予使用功能的任何root 權限,並且所有SECOMP 和SELinux 限制都適用於它。這樣的容器甚至可以透過新增像—uidmap 0 這樣的選項來使用使用者命名空間隔離來運行: 100000:10000。
性能。 但這裡的效能是最低的,因為每次來自容器註冊表的任何映像都會複製到主機,並且快取根本不起作用。 完成工作後,Buildah 容器必須將映像傳送到註冊表並銷毀主機上的內容。 下次建立容器映像時,必須再次從註冊表下載它,因為到那時主機上將不再有任何內容。
選項2。 如果需要Docker等級的效能,可以將主機容器/儲存直接掛載到容器中。
# podman run -v ./build:/build:z -v /var/lib/containers:/var/lib/containers --security-opt label:disabled quay.io/buildah/stable buildah -t image2 bud /build
# podman run -v /var/lib/containers:/var/lib/containers --security-opt label:disabled quay.io/buildah/stable buildah push image2 registry.company.com/myuser
安全。 這是建構容器的最不安全的方法,因為它允許容器修改主機存儲,並可能向 Podman 或 CRI-O 提供惡意鏡像。 此外,您需要停用 SELinux 分離,以便 Buildah 容器中的進程可以與主機上的儲存空間進行互動。 請注意,此選項仍然比 Docker 套接字更好,因為容器被剩餘的安全功能鎖定,並且不能簡單地在主機上執行容器。
性能。 這裡它是最大值,因為快取已被充分使用。 如果 Podman 或 CRI-O 已經將所需的鏡像下載到主機上,那麼容器內的 Buildah 進程就不必再次下載,並且後續基於該鏡像的構建也可以從快取中獲取所需的內容。
選項3。 這種方法的本質是將多個鏡像合併到一個專案中,並使用一個容器鏡像的公共資料夾。
# mkdir /var/lib/project3
# podman run --security-opt label_level=s0:C100, C200 -v ./build:/build:z
-v /var/lib/project3:/var/lib/containers:Z quay.io/buildah/stable buildah -t image3 bud /build
# podman run --security-opt label_level=s0:C100, C200
-v /var/lib/project3:/var/lib/containers quay.io/buildah/stable buildah push image3 registry.company.com/myuser
在此範例中,我們不會在運行之間刪除專案資料夾 (/var/lib/project3),因此專案內的所有後續建置都會受益於快取。
安全。 介於選項 1 和 2 之間。一方面,容器無權存取主機上的內容,因此無法將不良內容放入 Podman/CRI-O 鏡像儲存中。 另一方面,作為其設計的一部分,容器可能會幹擾其他容器的組裝。
性能。 這裡比在主機層級使用共享快取更糟糕,因為您無法使用已使用 Podman/CRI-O 下載的映像。 但是,一旦 Buildah 下載了映像,該映像就可以在專案內的任何後續建置中使用。
額外儲存空間
У
如果您向上捲動並查看我們用於建立映像 quay.io/buildah/stable 的 Dockerfile,會發現如下幾行:
# Adjust storage.conf to enable Fuse storage.
RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock
在第一行中,我們修改容器映像內的 /etc/containers/storage.conf ,告訴儲存驅動程式使用 /var/lib/shared 資料夾中的「additionalimagestores」。 在下一行中,我們建立一個共用資料夾並新增幾個鎖定文件,以便容器/儲存不會被濫用。 本質上,我們只是創建一個空的容器鏡像儲存。
如果您將容器/儲存掛載到高於此資料夾的級別,Buildah 將能夠使用這些映像。
現在讓我們回到上面討論的選項2,當Buildah 容器可以讀取和寫入主機上的容器/存儲時,由於在Podman/CRI-O 級別緩存圖像,因此具有最大性能,但提供最低限度的安全性因為它可以直接寫入儲存。 現在,讓我們在這裡添加額外的儲存空間,並獲得兩全其美的效果。
# mkdir /var/lib/containers4
# podman run -v ./build:/build:z -v /var/lib/containers/storage:/var/lib/shared:ro -v /var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable
buildah -t image4 bud /build
# podman run -v /var/lib/containers/storage:/var/lib/shared:ro
-v >/var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable buildah push image4 registry.company.com/myuser
# rm -rf /var/lib/continers4
請注意,主機的 /var/lib/containers/storage 以唯讀模式掛載到容器內的 /var/lib/shared 。 因此,在容器中工作時,Buildah 可以使用先前使用 Podman/CRI-O 下載的任何鏡像(hello、speed),但只能寫入自己的儲存空間(hello、security)。 另請注意,這是在不停用容器 SELinux 分離的情況下完成的。
重要的細微差別
在任何情況下都不應從底層儲存庫中刪除任何影像。 否則,Buildah 容器可能會崩潰。
而這些還不是全部優點
附加儲存的可能性並不限於上述場景。 例如,您可以將所有容器映像放置在共用網路儲存體上,並授予所有 Buildah 容器存取它的權限。 假設我們的 CI/CD 系統經常使用數百個鏡像來建立容器鏡像。 我們將所有這些鏡像集中在一台儲存主機上,然後使用首選的網路儲存工具(NFS、Gluster、Ceph、ISCSI、S3...),向所有 Buildah 或 Kubernetes 節點開放對此儲存的一般存取。
現在只需將此網路儲存安裝到 /var/lib/shared 上的 Buildah 容器中就足夠了 - Buildah 容器不再需要透過 pull 下載鏡像。 因此,我們拋棄了預填充階段並立即準備好推出容器。
當然,這可以在實時 Kubernetes 系統或容器基礎設施中使用,以便在任何地方啟動和運行容器,而無需任何鏡像下載。 此外,容器註冊表收到上傳更新鏡像的推送請求後,可以自動將該鏡像發送到共享網路存儲,並立即可供所有節點使用。
容器映像的大小有時可以達到許多千兆位元組。 附加儲存的功能可讓您避免跨節點複製此類映像,並使啟動容器幾乎是即時的。
此外,我們目前正在開發一項稱為覆蓋卷安裝的新功能,這將使建置容器變得更快。
結論
在 Kubernetes/CRI-O、Podman 甚至 Docker 中的容器內執行 Buildah 是可行、簡單的,並且比使用 docker.socket 更安全。 我們大大提高了處理影像的靈活性,因此您可以透過多種方式運行它們,以優化安全性和效能之間的平衡。
附加儲存的功能可讓您加快甚至完全消除將影像下載到節點的速度。
來源: www.habr.com