關於docker的scratch鏡像與helloworld

關於docker的scratch鏡像與helloworld

參考:https://hub.docker.com/_/scratch?tab=descriptionhtml

參考:https://segmentfault.com/a/1190000000628247linux

FROM scratchgit

官方說明:該鏡像是一個空的鏡像,能夠用於構建busybox等超小鏡像,能夠說是真正的從零開始構建屬於本身的鏡像。要知道,一個官方的ubuntu鏡像有60MB+,CentOS鏡像有70MB+github

能夠把一個可執行文件扔進來直接執行golang

1、注意:scratch不可用被pull

FROM scratch專門用於構建最小鏡像,直接pull會報如下錯誤,scratch是一個保留名稱docker

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

2、如何製做大小爲0 的鏡像

既然scratch不能被拉取,如何作到docker image ls看到一個0字節的鏡像ubuntu

官方給出了下面方法:segmentfault

$ 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

3、如何跑一個helloworld

能夠參考:https://github.com/docker-library/hello-world/bash

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

Dockerfileapp

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!

4、補充

  • 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以後, 文件變小了, 仍然能夠執行, 這就就節省了不少空間。
相關文章
相關標籤/搜索