buildah镜像构建, 替代dockerfile生成镜像


buildah 构建镜像工具

简述

​ Kubernetes宣布自 v1.20 起放弃对 Docker 的支持,在未来版本将全面弃用 官方文章

​ Kubernetes在安装过程中会直接使用containerd作为底层容器服务, 而containerd自带的ctr命令或者第三方工具crictl命令都没有构建镜像的功能

​ 所以在构建镜像的操作中,还是需要启动docker守护进程,并使用docker build来完成构建镜像操作。

​ 由此,需要一个可以摆脱docker服务的工具,就是 Buildah 工具

​ Buildah 是一个命令行工具,可以方便、快捷的构建与开放容器标准Open Container Initiative(OCI)兼容的容器镜像,这意味着其构建的镜像与 Docker 和 Kubernetes 兼容。

​ 该工具可作为 Docker 守护进程 docker build 命令(即使用传统的 Dockerfile 构建镜像)的一种简单drop-in替换,而且更加灵活,允许构建镜像时使用你擅长的工具。

​ Buildah 可以轻松与脚本集成并生成流水线pipeline,最好之处在于构建镜像不再需要运行容器守护进程。

源码安装

当前最新稳定版本: 1.21.1
githup地址: https://github.com/containers/buildah

环境需求

  • make
  • golang (Requires version 1.13 or higher.)
  • bats
  • btrfs-progs-devel
  • bzip2
  • device-mapper-devel
  • git
  • go-md2man
  • gpgme-devel
  • glib2-devel
  • libassuan-devel
  • libseccomp-devel
  • runc (Requires version 1.0 RC4 or higher.)
  • containers-common (包含大多数的配置文件信息,可由buildah源码编译后获取对应配置文件)
  • container-selinux

安装GO编译环境

GO安装包: https://golang.org/dl/

$ wget https://golang.org/dl/go1.16.5.linux-amd64.tar.gz
$ tar -C tar -C /usr/local -xzf go1.16.5.linux-amd64.tar.gz
$ echo "export PATH=$PATH:/usr/local/go/bin" /etc/profile <<EOF
$ source /etc/profile
$ go version
go version go1.16.5 linux/amd64

获取buildah源码

需要指定--branch参数,否则在源码构建后版本会为最新版本(非稳定版)

$ git clone --branch v1.21.1 https://github.com/containers/buildah.git

安装基础依赖

$ yum -y install  make  gcc  btrfs-progs-devel bzip2  device-mapper-devel    gpgme-devel  glib2-devel  libassuan-devel  libseccomp-devel container-selinux

安装runc命令

tar 参数 --strip-components=N去除解压文件前N层目录

$ mkdir /opt/tools

$ wget -P /opt/tools https://github.com/containerd/containerd/releases/download/v1.5.2/cri-containerd-cni-1.5.2-linux-amd64.tar.gz

$ tar --strip-components=3 -C /usr/local/sbin/ -xf  /opt/tools/cri-containerd-cni-1.5.2-linux-amd64.tar.gz usr/local/sbin/runc 

$ ll /usr/local/sbin/runc
-rwxr-xr-x. 1 1001 116 14385384 5月  20 00:57 runc

编译安装

$ make
$ make install

$ ls -lrt bin/
buildah  imgtype

# 添加至可执行环境变量中
$ cp bin/buildah /usr/local/bin/
$ buildah --version
buildah version 1.21.1 (image-spec 1.0.1-dev, runtime-spec 1.0.2-dev)

将源码包的配置文件复制对应路径, 并设置XDG_RUNTIME_DIR变量

​ XDG_RUNTIME_DIR 变量默认为/run/user/0 的路径,

​ buildah在login的时候生成一个 ${XDG_RUNTIME_DIR }/containers/auth.json 的文件来记录远程仓库的地址账号密码加密串.

​ 在这里需要变更实际路径为 /etc , 让buildah寻找指定的路径/etc/contianers/auth.json

​ storage.conf配置文件 graphroot 参数 为 镜像存储目录

mkdir /etc/containers
cp ./docs/samples/registries.conf /etc/containers/
cp ./tests/policy.json /etc/containers/
cp ./vendor/github.com/containers/storage/storage.conf /etc/containers/

# 设置全局变量
echo "export XDG_RUNTIME_DIR=/etc" >>/etc/profile
source /etc/profile

# 修改buildah的存储路径
$ vim /etc/containers/storage.conf
[storage]
graphroot = "/var/lib/containers/storage"
==>
[storage]
graphroot = "/data/containers/storage"

$ mkdir -p /data/containers/storage

使用

拉取示例nginx

$ build pull docker.io/library/nginx
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 30afc0b18f67 done  
Copying blob 596b1d696923 done  
Copying blob 351ad75a6cfa done  
Copying blob 8283eee92e2f done  
Copying blob febe5bd23e98 done  
Copying blob 69692152171a done  
Copying config d1a364dc54 done  
Writing manifest to image destination
Storing signatures
d1a364dc548d5357f0da3268c888e1971bbdb957ee3f028fe7194f1d61c6fdee
$ buildah  images
REPOSITORY                TAG      IMAGE ID       CREATED       SIZE
docker.io/library/nginx   latest   d1a364dc548d   2 weeks ago   137 MB

$ ls  /data/containers/storage
cache  mounts  overlay  overlay-containers  overlay-images  overlay-layers  storage.lock  tmp  userns.lock

$ ll  /data/containers/storage/overlay-images/
drwx------. 2 root root 4096 6月  10 12:03 d1a364dc548d5357f0da3268c888e1971bbdb957ee3f028fe7194f1d61c6fdee
-rw-------. 1 root root 1922 6月  10 12:03 images.json
-rw-r--r--. 1 root root   64 6月  10 12:03 images.lock

