一,缘起:
1,k8s1.24后不再使用Dockershim,即可不再安装docker使用其它的容器运行时如containerd,在k8s中进行镜像构建就需要寻找合适的工具。
2,jenkins容器化安装后的构建镜像步骤,不想挂载宿主机的docker和使用远端docker:2375
3,还不想使用publish over ssh等将资源传到其它服务器后再构建的模式。
二,buildkit说明
该工具使用CS模式,buildctl 为客户端,调用构建指令指明资源目录和dockerfile目录传到服务端buildkitd进行构建。服务端处理完后可选择输出镜像,或推到指定仓库。且可多个构建步骤同步执行,提升效率,并支持多种缓存模式。
服务器可在物理机安装为服务,也可运行为容器pod,也可以做为一个任务节点在使用时调度(用完即弃)。
注意:
所有的认证信息,如镜像仓,用户名密码等都由客户端提供。
如docker登陆信息,cache本地缓存等。
示例中以客户端和服务端通过tcp的方式交互。
1,安装服务端: buildkitd
物理机,docker/docker-compose,k8s安装均可,启动参数暴露端口即可。(此处未使用tls)
如:
docker run --name buildkit -d \
--privileged -p 1234:1234 \
moby/buildkit \
--addr tcp://0.0.0.0:1234
参数: --addr tcp://0.0.0.0:1234 监听1234端口
如果Dockerfile中的FROM来源是私仓且非https需要在服务端指定目录下写入配置文件:
#/etc/buildkit/buildkitd.toml
debug = true
[registry."192.168.230.5:5000"]
http = true
insecure = true
2,客户端(无需安装,容器中有提供) buildctl
docker cp buildkit:/usr/bin/buildctl /usr/local/bin/
3,构建镜像并推送,与dockerfile模式一样。
在客户端侧生成Dockerfile和镜像构建资源。
如:
./Dockerfile
./index.html
运行构建命令:
buildctl --addr tcp://127.0.0.1:1234 build \
--frontend=dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=192.168.230.5:5000/test/testbuildctl:20230816,push=true,registry.insecure=true
参数解释:
--addr tcp://buildkitd.default:1234 指定服务端地址和端口。
--frontend=dockerfile.v0 使用dockerfile
--local context=. 指向Dockerfile执行构建时的路径上下文。
--local dockerfile=. 指向dockerfile文件所在目录
--output type: 输出构建结果参数。如image为镜像,name为镜像名称(包含仓库地址和TAG的完整URL),push=true是指推送,registry.insecure=true是指目标仓库使用https。
注意:如果目标仓库需要登陆,需要将登陆信息保存在客户端侧的
$DOCKER_CONFIG 环境变量中,如docker-harbor的登陆信息:
$DOCKER_CONFIG/config.json
其中的内容为:docker login 后的认证信息。
{
"auths": {
"docker.io": {
"auth": "base64(username:password)"
}
}
}
经此步骤,最简单的buildkitd构建即完成。
其它参考官方文档资料。
三,遇到问题:
1,镜像打包后推送出现部分时间段一直不成功,偶尔又能成功的问题,显示超时,手工推送正常。不能从超时这个表面状态判断问题,查服务端日志发现是level=debug msg=Unauthorized,检查docker.config文件中配置的认证信息,发现重复配置了一个已经停用的用户,删除后测试正常。