最近一直在弄docker相关的东西, 因为我自己在用m1的mac,
架构是arm64的,
与一般服务器常用的x86_64架构不同,
因此构建的镜像在服务器上无法使用, 需要二次构建, 这怎么可能?!
必须一次性搞定, 因此本文记录一下
笨办法
参考资料
多架构下的
Docker 镜像 – 陈少文的网站
docker多架构镜像_oneslide的博客-CSDN博客_docker
多架构镜像
解决方法
因为部分应用着急用, 先用笨办法解决一下👇🏻
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 REGISTRY="nexus.goldwind.com.cn" IMG_PATH="aws/prod/pricing-api" docker login ${REGISTRY} docker build -t ${REGISTRY} /${IMG_PATH} :$(uname -m) . docker push ${REGISTRY} /${IMG_PATH} :$(uname -m) docker pull ${REGISTRY} /${IMG_PATH} :x86_64 docker pull ${REGISTRY} /${IMG_PATH} :arm64 docker manifest rm ${REGISTRY} /${IMG_PATH} :latest docker manifest create --insecure ${REGISTRY} /${IMG_PATH} :latest ${REGISTRY} /${IMG_PATH} :x86_64 ${REGISTRY} /${IMG_PATH} :arm64 docker manifest annotate --os linux --arch arm64 ${REGISTRY} /${IMG_PATH} :latest ${REGISTRY} /${IMG_PATH} :arm64 docker manifest annotate --os linux --arch amd64 ${REGISTRY} /${IMG_PATH} :latest ${REGISTRY} /${IMG_PATH} :x86_64 docker manifest push --insecure ${REGISTRY} /${IMG_PATH} :latest
问题&缺陷
很明显, 这个需要在两个环境分别执行, 效率极低不说, 主要是很麻烦,
而且缺少环境还不能搞, 这个肯定不行,
需要在一个环境可以直接构建是最好的
聪明方法
查询资料
经过一段时间的google, 查找到了官方提供了一个名为buildx的方法支持多架构构建镜像,
其中的概览如下:
Docker Buildx is a CLI plugin that extends the docker command with
the full support of the features provided by Moby BuildKit builder
toolkit. It provides the same user experience as docker build with many
new features like creating scoped builder instances and building against
multiple nodes concurrently.
翻译一下
Docker Buildx是一个CLI插件,它扩展了docker命令,完全支持Moby BuildKit
builder工具包提供的功能。它提供了与docker
build相同的用户体验和许多新的功能,如创建范围内的构建器实例和针对多个节点并发构建。
另外, 比较有用的信息还有:
Feature
docker
docker-container
kubernetes
remote
Automatic
--load
✅
❌
❌
❌
Cache export
❔ (inline only)
✅
✅
✅
Docker/OCI tarball
output
❌
✅
✅
✅
Multi-arch images
❌
✅
✅
✅
BuildKit
configuration
❌
✅
✅
❔ (managed externally)
因为我需要解决的是多架构构建的问题, 因此官方有写如何并发构建的内容, 后续用上的时候在看
通读了官方文档, 其中提示到👇🏻的信息
While Docker Desktop comes preconfigured with
binfmt_misc support for additional platforms, for other
installations it likely needs to be installed using tonistiigi/binfmt
image.
说明有些镜像可能需要安装额外的binfmt_misc支持,
执行👇🏻命令
1 docker run --privileged --rm tonistiigi/binfmt --install all
过程记录
如何构建多架构
Docker 镜像?_云计算_Preetam DSouza_InfoQ精选文章
docker buildx
开启及使用(模拟器构建和远程构建) - 简书
默认驱动器
1 2 docker buildx create --name mybuilder --use
添加新驱动
1 2 3 4 5 6 REGISTRY="nexus.goldwind.com.cn" IMG_PATH="aws/prod/pricing-api" docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t ${REGISTRY} /${IMG_PATH} :latest --push .
返回HTTP类型的请求导致错误
如👆🏻图, 报错, 因为私服不是HTTPS协议的, 因此无法推送镜像, 查询手册,
发现可以添加--allow security.insecure解决
添加参数忽略证书问题
添加后, 依旧报错,
不过错误不同了granting entitlement security.insecure is not allowed by build daemon configuratio
不允许的参数
通过阅读👇🏻的官方文档
Change
Docker Desktop preferences on Mac | Docker Documentation
dockerd
| Docker Documentation
说实话没啥用, 一个是说修改Docker Desktop配置的介绍,
一个是说如何对Engine添加相关命令行--insecure-registry参数的,
无法解决我这个使用buildx的问题
docker
- push cache to insecure registry by buildx - Stack Overflow
上面的帖子貌似揭示了一些问题,
我原来的Docker Desktop配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { "builder" : { "gc" : { "defaultKeepStorage" : "20GB" , "enabled" : true } } , "experimental" : true , "features" : { "buildkit" : true } , "insecure-registries" : [ "10.32.26.254:8082" , "10.32.26.254:8088" , "10.32.90.208:8080" , "nexus.goldwind.com.cn:8080" , "nexus.goldwind.com.cn:9000" ] , "registry-mirrors" : [ "http://nexus.goldwind.com.cn:9000" ] }
修改后的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { "builder" : { "gc" : { "defaultKeepStorage" : "20GB" , "enabled" : true } } , "experimental" : true , "features" : { "buildkit" : true } , "insecure-registries" : [ "10.32.26.254:8082" , "10.32.26.254:8088" , "10.32.90.208:8080" , "http://nexus.goldwind.com.cn:8080" , "http://nexus.goldwind.com.cn:9000" ] , "registry-mirrors" : [ "http://nexus.goldwind.com.cn:9000" ] }
添加了schema(http://),
不过依旧无效❎ , 继续查文档
docker
buildx build | Docker Documentation
上面是官方给出的buildx添加参数方法
1 2 docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' docker buildx build --allow security.insecure .
依照官方的, 修改我的命令
1 2 docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t ${REGISTRY} /${IMG_PATH} :latest --push --allow security.insecure .
运行报错
提示返回了http协议的内容, 报错
Buildx
is not honouring the insecure registry config in toml config provided by
the default builder. · Issue #777 · docker/buildx
搜到上面的一个帖子, 里面指出需要指定一个toml的配置文件,
通过这个配置文件说明registry的情况, 因此修改命令
1 2 3 4 5 6 7 8 9 10 docker buildx rm insecure-builder cat << EOF > buildkit-config.toml [registry."${REGISTRY}"] # 这行不需要加, 无需设置镜像代理 # mirrors = ["${REGISTRY}"] http = true insecure = true EOF docker buildx create --use --config buildkit-config.toml --name insecure-builder docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t ${REGISTRY} /${IMG_PATH} :latest --push --allow security.insecure .
执行后报错
回到了之前的问题?
这个报错居然回到了之前的问题???
那么如果将之前的解决方法与这个方法合并一下呢?
1 2 3 docker buildx rm insecure-builder docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' --config buildkit-config.toml docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t ${REGISTRY} /${IMG_PATH} :latest --push --allow security.insecure .
终于成功了!太不容易了
总结
核心参考文档如下:
docker
buildx build | Docker Documentation
Buildx
is not honouring the insecure registry config in toml config provided by
the default builder. · Issue #777 ·
docker/buildx https://github.com/docker/buildx/issues/777#issuecomment-928000274
完整命令汇总如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 REGISTRY="nexus.goldwind.com.cn:8080" IMAGE_PROJECT="jsonhero" IMAGE_ENV="prod" IMAGE_NAME="jsonhero" IMG_PATH="${IMAGE_PROJECT} /${IMAGE_ENV} /${IMAGE_NAME} " docker login ${REGISTRY} cat << EOF > buildkit-config.toml [registry."${REGISTRY}"] # 这行不需要加, 无需设置镜像代理 # mirrors = ["${REGISTRY}"] http = true insecure = true EOF docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' --config buildkit-config.toml docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t ${REGISTRY} /${IMG_PATH} :latest --push --allow security.insecure .
反思
以后遇到这类问题首先应该先去看看官方手册是否有对某个功能的详细文档描述,
比如buildx build这块的配置内容我就绕了弯路,
没理解buildx其实是通过container的方式实现构建工作的,
跟你本地的docker服务配置没关系的,
并且自己已经配置了insecure-registry的相关内容,
按理说不会有返回http请求的报错了, 还报错就证明方向出了问题.
搜索到部分帖子说到了buildx create, 应当去查查官方文档,
比如我在写下这段话的时候去搜了一下, 正好找到了更详细的信息👇🏻
docker
buildx create | Docker Documentation
buildkit/buildkitd.toml.md
at master · moby/buildkit
其中1号链接为官方介绍buildx create --config相关信息的详细说明,
2号链接为官方链接中包含的样例配置信息,
其中就包含了本次的全部信息.
搜索其他博客或者StackOverflow的提问多数时候可以快速解决问题, 但是,
如果要知其然且知其所以然, 还是需要多看看官方手册的说明,
其中不光内容翔实, 也可以更快速的解决问题, 有时候==慢就是快,
快反而慢==