Ken的杂谈
  • Ken的杂谈 (current)
  • 关于
  • 杂谈
    Java Spring Spring Boot Spring Cloud MyBatis C# .NET Core .NET ASP.NET Core ASP.NET ClassLibrary Mono 数据库 MySQL SQL Server 网络 缓存 Web Linux CentOS Ubuntu macOS Windows openEuler Nginx ServiceStack JS/JQ 正则 工具 IDE Grafana Exceptions CI/CD Solution 微服务 Arch Docker 杂谈
  • 系列
    Java 快速入门系列教程 Spring Boot 入门教程 Spring Boot 2.x 入门教程 Spring Cloud 入门教程 .NET Core 快速入门教程 ASP.NET Core 2.1 入门教程 CentOS 7 快速上手教程 Ubuntu快速上手入门教程 Hyper-V基础教程 Docker入门教程
  • GitHub

Docker入门:构建支持多系统架构的Docker镜像

Docker @ 2023-05-12 22:33:35 · 阅读:(5475)

一、前言

1、本文主要内容

使用Docker Buildx构建支持AMD64、ARM、ARM64等架构的镜像并传到到Docker Hub

2、本文环境信息

环境 说明
Docker Docker CE 23.0.5
Docker Desktop 4.19
Docker Buildx 0.10.4
Docker Golang镜像 1.20
Golang 1.20
Windows Windows 11
curl for Windows 7.87

3、前置知识

Docker入门:使用Dockerfile构建Docker镜像
https://ken.io/note/docker-image-build-with-dockerfile

二、镜像制作准备

创建镜像制作根目录,例如:d:\docker\helloworld(Windows),~/docker/helloworld(macOS),后续所有文件都放在该目录中

1、准备应用代码

用golang写的一个简单http server,监听8000端口,默认输出helloworld,并返回操作系统、HostName以及IP地址信息
新建helloworld.go保存以下代码

package main

import (
    "fmt"
    "log"
    "net"
    "net/http"
    "os"
    "runtime"
    "strings"
)

func getHostName() string {
    hostname, err := os.Hostname()
    if err != nil {
        log.Fatalf("Failed to open log file: %v", err)
    }
    return hostname
}

func getIpAddresses() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        log.Fatal(err)
        return ""
    }
    var ips []string
    for _, address := range addrs {
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                ips = append(ips, ipnet.IP.String())
            }
        }
    }
    return strings.Join(ips, ",")
}

func handler(w http.ResponseWriter, r *http.Request) {
    log.Println("received request from", r.RemoteAddr, r.URL.Path[1:])
    var welcome = r.URL.Path[1:]
    if len(welcome) == 0 {
        welcome = "World"
    }
    fmt.Fprintf(w, "Hello, %s!  ---ken.io \r\n", welcome)
    fmt.Fprintf(w, "OS:%s/%s,Host:%s,IP:%s\r\n", runtime.GOOS, runtime.GOARCH, getHostName(), getIpAddresses())
}

func main() {
    http.HandleFunc("/", handler)
    log.Println("starting server on port 8000")
    log.Fatal(http.ListenAndServe(":8000", nil))
}

2、编写Dockerfile文件

Dockerfile 是用于Docker镜像的文本文件(默认无后缀名),包含所有我们需要用于创建Docker镜像的命令,例如:指定基础镜像、安装依赖的软件、配置环境变量、添加文件和目录、定义容器启动时运行的命令等
新建helloworld.build并保存以下内容

# 使用官方提供的 Go 镜像作为基础镜像
FROM golang:1.20

# 将工作目录设置为 /app
WORKDIR /app

# 将helloworld.go复制到 /app 下
COPY helloworld.go /app

# 设置go mod 镜像
RUN go env -w GO111MODULE=on
RUN go env -w  GOPROXY=https://goproxy.cn,direct

# 导入依赖的Redis go module
RUN go mod init helloworld

# 允许宿主机访问容器的 8000 端口
EXPOSE 8000

# 设置容器进程为:go run helloworld.go
CMD go run helloworld.go

三、镜像制作

1、确认BaseImage支持架构

以Golang的官方镜像镜像为例,我们可以在找到指定版本,查看支持的系统架构
Docker Build

2、登录账号

访问 https://hub.docker.com/signup 注册账号,然后在Docker Desktop登录账号,或者通过命令登录

# 登录命令
docker login

# 根据命令号交互输入注册时的账号密码即可成功登录
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: kentalk
Password:
Login Succeeded

Logging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/

3、构建镜像

Docker从19.03版本提供了构建工具Buildx,可以通过—platform参数指定构建的目标平台,例如:linux/amd64、linux/arm64或、darwin/amd64等等,通过Buildx可以连接面向不同架构的Docker节点分别构建,也可以直接将构建信息推送到Docker Hub,这里选择后者,毕竟不需要准备面向不同架构的Docker节点,更省事儿

# 进入目录
d: && cd d:\docker\helloworld

# 查看Buildx版本(确认buildx已启用,如未启用,使用docker buildx install安装)
docker buildx version

# 构建镜像(默认为latest)(注意结尾一定要加.)
# 这里选择构建常见的linux/amd64,linux/arm64 架构,如需其他的可以自行追加
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f helloworld.build   \
-t kentalk/helloworld --push .

4、查看构建结果

访问 https://hub.docker.com/r/kentalk/helloworld/tags 查看构建的结果
Docker Build

5、镜像测试

# 拉取镜像
docker pull kentalk/helloworld

# 启动容器
docker run --name myhello -p 8000:8000 -d kentalk/helloworld

# 访问测试
curl localhost:8000

# 输出示例
Hello, World!  ---ken.io 
OS:linux/arm64,Host:3426a278c72e,IP:172.17.0.3

6、查看镜像信息

docker buildx imagetools inspect kentalk/helloworld

# 输出示例

*****************省略部分内容******************
Manifests:
  Name:        docker.io/kentalk/helloworld:latest@sha256:e84a3c9b0ebfa61af984594dedfbaaba092fa592e0e881f62fe7999f17e44b53
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/amd64

  Name:        docker.io/kentalk/helloworld:latest@sha256:df49a99b6f5ddbcd5e79826c5cd1086cb5edff4601be35c8f4358616f0e2d749
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/arm64
*****************省略部分内容******************

备注

1、相关阅读

  • https://docs.docker.com/build/building/multi-platform/
  • https://docs.docker.com/engine/reference/commandline/buildx/
  • https://docs.docker.com/engine/reference/commandline/buildx_build/

Ken的杂谈

本文由 ken.io 创作,采用CC BY 3.0 CN协议 进行许可。 可自由转载、引用、甚至修改,但需署名作者且注明出处。

Docker

随笔目录


    © Copyright 2012-2025 Ken的杂谈

    豫ICP备10025012号

    ASP.NET Core(6.0) on Linux