当前位置: 首页 > 工具软件 > Buildah > 使用案例 >

buildah_Buildah入门

司允晨
2023-12-01

buildah

Buildah是一个命令行工具,用于快速,轻松地构建兼容Open Container Initiative的映像(也意味着Docker和Kubernetes兼容)。 它可以代替Docker守护进程的docker build命令(即,使用传统的Dockerfile生成映像),但具有足够的灵活性以允许您使用喜欢使用的任何工具来生成映像。 Buildah易于集成到脚本和构建管道中,最重要的是,它不需要运行中的容器守护程序即可构建其映像。

Docker构建的直接替代品

您可以立即开始使用Buildah,将其放到当前使用Dockerfile和docker docker build映像的位置。 Buildah的build-using-dockerfilebud参数使它的行为build-using-dockerfile docker build一样,因此很容易将其合并到现有脚本或构建管道中。

我以前撰写的有关Buildah的文章一样 ,我喜欢使用从源代码安装“ GNU Hello”的示例。 考虑以下Dockerfile:


   
   
FROM fedora:28
LABEL maintainer Chris Collins <collins.christopher@gmail.com>

RUN dnf install -y tar gzip gcc make \
        && dnf clean all

ADD http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz /tmp/hello-2.10.tar.gz

RUN tar xvzf /tmp/hello-2.10.tar.gz -C /opt

WORKDIR /opt/hello-2.10

RUN ./configure
RUN make
RUN make install
RUN hello -v
ENTRYPOINT "/usr/local/bin/hello"

Buildah可以像buildah bud -t hello .一样轻松地从该Dockerfile创建映像buildah bud -t hello . ,替换docker build -t hello .


   
   
[chris@krang] $ sudo buildah bud -t hello .
STEP 1: FROM fedora:28
Getting image source signatures
Copying blob sha256:e06fd16225608e5b92ebe226185edb7422c3f581755deadf1312c6b14041fe73
 81.48 MiB / 81.48 MiB [====================================================] 8s
Copying config sha256:30190780b56e33521971b0213810005a69051d720b73154c6e473c1a07ebd609
 2.29 KiB / 2.29 KiB [======================================================] 0s
Writing manifest to image destination
Storing signatures
STEP 2: LABEL maintainer Chris Collins <collins.christopher@gmail.com>
STEP 3: RUN dnf install -y tar gzip gcc make    && dnf clean all

<snip>

构建完成后,您可以使用buildah images命令查看新图像:


   
   
[chris@krang] $ sudo buildah images
IMAGE ID        IMAGE NAME                              CREATED AT              SIZE
30190780b56e    docker.io/library/fedora:28             Mar 7, 2018 16:53       247 MB
6d54bef73e63    docker.io/library/hello:latest    May 3, 2018 15:24     391.8 MB

标记为hello:latest的新映像可以推送到远程映像注册表,或者使用CRI-O或其他Kubernetes CRI兼容的运行时运行,也可以推送到远程注册表。 如果要测试它作为Docker构建的替代品,则可能需要将映像复制到Docker守护程序的本地映像存储中,以便它可以由Docker运行。 这可以通过buildah push命令轻松完成:


   
   
[chris@krang] $ sudo buildah push hello:latest docker-daemon:hello:latest
Getting image source signatures
Copying blob sha256:72fcdba8cff9f105a61370d930d7f184702eeea634ac986da0105d8422a17028
 247.02 MiB / 247.02 MiB [==================================================] 2s
Copying blob sha256:e567905cf805891b514af250400cc75db3cb47d61219750e0db047c5308bd916
 144.75 MiB / 144.75 MiB [==================================================] 1s
Copying config sha256:6d54bef73e638f2e2dd8b7bf1c4dfa26e7ed1188f1113ee787893e23151ff3ff
 1.59 KiB / 1.59 KiB [======================================================] 0s
Writing manifest to image destination
Storing signatures

