首页 > 其他分享 >镜像构建工具 buildah

镜像构建工具 buildah

时间:2023-02-14 11:14:43浏览次数:60  
标签:KB fedora root 构建 镜像 buildah hello

什么是 buildah

它是一个专注与构建 OCI 镜像的工具,它可以用来:

  • 从头开始或从一个镜像创建一个容器
  • 从容器或通过 Dockerfile 创建镜像
  • 构建 OCI 或者 docker 格式的镜像
  • 挂载容器的根文件系统
  • 卸载容器的根文件系统
  • 使用容器根文件系统的更新内容作为文件系统层来创建新镜像
  • 删除容器或镜像
  • 重命名本地容器

那么,有了 Docker 或者 Podman 为什么还需要 buildah?

与之前podman 配置简介 所写的一样,buildah 也是无守护进程以及可以 rootless 运行的。

请相信 buildah,构建镜像就别劳烦那俩货了,我认为 podman 居然可以构建镜像就已经是多管闲事了,事实上也有不少反馈反应 podman 构建镜像很慢的。

我们需要更专业的工具来构建镜像。buildah 的思想不再局限通过一个 Containerfile 去描述一个镜像,而是为镜像构建提供了一种新的思路,你可以很轻松的复刻任何一个容器为镜像。

配置 buildah

buildah 是完全符合 OCI 规范的,所以配置完全参考 podman 配置简介 即可。包括 国内源 和 rootless

buildah 的各种操作

通过 Dockerfile 构建镜像

当然了,这应该是属于基操(勿6)。准备一个 Dockerfile:

FROM fedora:32
MAINTAINER <[email protected]>
RUN echo "hello fedora" > /index.txt
CMD cat /index.txt

构建运行:

$ buildah build -t fedora-hello .
STEP 1/4: FROM fedora:32
STEP 2/4: MAINTAINER <[email protected]>
STEP 3/4: RUN echo "hello fedora" > /index.txt
STEP 4/4: CMD cat /index.txt
COMMIT fedora-hello
Getting image source signatures
Copying blob fa96786f7d52 skipped: already exists
Copying blob 3491ca9ebf88 done
Copying config 58abb8869f done
Writing manifest to image destination
Storing signatures
--> 58abb8869f6
Successfully tagged localhost/fedora-hello:latest
58abb8869f689d53400690e9da3ee4f96705cc907a9b4cbaeec30c7afcebd267

构建成功(那不是理所当然的吗),直接用 podman 看一下镜像(换成 buildah 也能看,命令一样)

$ podman images
REPOSITORY                     TAG         IMAGE ID      CREATED         SIZE
localhost/fedora-hello         latest      a82aa8a08eda  10 seconds ago  209 MB

然后就是跑起来啦

$ podman run --rm fedora-hello
hello fedora

完全没有任何问题。但是如果仅仅是这样,那也太不能显示 buildah 的强大之处了。

使用命令式构建镜像

buildah 相对于 Dockerfile 提供了强大的命令式构建方式,将 Dockerfile 指令变成一条一条的命令,为我们构建镜像提供了新的选择:

$ container=$(buildah from fedora:32)
$ buildah run $container -- bash -c 'echo "hello fedora" > /index.txt'
$ buildah config --cmd "cat /index.txt" $container
$ buildah commit $container fedora-hello-cli
Getting image source signatures
Copying blob fa96786f7d52 skipped: already exists
Copying blob 44c13b143fff done
Copying config 454818c642 done
Writing manifest to image destination
Storing signatures
454818c642188a9d2d64f57deedbac40cb22eb597e2ce9c003c8e71d2f150be9

再使用 podman 跑一下:

$ podman run --rm fedora-hello-cli
hello fedora

没有任何问题,就很舒服。你可以将这一串指令保存为 .sh,就像 Dockerfile 一样,buildah 官方仓库提供了一个比较完整的示例:

$ cat > lighttpd.sh <<"EOF"
#!/usr/bin/env bash -x

ctr1=$(buildah from "${1:-fedora}")

## Get all updates and install our minimal httpd server
buildah run "$ctr1" -- dnf update -y
buildah run "$ctr1" -- dnf install -y lighttpd

## Include some buildtime annotations
buildah config --annotation "com.example.build.host=$(uname -n)" "$ctr1"

## Run our server and expose the port
buildah config --cmd "/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf" "$ctr1"
buildah config --port 80 "$ctr1"

## Commit this container to an image name
buildah commit "$ctr1" "${2:-$USER/lighttpd}"
EOF
$ chmod +x lighttpd.sh
$ sudo ./lighttpd.sh

当然了,这种方式也许并没有太大的吸引力,但是,当它配合上 mount 之后,威力就彻底发挥出来了

使用 mount 指令

在上面我们创建了一个 $container 变量来存储一个容器名。可以打印一下:

$ echo $container
fedora-working-container-1

接着,我们可以直接把这个容器 mount 进来(其实可以mount任何容器哦):

如果是在 rootless 模式,需要先执行一次 buildah unshare 在用户名称空间中启动一个具有修改过的 ID mapping 的命令,因为 mount 需要在不同的命令空间

$ buildah unshare
$ fedoramnt=$(buildah mount fedora-working-container-1)

然后我们就直接把整个容器挂在到了我们的宿主机中,打印一下:

