本文记录制作一个镜像的过程,先构建可运行静态程序的镜像,以此为基础,构建一个golang语言编写的web服务器,可获取容器的主机、内核版本等信息。该镜像可用于 k8s 和 KubeEdge 群集测试。

环境说明

安装docker,登陆到dockerhub。
安装golang编译器,用于编译源码。
安装 qemu,用于在 x86 平台上运行 arm 版本容器。如无此需求,可忽略。

sudo apt install qemu-user-static

基于manifest制作镜像,适用于 x86 和 arm 平台。
注意,这里说的 x86,实际是64位系统,应该称为amd64,说 x86 仅是习惯而已,非错误。但 arm 平台,是指 32 位系统,因笔者暂无 64 位系统,后续再完善。

镜像设计

如下:

latelee/busybox  这是对外使用的镜像名称,根据不同平台自动匹配下载
latelee/busybox-arm
latelee/busybox-amd64latelee/webgin
latelee/webgin-arm
latelee/webgin-amd64

基础镜像

官方busybox支持众多平台,但默认的版本没有一些依赖文件。但glibc版本有。
下面从实践角度描述如何制作。

制作x86平台基础镜像

下载:

docker pull busybox

制作如下:

运行:
docker run -itd --name busybox busybox
创建目录:
docker exec -it busybox mkdir -p /lib/x86_64-linux-gnu /lib64
拷贝运行库、链接器:
docker cp -a /lib/x86_64-linux-gnu/libpthread.so.0 busybox:/lib/x86_64-linux-gnu
docker cp -a /lib/x86_64-linux-gnu/libpthread-2.23.so busybox:/lib/x86_64-linux-gnu
docker cp -a /lib/x86_64-linux-gnu/libc-2.23.so  busybox:/lib/x86_64-linux-gnu
docker cp -a /lib/x86_64-linux-gnu/libc.so.6  busybox:/lib/x86_64-linux-gnu
docker cp -a /lib64/ld-linux-x86-64.so.2 busybox:/lib64/
docker cp -a /lib/x86_64-linux-gnu/ld-2.23.so busybox:/lib/x86_64-linux-gnu/保存为镜像
docker commit busybox latelee/busybox-amd64测试(预期结果有上述文件输出)
docker run -it --rm latelee/busybox-amd64 ls -lh /lib/x86_64-linux-gnu /lib64

提交:

docker push latelee/busybox-amd64

制作arm平台基础镜像

在一块安装了 docker 的 arm 板子上执行:

docker pull busybox

注:该命令与上述完全相同,因其系统不同,dockerhub自动匹配到合适的并下载。在真实机器上是为了确保镜像的可靠性。

制作如下:

运行:
docker run -itd --name busybox busybox
创建目录:
docker exec -it busybox mkdir -p /usr/lib/ /lib
拷贝运行库、链接器:
docker cp /lib/ld-2.25.so busybox:/lib/
docker cp /lib/ld-linux-armhf.so.3 busybox:/lib/
docker cp /usr/lib/libpthread-2.25.so busybox:/usr/lib
docker cp /usr/lib/libpthread.so.0 busybox:/usr/lib
docker cp /usr/lib/libc.so.6 busybox:/usr/lib/
docker cp /usr/lib/libc-2.25.so busybox:/usr/lib/保存为镜像
docker commit busybox latelee/busybox-arm测试(预期结果有上述文件输出)
docker run -it --rm latelee/busybox-arm ls -lh /usr/lib/ /lib

提交:

docker push latelee/busybox-arm

使用glibc版本

直接使用busybox:glibc版本制作,无法额外拷贝文件。在 x86 上执行:

docker pull busybox:glibc
docker tag busybox:glibc latelee/busybox-amd64

在 arm 上执行:

docker pull busybox:glibc
docker tag busybox:glibc latelee/busybox-arm

注:笔者使用前面小节的方法,glibc版本可能后续更新。

在 x86 上运行 arm 版本容器

有时不方便在 arm 板子上运行,则可以在 x86 上模拟之。
挂载 qemu-arm-static 文件:

docker run -it --rm -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static latelee/busybox-arm ls -lh /usr/lib/ /lib

另一方法,运行 qemu-user-static 容器,再运行 arm 容器:

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run -it --rm latelee/busybox-arm ls -lh /usr/lib/ /lib