[chris@krang] $ sudo docker images | head -n2
REPOSITORY              TAG             IMAGE ID        CREATED                 SIZE
docker.io/hello      latest       6d54bef73e63  2 minutes ago   398 MB

[chris@krang] $ sudo docker run -t hello:latest
Hello, world!

一些差异

与Docker构建不同,Buildah不会针对Dockerfile中的每条指令自动将更改提交到层,而是每次都从上到下构建所有内容。 从积极的方面来说,这意味着非缓存的构建(例如,您将使用自动化或构建管道进行的构建)最终会比其Docker构建对等的构建更快,尤其是在有大量指令的情况下。 从自动化部署或连续交付的角度来看,这对于快速将新更改投入生产非常有用。

但是,实际上,缺少缓存对于图像开发可能不是那么有用,因为当进行一遍又一遍的构建时,缓存层可以节省大量时间。 但是,这仅适用于build-using-dockerfile命令。 当使用Buildah本机命令时,如下所示,您可以选择何时将更改提交到磁盘,从而实现更灵活的开发。

Buildah本机命令

Buildah 真正令人瞩目的地方在于其本机命令,您可以使用它与容器构建进行交互。 Buildah的命令不是与每个构建都使用build-using-dockerfile/bud ,而是与构建过程中创建的临时容器进行实际交互的命令。 (Docker也使用临时或中间容器,但是在构建映像时,您实际上并没有与它们进行交互。)

再次使用“ GNU Hello”示例,考虑使用Buildah命令构建此映像:


   
   
#!/usr/bin/env bash

set -o errexit

# Create a container
container =$ ( buildah from fedora: 28 )

# Labels are part of the "buildah config" command
buildah config --label maintainer = "Chris Collins <collins.christopher@gmail.com>" $container

# Grab the source code outside of the container
curl -sSL http: // ftpmirror.gnu.org / hello / hello- 2.10 .tar.gz -o hello- 2.10 .tar.gz

buildah copy $container hello- 2.10 .tar.gz / tmp / hello- 2.10 .tar.gz

buildah run $container dnf install -y tar gzip gcc make
Buildah run $container dnf clean all
buildah run $container tar xvzf / tmp / hello- 2.10 .tar.gz -C / opt

# Workingdir is also a "buildah config" command
buildah config --workingdir / opt / hello- 2.10 $container

buildah run $container . / configure
buildah run $container make
buildah run $container make install
buildah run $container hello -v

# Entrypoint, too, is a “buildah config” command
buildah config --entrypoint / usr / local / bin / hello $container

# Finally saves the running container to an image
buildah commit --format docker $container hello:latest

应该立即显而易见的一件事是,这是一个Bash脚本而不是一个Dockerfile。 使用Buildah的本机命令可以轻松编写脚本,无论您使用哪种语言或自动化上下文。 这可以是一个makefile,一个Python脚本或您想要使用的任何工具。

那么这是怎么回事? 第一个Buildah命令container=$(buildah from fedora:28) ,从fedora:28映像中创建一个正在运行的容器,并将容器名称(命令的输出)存储为变量,以备后用。 其余所有Buildah命令都使用$container变量来说明要对哪个容器进行操作。 这些命令在大多数情况下是不言自明的: buildah copy将文件移入容器, buildah run在容器中执行命令。 将它们与它们的Dockerfile等效项进行匹配很容易。

最后buildah commit命令buildah commit ,将容器提交到磁盘上的映像。 在使用Buildah命令而不是从Dockerfile构建映像时,可以使用commit命令来决定何时保存更改。 在上面的示例中,所有更改都被一次提交,但也可以包括中间提交,从而使您可以选择从中开始的缓存点。 (例如,在dnf install之后将其缓存到磁盘将特别有用,因为这可能需要很长时间,但每次可靠地相同。)

挂载点,安装目录和chroot

另一个有用的Buildah命令为构建映像提供了很大的灵活性。 buildah mount将容器的根目录安装到主机上的安装点。 例如:


   
   