登录https协议的私有仓库harbor

登录https前需要将harbor证书放置在对应环境上,否则会报错

authenticating creds for "192.168.10.10": error pinging docker registry 192.168.10.10: Get "https://192.168.10.10/v2/": x509: certificate signed by unknown authority

将harbor证书放置在客户端/etc/containers/certs.d/${仓库名}中, 其中harbor.crt 由harbor服务端提供

mkdir -p /etc/containers/certs.d/192.168.xx.xx
cp harbor.crt  /etc/containers/certs.d/192.168.xx.xx/
$ buildah login 192.168.10.10
username: xxx
password: 222

# 查看auth.json文件
$ cat /etc/containers/auth.json
{
	"auths": {
		"192.168.10.10": {
			"auth": "xxxxx"
		}
	}
}

自建Dockerfile文件,使用buildah构建镜像,并上传至私有仓库harbor中


$ cat > Dockerfile <<EOF
FROM docker.io/library/nginx:1.21.0
RUN echo 'This is version 4' > /usr/share/nginx/html/index.html
EOF

$ buildah bud -f Dockerfile -t 192.168.10.10/admin/nginx:v3.0


$ buildah image 
REPOSITORY                     TAG      IMAGE ID       CREATED          SIZE
192.168.10.10/admin/nginx       v3.0     8e0080526eda   6 minutes ago    137 MB


$ buildah push 192.168.10.10/admin/nginx:v3.0

配置文件

storage.conf

必须存在

路径: /etc/containers/stroage.conf
链接: https://github.com/containers/buildah/blob/master/vendor/github.com/containers/storage/storage.conf

描述: 数据存储配置文件,包含数据存储目录修改

registries.conf

必须存在

路径: /etc/containers/registries.conf
链接: https://github.com/containers/buildah/blob/master/docs/samples/registries.conf
描述: registries.conf 是配置文件,它指定在完成不包含注册表或域部分的映像名称时应咨询哪些容器注册表。

policy.json

必须存在

路径: /etc/containers/policy.json

链接:https://github.com/containers/buildah/blob/master/tests/policy.json

描述: 待补充

mounts.conf

可选

路径:/usr/share/containers/mounts.conf 或者 可选路径 /etc/containers/mounts.conf
链接: https://src.fedoraproject.org/rpms/skopeo/blob/master/f/mounts.conf
描述: 文件指定在执行buildah run 或者 buildah build-using-dockerfile命令时自动挂载在容器内的卷挂载文件或目录。然后容器进程可以使用此内容。卷装入内容不会提交到最终镜像

seccomp.json

可选

路径: /usr/share/containers/seccomp.json
链接: https://src.fedoraproject.org/rpms/skopeo/blob/master/f/seccomp.json
描述:seccomp.json 包含允许在容器内使用的 seccomp 规则列表。该文件通常由容器公共包提供。

报错

编译报错

$ make
cgo: exec gcc: exec: "gcc": executable file not found in $PATH

修复建议 : make依赖gcc软件包,需要安装gcc

执行命令: yum install gcc

$ make 
Package libseccomp was not found in the pkg-config search path.

buildah镜像构建, 替代dockerfile生成镜像 


Perhaps you should add the directory containing `libseccomp.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libseccomp' found
Package libseccomp was not found in the pkg-config search path.
Perhaps you should add the directory containing `libseccomp.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libseccomp' found
pkg-config: exit status 1
make: *** [bin/buildah] 错误 2

修复建议: 缺乏 libseccomp 依赖

执行命令: yum install libseccomp

其他报错

$ buildsh push 192.168.10.10/admin/nginx:latest
Error writing blob: Error initiating layer upload to /v2/admin/print-num/blobs/uploads/ in 192.168.10.10: unauthorized: unauthorized to access repository: admin/print-num, action: push: unauthorized to access repository: admin/print-num, action: push

修复建议: 需要提前登录私有仓库中,否则上传镜像时候会没push权限

执行命令: buildsh login 192.168.10.10

$ buildah bud -f Dockerfile -t 192.168.10.10/admin/test:v4.0
STEP 1: FROM docker.io/library/nginx:1.21.0
STEP 2: RUN echo 'This is version 4' > /usr/share/nginx/html/index.html
error running container: error from  creating container for [/bin/sh -c echo 'This is version 4' > /usr/share/nginx/html/index.html]: : fork/exec : no such file or directory
error building at STEP "RUN echo 'This is version 4' > /usr/share/nginx/html/index.html": error while running runtime: exit status 1

修复建议: 当前主机缺乏runc命令, 需安装runc命令

$ buildah bud -f Dockerfile -t 192.168.10.10/admin/nginx:v1.0
STEP 1: FROM docker.io/library/nginx:1.20.0
STEP 2: RUN echo 'This is version 4' > /usr/share/nginx/html/index.html
WARN[0004] Path "/usr/share/rhel/secrets" from "/usr/share/containers/mounts.conf" doesn't exist, skipping 
/bin/sh: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
error building at STEP "RUN echo 'This is version 4' > /usr/share/nginx/html/index.html": error while running runtime: exit status 127

修复建议: 缺乏 container-selinux 依赖

执行命令: yum install container-selinux

error creating build container: open /etc/containers/policy.json: no such file or directory

修复建议: 缺少policy.json文件

参考链接

https://linux.cn/article-9836-1.html

本文作者:风吹蛋生丶

本文链接:https://www.cnblogs.com/xzj-blog/p/15157923.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @ 2023-06-04 11:52  技术颜良  阅读(638)  评论(0编辑  收藏  举报