关于docker的scratch镜像与helloworld

参考:https://hub.docker.com/_/scratch?tab=description

参考:https://segmentfault.com/a/1190000000628247

FROM scratch

官方说明:该镜像是一个空的镜像,可以用于构建busybox等超小镜像,可以说是真正的从零开始构建属于自己的镜像。要知道,一个官方的ubuntu镜像有60MB+,CentOS镜像有70MB+

可以把一个可执行文件扔进来直接执行

一、注意:scratch不可用被pull

FROM scratch专门用于构建最小镜像,直接pull会报以下错误,scratch是一个保留名称

[root@es-master1 ~]# docker pull scratch
Using default tag: latest
Error response from daemon: 'scratch' is a reserved name

二、如何制作大小为0 的镜像

既然scratch不能被拉取,如何做到docker image ls看到一个0字节的镜像

官方给出了下面方法:

$ tar cv --files-from /dev/null | docker import - scratch
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
scratch latest 775bfce21429 9 minutes ago 0B

三、如何跑一个helloworld

可以参考:https://github.com/docker-library/hello-world/

3.1C语言不行,docker是go语言写的,跑的话报错

[root@es-master1 ~]# cat hello.c
#include <stdio.h> main() {
printf("hello world\n");
}
[root@es-master1 ~]# gcc hello.c -o hello
[root@es-master1 ~]# ll hello
-rwxr-xr-x 1 root root 8440 Nov 21 03:36 hello

Dockerfile

FROM scratch
COPY hello /
CMD ["/hello"]
[root@es-master1 ~]# docker build -t hello .
[root@es-master1 ~]# docker image ls hello
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 3b89b5056a03 5 minutes ago 8.44kB

果然报错

[root@es-master1 ~]# docker run --rm hello
standard_init_linux.go:211: exec user process caused "no such file or directory"

ubuntu当然可以

[root@es-master1 ~]# cat Dockerfile
FROM ubuntu
COPY hello /
CMD ["/hello"]
[root@es-master1 ~]# docker build -t hello .
Sending build context to Docker daemon 24.63MB
Step 1/3 : FROM ubuntu
---> 775349758637
Step 2/3 : COPY hello /
---> 33de2082f11a
Step 3/3 : CMD ["/hello"]
---> Running in 3d347f62b926
Removing intermediate container 3d347f62b926
---> 1829a7bd40fe
Successfully built 1829a7bd40fe
Successfully tagged hello:latest
[root@es-master1 ~]# docker run --rm hello
hello world

官方的这个竟然有点看不懂了,c语言:https://github.com/docker-library/hello-world

[root@es-master1 tmp]# git clone https://github.com/docker-library/hello-world.git
[root@es-master1 tmp]# cd hello-world/
[root@es-master1 hello-world]# make all
[root@es-master1 hello-world]# amd64/hello-world/hello Hello from Docker!
......

3.2go语言

使用go语言写:https://github.com/adriaandejonge/helloworld

[root@es-master1 hello-world]# tree -C .
.
├── Dockerfile
└── hello.go
0 directories, 2 files
[root@es-master1 hello-world]# cat hello.go
package main
import "fmt" func main(){
fmt.Printf("hello world\n")
}
[root@es-master1 hello-world]# cat Dockerfile
FROM google/golang as builder
WORKDIR /go/src/app
COPY hello.go .
RUN go build hello.go FROM scratch
COPY --from=builder /go/src/app/hello /
CMD ["/hello"]

一个helloworld都这么大...

[root@es-master1 hello-world]# docker build -t hello .
[root@es-master1 hello-world]# docker image ls hello
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 27eca431407a 2 minutes ago 2.36MB
[root@es-master1 hello-world]# docker run --rm hello
hello world
[root@es-master1 hello-world]# docker image history hello
IMAGE CREATED CREATED BY SIZE COMMENT
27eca431407a 3 minutes ago /bin/sh -c #(nop) CMD ["/hello"] 0B
1a35249e8575 3 minutes ago /bin/sh -c #(nop) COPY file:7b1994197d7b5310… 2.36MB

也没用过go,网上了解到加个选项就能变小:https://www.jianshu.com/p/1405b0c2c5a3

[root@es-master1 hello-world]# cat Dockerfile
FROM google/golang as builder
WORKDIR /go/src/app
COPY hello.go .
RUN go build -ldflags="-w -s" hello.go FROM scratch
COPY --from=builder /go/src/app/hello /
CMD ["/hello"]
[root@es-master1 hello-world]# docker build -t hello .
[root@es-master1 hello-world]# docker image ls hello
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest df8b3c8897f9 8 seconds ago 1.65MB

