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.
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
文件