在x86平台下使用Buildx构建跨平台镜像并运行arm应用

最近又开始写qqbot,因为OPQBot针对linux/amd64平台做出了限制,很多东西无法实现,而我手上除了一台vps以外又没有其他平台的机子用来24h跑bot,所以想到在Docker的跨平台容器里跑opq

各平台的限制

About Buildx

BuildKit是下一代的Docker镜像构建工具,来源于Moby/BuildKit。在最新的Docker Desktop和Docker CE中,官方以Buildx形式集成到Docker CLI中,不再需要额外构建添加。

使用Buildx,开发者可以轻松构建不同平台镜像

在本地安装使用Buildx构建多平台镜像

在最新的Docker Desktop以及Docker CE中已经集成了Buildx,但是并未启用多平台构建,为了启用此特性,需要做以下操作:

1. 安装qemu多平台支持

运行以下容器:

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

该容器会为你的设备安装qemu多平台支持,如果你需要运行跨平台容器,也会用到它。

2. 创建新的builder实例并设为默认

docker buildx create --use --name mybuilder

看到输出mybuilder即表示创建成功,使用--use指令将在builder实例创建完成时自动将其设为默认,否则需要手动使用docker buildx use mybuilder将创建的实例设为默认。

3. 使用Buildx构建多平台镜像

Buildx的使用与docker build十分相似,基本上只需要将命令中的docker build替换成docker buildx build即可。如果使用docker buildx install将默认的docker build替换为Buildx,那么直接使用docker build即可。

例如,将当前目录下的Dockerfile文件打包成镜像,需要使用以下命令:

docker buildx build -t xxx/xxx:tag . --push

如果替换了默认docker build,将是这样的:

docker build -t xxx/xxx:tag . --push

--push指令会自动把构建好的镜像推送到远端仓库,否则只会在存放在cache中。

如果要构建多平台镜像,在指令中加入--platform=即可,等号后填写需要构建的平台,如linux/armlinux/arm64linux/amd64等,用,隔开。Dockerfile本身并不需要做出更改,除非你需要做的操作在不同平台下有所区别,比如根据平台下载不同文件等。

docker buildx build --platform=linux/arm,linux/arm64,linux/amd64 -t xxx/xxx:tag . --push

Buildx将根据以上指令自动构建三个平台的镜像并推送到远端,这三个镜像会使用命令中指定的同一个tag。

需要注意的是,指定的平台必须是底层镜像所支持的。

Docker Documents查看更多详细的说明。

使用GitHub Action自动构建多平台镜像

由于DockerHub的自动构建工具对多平台支持并不友好,推荐使用GitHub Action来构建。具体流程如下:

1. 创建GitHub Action流程

在GitHub仓库中点击Actions进入GitHub Action页面,点击set up a workflow yourself创建新的Action流程。

创建GitHub Action流程

2. 编辑GitHub Action流程

这实际上就是编辑位于仓库.github/workflows/文件夹下的一个yml文件。

使用docker官方在GitHub创建的几个流程组合起来可以快速完成我们需要的任务。可以参考以下内容:

name: docker build and push

on:
  release:
    branches: [ main ]
    types: released
    # 将在main分支的release发布时自动运行该流程
  workflow_dispatch:
    # 将在GitHub Action界面创建一个run workflow按钮,点击后执行该流程
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Get the tag name
        run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
        # 获取release tag,在创建镜像时会用到
      - name: Setup QEMU
        uses: docker/setup-qemu-action@v1

      - name: Docker Setup Buildx
        uses: docker/[email protected]
        # 启用Buildx
      - name: Login
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
            # 登陆DockerHub账号,供推送镜像使用,这里的secrets需要在仓库设置页面添加
      - name: Build and Push with Version Tag
        uses: docker/build-push-action@v2
        with:
          context: .
          platforms: linux/amd64,linux/arm64,linux/arm
          push: true
          tags: xxx/abc:${{ env.TAG }}
          # 使用仓库根目录中的Dockerfile构建三个平台的镜像,并推送到xxx/abc仓库,使用之前获取的tag

提交编辑好的GitHub Action流程

点击右上角的Start commit,编辑好信息后点击Commit changes提交,该流程就创建好了。系统将在该仓库的release发布时自动运行流程,构建镜像并推送到DockerHub仓库中。

这里查看更多详细的GitHub Action用法。

跨平台运行容器

运行跨平台的docker容器需要qemu支持,在前面查看具体指令。

默认使用docker pull指令只会拉取和当前平台一致的镜像,要拉取其他平台的镜像,使用–platform指定对应的平台。

同样,在使用docker run运行容器时也需要使用–platform指定平台。

如果使用docker-compose来管理容器,需要在image的同级添加类似platform: linux/arm的指令来指定平台。如果本地已有相同tag的其他平台镜像,需要使用docker-compose pull来拉取需要平台的镜像

总结

总的来说,Docker这套跨平台镜像创建运行机制还是蛮方便的,对于我这种缺少设备的人来说简直是福音。

第一次用GitHub Action,感觉也是非常强,虽然需要编写配置文件这点比不上DockerHub直接指定仓库构建方便,但是相对复杂的配置带来了十分强大的功能,借助GitHub Action几乎可以做到任何想要做的事。

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