多平台支持

技术要点:开启docker实验功能,预先提交不同平台的镜像到dockerhub上,创建manifest,推送。

export DOCKER_CLI_EXPERIMENTAL=enableddocker manifest create latelee/busybox latelee/busybox-amd64 latelee/busybox-armdocker manifest annotate latelee/busybox latelee/busybox-amd64 --os linux --arch amd64
docker manifest annotate latelee/busybox latelee/busybox-arm --os linux --arch arm查看:
docker manifest inspect latelee/busybox推送:
docker manifest push latelee/busybox

webgin

webgin 是指用 gin 框架编写的 web 服务,开放80端口,可输出主机信息。其构建方式与上述类似,不再赘述。webgin.go源码如下:

package mainimport ("fmt""runtime""os""time""github.com/gin-gonic/gin""net/http"
)// uname/*
#include <stdio.h>
#include <sys/utsname.h>char* GetName()
{arch := fmt.Sprintf("arch: %s os: %s hostname: %s\r\n", runtime.GOARCH, runtime.GOOS, hostname)struct utsname myname;static char buffer[128] = {0};uname(&myname);snprintf(buffer, 128, "uname: %s %s %s %s %s\r\n", myname.sysname, myname.nodename, myname.release, myname.version, myname.machine);return buffer;
}
*/
import "C"var version = "v1.0"func myIndex (c *gin.Context) {uname := C.GetName()name := C.GoString(uname)hostname, _ := os.Hostname()arch := "arch: " + runtime.GOARCH + " os: " + runtime.GOOS + " hostname: " + hostname + "\r\n";timeStr := "Now: " + time.Now().Format("2006-01-02 15:04:05") + "\r\n"c.String(http.StatusOK, "Hello World " + version + "\r\n" + arch + name + timeStr)
}func main(){router := gin.Default()router.GET("/", myIndex)fmt.Println("gin server start...")router.Run(":80")
}

构建脚本:

#!/bin/shexport GOARCH=amd64
export GOOS="linux"
export GOARM=
export CGO_ENABLED=1
export CC=gcc
GO111MODULE=off go build
strip webgin
docker build -t latelee/webgin-amd64 . -f Dockerfileexport GOARCH=arm
export GOOS="linux"
export GOARM=7
export CGO_ENABLED=1
export CC=arm-linux-gnueabihf-gcc
GO111MODULE=off go build
arm-linux-gnueabihf-strip webgin
docker build -t latelee/webgin-arm . -f Dockerfile.arm

dockerfile:

From latelee/busybox-amd64LABEL maintainer="Late Lee"COPY webgin /EXPOSE 80CMD ["/webgin"]

运行:

docker run -it --name webgin --rm -p 80:80 latelee/webgin

测试:

# curl localhost:80
Hello World v1.0
arch: amd64 os: linux hostname: 60acfd65857a
uname: Linux 60acfd65857a 4.4.0-174-generic #204-Ubuntu SMP Wed Jan 29 06:41:01 UTC 2020 x86_64
Now: 2020-03-26 23:10:36

依赖文件确认

缺少链接器:
/ # ./webgin
sh: ./webgin: not found
其它:
/ # /webgin
/webgin: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory/ # /webgin
/webgin: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

如果官方 dockerhub 速度慢,可选用阿里云容器镜像服务。其企业版本已于2020年3月中旬商业化,个人版不太清楚。
登陆阿里云仓库:sudo docker login --username=li@latelee.org registry.cn-hangzhou.aliyuncs.com
已完成版本:

registry.cn-hangzhou.aliyuncs.com/latelee/webgin  版本:v1.0 v1.1 v1.2
registry.cn-hangzhou.aliyuncs.com/latelee/busybox

