4 min read

构建多架构容器镜像

构建多架构容器镜像

随着多硬件架构的出现和云平台的兴起,对多架构支持的需求变得至关重要。多架构容器支持不同架构无缝部署同一映像。以下为几种常见的构建方式:

多架构镜像构建流程

若要构建多架构容器镜像,大概需要遵循以下步骤:

  1. 创建 Dockerfile:首先需要创建单独的 Dockerfile。 Dockerfile 将定义用于生成容器映像的指令。
  2. 构建镜像:使用 Docker 的命令为每个体系结构构建镜像。例如,可以使用标志显式指定体系结构。build--platform
  3. 标记镜像:构建镜像后,使用相应的特定于平台的标记对其进行标记。这些标记通常包括体系结构名称,例如 AMD64、arm64 或 ppc64le。
  4. 推送镜像:将标记的映像推送到 Docker 注册表或您选择的任何其他容器注册表。确保注册表支持多体系结构清单列表。
  5. 创建清单列表:最后,创建一个清单列表,该列表引用不同的特定于平台的镜像。清单列表充当拉取和部署多体系结构容器的单个入口点。使用 podman 命令创建清单列表。 manifest create
  6. 推送清单列表:将清单列表推送到注册表,将其链接到每个体系结构的相应镜像。这可确保 Docker 根据目标平台拉取正确的镜像。

多架构镜像的优势

  • 可移植性:打包为多架构容器的应用程序可以在不同的硬件架构上无缝运行,从而更轻松地在平台或云提供商之间迁移。
  • 可扩展性:借助多架构支持,可以利用各种硬件架构,从而更加灵活地扩展应用程序。
  • 开发效率:可以跨各种架构同时构建、测试和分发应用程序,从而减少跨平台部署所需的时间和精力。
  • 面向未来:多架构容器使您的应用程序面向未来,确保它们能够在新架构出现时运行。

   

Podman

如果使用Podman,就比较简单了,3步曲:

创建镜像manifest

# podman manifest create <image name>

构建Amd64、Arm64平台架构双镜像

# podman build --platform linux/amd64,linux/arm64  --manifest <image name>  .

镜像推送

# podman manifest push <image name>

Docker buildx

docker buildx 这也是最为常见的一种容器架构方案,操作如下:

想要查看当前docker版本是否支持buildx,运行如下:

docker buildx version

为 Docker Buildx 创建新的构建器实例

docker buildx create --use --name builder

验证构建器实例是否已设置并可供使用

docker buildx inspect --bootstrap

示例:架构一个多平台的rsyncd容器镜像

创建 Dockerfile,内容如下:

# cat >Dockerfile<<EOF
#!/usr/bin/env -S docker build . -t rsyncd --file
FROM alpine:3.19
MAINTAINER Qiu Shuhui<shuhui@vqiu.cn>

RUN set -xe \
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    && apk update upgrade \
    && apk add --no-cache tzdata rsync \
    && cp -rf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && rm -rf /var/cache/apk/*

COPY ./docker-entrypoint.sh /entrypoint.sh

RUN mkdir -p /data

EXPOSE 873

ENTRYPOINT [ "/entrypoint.sh" ]

创建 docker-entrypoint.sh

#!/bin/sh

# 环境变量
VOLUME_NAME=${VOLUME_NAME:-vqiu}
PORT=${PORT:-873}
ALLOW=${ALLOW:-0.0.0.0/0}
OWNER=${OWNER:-root}
GROUP=${GROUP:-root}
VOLUME_PATH=${VOLUME_PATH:-/data}
READ_ONLY=${READ_ONLY:-true}
COMMENT=${COMMENT:-"docker rsyncd"}
MAX_CONNECTIONS=${MAX_CONNECTIONS:-20}
BWLIMIT=${BWLIMIT:-0}

# write password file
cat <<EOF > /etc/rsyncd.secrets
$RSYNC_USER:$RSYNC_PASS
EOF

# 分配凭证文件权限
chmod 0600 /etc/rsyncd.secrets

# 写入配置文件
cat <<EOF >> /etc/rsyncd.conf
port = ${PORT}
uid = ${OWNER}
gid = ${GROUP}
log file = /dev/stdout
pid file = /var/run/rsyncd.pid
max connections = ${MAX_CONNECTIONS}
use chroot = yes
strict modes = yes
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 600
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz
list = false
auth users = ${RSYNC_USER}
secrets file = /etc/rsyncd.secrets

[${VOLUME_NAME}]
path = ${VOLUME_PATH}
hosts allow = ${ALLOW}
hosts deny = *
read only = ${READ_ONLY}
comment = "${COMMENT}"
EOF

# 启动服务
echo "[-] 服务监听端口: [ ${PORT} ]"
echo "[-] 网络带宽限制: [ ${BWLIMIT} ]"
echo "[-] 服务模块名称: [ ${VOLUME_NAME} ]"
echo "[-] 允许访问地址: [ ${ALLOW} ]"
echo "[-] 是否只读模式: [ ${READ_ONLY} ]"

OPTS="--no-detach --daemon --config /etc/rsyncd.conf --bwlimit=${BWLIMIT}"

/usr/bin/rsync ${OPTS}

使用以上Dockerfile,创建一个rsyncd双架构容器

# docker buildx create --use --name builder
# docker buildx build --platform linux/amd64,linux/arm64 --output "type=image,push=true"--tag registry.vqiu.top/docker-rsyncd:latest  --builder builder .
# docker buildx stop builder

其它

复制多架构镜像

我们有时候需要将hub.docker上面的多架构容器镜像到内网的私有镜像仓库中

# skopeo  copy --multi-arch=all docker://<镜像名> docker://<私有镜像地址>

咳咳咳,上年纪了,记性不佳,纯为个人笔记。