3.3改写官方的helloword

hello.c

[root@es-master1 ~]# cat hello.c
//#include <unistd.h>
#include <sys/syscall.h> #ifndef DOCKER_GREETING
#define DOCKER_GREETING "Hello from Docker!"
#endif const char message[] =
DOCKER_GREETING "\n"; void _start() {
//write(1, message, sizeof(message) - 1);
syscall(SYS_write, 1, message, sizeof(message) - 1); //_exit(0);
syscall(SYS_exit, 0);
}

编译

[root@es-master1 ~]# gcc -static -Os -nostartfiles -fno-asynchronous-unwind-tables -o './hello'  'hello.c'
[root@es-master1 ~]# strip -R .comment -s 'hello'
[root@es-master1 ~]# ./hello
Hello from Docker!

dockerfile

FROM scratch
COPY hello /
CMD ["/hello"]
[root@es-master1 ~]# docker build -t hello .
#才1.06kB
[root@es-master1 ~]# docker image ls hello
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 3b204a40c8cb 14 seconds ago 1.06kB
[root@es-master1 ~]# docker run --rm hello
Hello from Docker!

四、补充

  • gcc -D可以定义宏,起到替换、条件编译的功能;即hello.c中定义了一个宏,我可以在gcc编译时使用-D替换该宏。就好像我docker镜像定义了一些变量,但是docker run仍可以-e传递变量,覆盖原有的变量
  • gcc -static指定强制使用静态库,
  • -O 对程序进行优化编译、链接。采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是编译、链接的速度就相应地要慢一些,而且对执行文件的调试会产生一定的影响,造成一些执行效果与对应源文件代码不一致等一些令人“困惑”的情况。因此,一般在编译输出软件发行版时使用此选项
  • -Os 使用了所有-O2的优化选项,但又不缩减代码尺寸的方法 https://www.cnblogs.com/luolizhi/p/5737091.html
  • -nostartfiles 连接的使用不使用标准系统库。只有你指定的库才能够传递给连接器。不链接系统标准启动文件,而标准库文件仍然正常使用
  • -fno-asynchronous-unwind-tables 用来不生成CFI指令
  • -o 输出文件名
  • stribe 给文件脱裤子。具体就是从特定文件中剥掉一些符号信息调试信息。 在strip之后, 文件变小了, 仍然可以执行, 这就就节省了很多空间。

最新文章

  1. Struts2中跳转问题
  2. HTTP状态管理机制之Cookie
  3. 【转】【UML】使用Visual Studio 2010 Team System中的架构师工具(设计与建模)
  4. 使用UILocalizedIndexedCollation实现区域索引排序 及 不显示没有数据的区域
  5. HW4.15
  6. Unity 单元测试(NUnit,UnityTestTools)
  7. java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException
  8. Android工程师面试准备知识点
  9. css 水平居中的办法
  10. canvas图形编辑器
  11. POJ 2828 Buy Tickets(单点更新) 详细题解和思路
  12. BCGcontrolBar(八) Ribbon图标变换
  13. linux 信号处理 三 (信号集的使用)
  14. CSS深入理解之absolute(HTML/CSS)
  15. linux java jdk环境变量设置之后,依旧提示 No such file or directory
  16. javamail模拟邮箱功能--邮件回复-中级实战篇【邮件回复方法】(javamail API电子邮件实例)
  17. Oracle数据库创建表ID字段的自动递增
  18. SPI子系统分析之四:驱动模块
  19. bzoj2326:[HNOI2011]数学作业(分段矩阵乘法)
  20. Js文件中调用其它Js函数的方法

热门文章

  1. 函数式编程:面向monad和pipeline编程
  2. [HTTP趣谈]origin,referer和host区别
  3. OpenCV 学习笔记(7)vs2015+ffmpeg开发环境配置
  4. 关于读取Com口数据时,Com口的名字的两种读法。
  5. Nagios HTTP WARNING: HTTP/1.1 403 Forbidden
  6. OpenFOAM——圆柱绕流对流换热
  7. Spring Transaction 使用入门
  8. 责任链模式(chainOfResponsibility)
  9. [Beta阶段]第七次Scrum Meeting
  10. java 注解,动态代理