我的docker随笔25:一个测试用的镜像制作过程相关推荐

  1. 一个简单购物网页的制作过程

    一.网页效果 1.登录(vip用户和普通会员) 选择vip和普通会员,最终的付款折扣会不同. 2.购物页面 文本框中输入要购买的数量 3.结账页面(购物操作的数量以1.2.3为例) 名字前面显示vip ...

  2. 记一个简单的Android计时器制作过程。

    刚学Handler,做一个计时器,就是秒表啦. 开始试图用Handler延迟发送消息来读秒,发现根本不现实,根本不会有准确的时间. 改成了比较当前时间和开始时间后成功计时. 没什么难度,就直接放源码啦 ...

  3. 一个针对小白的蘑菇制作过程(一)

    别的先不说,先放一张对比图 这是完成之后放入unity中的效果,shader用的是unity自带的基于物理渲染的standard,那么下面就说说制作的一个过程. 首先我们去百度找到这样一张图: 然后将 ...

  4. 一个针对小白的蘑菇制作过程(二)

    制作完成之后发现一些问题,低模的模型和高模匹配很差,于是从新制作了低模,这次是在ZB中利用zremsher进行减面从而得到低模.然后依然是在rizom中分UV 完成之后打开substance pain ...

  5. 系统制成docker镜像_docker镜像原理 镜像制作 dockerfile

    为什么一个centos镜像只有两百多兆,而tomcat镜像五百多兆 1.先说说操作系统 操作系统组成部分: 进程调度子系统 进程通信子系统 内存管理子系统 设备管理子系统 文件管理子系统 网络通信子系 ...

  6. Docker2 docker commit方法镜像制作

    一.前期准备 1.下载一个centos镜像,进入容器,安装wget docker pull centos docker run -it centos bash [root@web1 ~]# docke ...

  7. 我的docker随笔16:构建一个特定的nodejs镜像

    一.背景 某网友需要对区块链交易的项目进行测试.测试脚本需要在nodejs环境中运行,脚本有server.js.package.json,主要依赖包为web3(当然还是其它的).为方便测试,较好的解决 ...

  8. 从零开始搭建一个测试技术练习平台

    工作中,要不断学习,为了快速上手,我打算写一个有增删改查功能的Javaweb项目,方便以后练习各种测试技术. 环境准备 1.准备一台电脑 2.官网下载最新版Intellij IDEA,破解步骤找&qu ...

  9. 手撸架构,Docker 面试25问

    技术栈 传送门 JAVA 基础 手撸架构,Java基础面试100问_vincent-CSDN博客 JAVA 集合 手撸架构,JAVA集合面试60问_vincent-CSDN博客 JVM 虚拟机 手撸架 ...

最新文章

  1. 蚂蚁金服-支付风险识别亚军方案!
  2. URL概念及与URL的区别
  3. 配置windows 2008 作为远程访问SSL-×××服务器系列之二
  4. stmmac 中断处理
  5. @Test 运行 Method xxx should be void、Method xxx should have no parameters
  6. 互联网各岗位的生存指南
  7. 自然语言处理实践Task2
  8. linux的可执行文件通常放在哪个目录中?写出该目录的路径.,实验2 Linux的基本操作与 使用vi编辑器 2010 (1)...
  9. 单片机c语言编程RGB,C语言将raw data(rgb/rgba)写成bmp文件(bmp24或32)
  10. STM32工作笔记0031---基于STM32F103C8自己实现的跑马灯实验_使用STLINK调试
  11. iOS 用Swipe手势和动画实现循环播放图片
  12. python网址编码转换_python字符串与url编码的转换实例
  13. 简单的SQL语句 DDL
  14. 二极管主要特性及伏安特性曲线
  15. 微服务实践(总)-原文
  16. 淘宝R2去模糊化+聚石塔+奇门
  17. 【分层图最短路】P2939 [USACO09FEB]Revamping Trails G
  18. error the @annotation pointcut expression is only supported at Java 5 compliance level or above
  19. (简单)华为畅玩5C NEM-AL00的usb调试模式在哪里打开的教程
  20. h3c 链路聚合测试_H3C链路聚合

热门文章

  1. i2c时序图的详细讲解_外脚手架及外架防护棚搭设详细讲解,附做法图
  2. Google十大真理带给中国网络公司的启示
  3. 定时更换超级连接的代码
  4. 科学解释成功者成功的秘诀
  5. QQ音乐首发“无缝播放”新功能 音乐流媒体平台陆续上线
  6. 雷军接连退出多家小米关联公司董事职务
  7. realme下月将推Q3s:Q系列下半年独苗 配置更强更全面
  8. 由于两家重要零件厂商的疫情,iPhone 13备货可能受影响
  9. 荣耀50系列外观配置抢先看:售价成唯一悬念
  10. 4999元起!华为Mate 40今日开启预售:搭载麒麟9000E