$ echo $fedoramnt
/home/zido/.local/share/containers/storage/overlay/6f498ec049db976fdc07bae7f0c6b321d2158c120270d1d1a51a18b625b6a449/merged
$ ls $fedoramnt -l
lrwxrwxrwx root root   7 B  Wed Jan 29 02:30:58 2020  bin ⇒ usr/bin
dr-xr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  boot
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:47:38 2021  dev
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:48:12 2021  etc
drwxr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  home
.rw-r--r-- root root  13 B  Fri Sep 24 23:14:46 2021  index.txt
lrwxrwxrwx root root   7 B  Wed Jan 29 02:30:58 2020  lib ⇒ usr/lib
lrwxrwxrwx root root   9 B  Wed Jan 29 02:30:58 2020  lib64 ⇒ usr/lib64
drwx------ root root 4.0 KB Tue Apr 27 14:47:38 2021  lost+found
drwxr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  media
drwxr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  mnt
drwxr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  opt
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:47:39 2021  proc
dr-xr-x--- root root 4.0 KB Tue Apr 27 14:48:12 2021  root
drwxr-xr-x root root 4.0 KB Fri Sep 24 23:11:30 2021  run
lrwxrwxrwx root root   8 B  Wed Jan 29 02:30:58 2020  sbin ⇒ usr/sbin
drwxr-xr-x root root 4.0 KB Wed Jan 29 02:30:58 2020  srv
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:47:39 2021  sys
drwxrwxrwt root root 4.0 KB Tue Apr 27 14:48:12 2021  tmp
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:47:54 2021  usr
drwxr-xr-x root root 4.0 KB Tue Apr 27 14:47:58 2021  var

接下来就可以应用任何 linux 工具去修改里面的任意文件,例如:

$ echo 'hello fedoramnt' > $fedoramnt/index.txt

或者甚至,你可以直接 chroot 到里面执行 fedora 的任何操作,发挥你的想象吧,我只是做个示例:

$ chroot $fedoramnt /bin/sh
sh-5.0# ls
sh-5.0# echo "I'm inside" >> index.txt
sh-5.0# cat index.txt
hello fedoramnt
I'm inside
sh-5.0# exit
exit

然后卸载该容器文件系统,配上新命令(如果有变化),跑一下:

$ container=$(buildah umount fedora-working-container-1)
$ buildah config --cmd "cat /index.txt" $container
$ buildah commit $container fedora-hello-cli2
$ podman run --rm fedora-hello-cli2
hello fedoramnt
I'm inside

好了,你有新的镜像了,关键是速度非常快。这与 docker commit 有点类似,却有是完全不同的工作流,就很香。

总结

至此,OCI 三剑客就介绍完了,podman、skopeo、buildah 互相之间功能会有些重叠,不过总的来看还是专人专事的。

另外可能大家会好奇为什么我会纠结于 rootless 模式,这是因为我的工作内容大概就是为用户提供一个可连接的 k8s 容器,因此我会很关注安全,因为你永远无法预测用户会在容器内干什么,一不小心逃逸出来就是大乱子了。

相比起原来的 Docker。OCI 镜像事实上具有很多意想不到的可玩性,如果有时间,我后面可能会出一些博文讲解一下具体的应用吧(挖个坑,管挖不管埋)。

标签:KB,fedora,root,构建,镜像,buildah,hello
From: https://www.cnblogs.com/cheyunhua/p/17118933.html

相关文章

  • 自动化运维:如何零停机构建与部署项目
    本文,我们将向您展示如何配置一个流水线,该流水线将在零停机的情况下构建、测试和部署项目。零停机是一种部署技术,可让您在此过程中通过终端用户完全更新网站。请确保在您......
  • Idea基于Gradle构建SpringBoot3.0集成MP项目
    发生缘由学习Idea基于Gradle构建SpringBoot3.0集成MP项目运行环境电脑系统:win10jdk:17.0.6JVM:JavaHotSpot(TM)64-BitServerVM(build17.0.6+9-LTS-190,mixed......
  • coding持续集成构建环境自定义node版本
    解决方案只需要在构建计划的编写过程中增加一个如下的stage,具体nodejs版本下载地址可参考https://nodejs.org/en/download/releases/这里。stage('toggleNode.......
  • 使用 PHP 和 Laravel 构建 REST API 的教程
    RepresentationalStateTransfer( ​​REST​​ )是一种用于构建Web服务的流行软件架构样式。RESTAPI允许客户端通过向特定端点或“路由”发出HTTP请求来从服务......
  • Docker本地镜像发布到阿里云
    Docker本地镜像发布到阿里云​​1、将本地镜像推送到阿里云​​​​1.1、本地镜像素材原型​​​​1.2创建仓库镜像​​​​1.3选择个人实例​​​​1.4选择命名空间,没有......
  • Docker本地镜像发布到私有库
    本地镜像发布到私有库​​1、私有库是什么?​​​​2、将本地镜像推送到私有库实践​​​​2.1下载镜像DockerRegistry​​​​2.2运行私有库​​​​2.3制作一个新镜像......
  • Docker镜像是什么?
    Docker镜像​​1、Docker镜像是什么?​​​​1.1分层的镜像​​​​1.2UnionFS(联合文件系统)​​​​1.3Docker镜像加载原理​​​​1.4为什么Docker才200M?​​​​1.5......
  • Docker容器的ubuntu镜像配置apt国内源
    1、问题描述  在Docker容器中安装ubuntu镜像之后,默认使用的软件源是ubuntu的官网,速度非常慢,更新软件包经常报错  而且初始镜像默认没有安装vim命令,导致修改​​/etc/ap......
  • 创维光伏:坚持科技创新,构建中国式现代化光伏生态体系
    前言:党的二十大报告提出:中国共产党的中心任务就是团结带领全国各族人民全面建成社会主义现代化强国、实现第二个百年奋斗目标,以中国式现代化全面推进中华民族伟大复兴。报告......
  • 初级入门 ---用基本图形构建规则形体。
    WebGL坐标系本节开始学习3D形体的绘制,与之前几个章节绘制点和面不同,3D形体的顶点坐标需要包含深度信息Z轴坐标。所以我们先了解一下WebGL坐标系的概念。WebGL......