[ chris @ krang ] $ container =$ ( sudo buildah from fedora: 28 )
[ chris @ krang ] $ mountpoint =$ ( sudo buildah mount ${container} )
[ chris @ krang ] $ echo $mountpoint
/ var / lib / containers / storage / overlay2 / 463eda71ec74713d8cebbe41ee07da5f6df41c636f65139a7bd17b24a0e845e3 / merged
[ chris @ krang ] $ cat ${mountpoint} / etc / redhat-release
Fedora release 28 ( Twenty Eight )
[ chris @ krang ] $ ls ${mountpoint}
bin   dev  home  lib64          media  opt   root  sbin  sys  usr
boot  etc  lib   lost+found  mnt        proc  run   srv   tmp  var

这很棒,因为现在您可以与安装点进行交互以更改容器映像。 这使您可以使用主机上的工具来构建和安装软件,而不必在容器映像本身中包括这些工具。 例如,在上面的Bash脚本中,我们需要安装tar,Gzip,GCC,并制作软件包以在容器内编译“ GNU Hello”。 使用安装点,我们可以使用相同的软件构建映像,但是下载的tarball和tar,Gzip等RPM都在主机上,而不是在容器和生成的映像中:


   
   
#!/usr/bin/env bash

set -o errexit

# Create a container
container =$ ( buildah from fedora: 28 )
mountpoint =$ ( buildah mount $container )

buildah config --label maintainer = "Chris Collins <collins.christopher@gmail.com>" $container

curl -sSL http: // ftpmirror.gnu.org / hello / hello- 2.10 .tar.gz \
      -o / tmp / hello- 2.10 .tar.gz
tar xvzf src / hello- 2.10 .tar.gz -C ${mountpoint} / opt

pushd ${mountpoint} / opt / hello- 2.10
. / configure
make
make install DESTDIR = ${mountpoint}
popd

chroot $mountpoint bash -c "/usr/local/bin/hello -v"

buildah config --entrypoint "/usr/local/bin/hello" $container
buildah commit --format docker $container hello
buildah unmount $container

注意上面脚本中的几件事:

  1. curl命令将压缩文件下载到主机,而不是映像

  2. tar命令(从主机本身运行)将tarball的源代码提取到容器内的/opt中。

  3. Configuremakemake install都从安装点内部的目录运行,安装到主机上,而不是在容器本身内部运行。

  4. 此处的chroot命令用于将root本身更改为安装点,并测试“ hello”是否正常工作,类似于先前示例中使用的buildah run命令。

该脚本更短,使用了大多数Linux人士已经熟悉的工具,并且生成的映像更小(没有压缩包,没有额外的软件包等)。 您甚至可以使用主机系统的软件包管理器将软件安装到容器中。 例如,假设您想通过GNU Hello将NGINX安装到容器中(无论出于何种原因):


   
   
[chris@krang] $ mountpoint=$(sudo buildah mount ${container})
[chris@krang] $ sudo dnf install nginx --installroot $mountpoint
[chris@krang] $ sudo chroot $mountpoint nginx -v
nginx version: nginx/1.12.1

在上面的示例中,DNF与--installroot标志一起用于将NGINX安装到容器中,可以使用chroot进行验证。

试试看!

Buildah是创建容器映像的轻量级且灵活的方法,而无需在主机上运行完整的Docker守护程序。 除了提供从Dockerfiles进行构建的开箱即用支持外,Buildah还易于与脚本或您选择的构建工具一起使用,并且可以帮助您使用构建主机上的现有工具来构建容器映像。 结果是更精简的图像,这些图像使用较少的带宽来传送,需要较少的存储空间,并且对于潜在的攻击者而言具有较小的表面积。 试试看!

[请参阅我们的相关故事, 使用Buildah创建小容器 ]

翻译自: https://opensource.com/article/18/6/getting-started-buildah

buildah

 类似资料: