首页 > 其他分享 >Docker基础知识 (28) - 在 Dockerfile 中以 scratch 为基础镜像 (FROM scratch)

Docker基础知识 (28) - 在 Dockerfile 中以 scratch 为基础镜像 (FROM scratch)

时间:2023-03-15 18:22:33浏览次数:44  
标签:中以 1.0 scratch 28 debian 镜像 docker hello

  通常使用 Docker 镜像时会以一个已存在的镜像为基础,在其上进行定制,这个已存在的镜像就是基础镜像。
在 DockerFile 中必须指定基础镜像,FROM 指令就是用于指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。在 Dockerfile 中以 scratch 为基础镜像 (FROM scratch),意味着不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 FROM scratch 会让镜像体积更加小巧。使用 Go 语言开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。

 

1. 创建基于静态编译的 C 程序镜像

    1) C 程序
        $ cd ~/gcc         $ vim hello.c
            #include <stdio.h>
           
            int main() {
                puts("Hello World!- C");
                return 0;
            }

  

        # gcc 静态编译         $ gcc hello.c -static -o hello
        $ ./hello
            Hello World! - C
        $ ll -h hello
            -rwxrwxr-x 1 root root   852K  hello
    2) 创建 Dockerfile
        $ cd ~/gcc         $ vim Dockerfile
            FROM scratch             COPY hello /             CMD ["/hello"]
        注:scratch 空镜像中没有 sh 或 bash,无法 mkdir、mv 等 shell 命令是无效的,因此需要在镜像外部把文件目录结构建立好,然后通过 ADD 或 COPY 命令拷贝到容器内。
    3) 创建 hello 镜像,并运行容器
        $ cd ~/gcc
        # 创建镜像         $ docker build -t hello:1.0 .
            Step 1/3 : FROM scratch
            --->
            Step 2/3 : COPY hello /
            ---> bb893abeef08
            Step 3/3 : CMD ["/hello"]
            ---> Running in c31e62693472
            Removing intermediate container c31e62693472
            ---> cebea71dcbe0
            Successfully built cebea71dcbe0
            Successfully tagged hello:1.0

        $ docker images


            REPOSITORY      TAG      IMAGE ID       CREATED          SIZE             hello           1.0      cebea71dcbe0   38 seconds ago   872kB
        $ docker run --rm hello:1.0
            Hello World!- C
    注:以上 Dockerfile 制作出来的镜像是 872kB,hello 的二进制文件是 852kB。使用 scratch 空镜像的本质是让程序只调用 host 主机的 Linux 内核部分的功能,而不依赖容器内的操作环境功能。host 主机的 Linux 内核部分对 Docker 容器是共享的,因此其 scratch 空镜像的大小可以认为近似为 0。

 

2. 创建基于编译的 Go 程序镜像

    1) Go 程序
        $ cd ~/go         $ vim test.go
            package main

            import "fmt"

            func main() {
                fmt.Println("Hello world - Go")
            }

 

        # 编译

        $ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' test.go
            参数说明:
                GOOS=linux GOARCH=amd64 表示确保编译出来的程序可以运行在 amd64 linux 环境;                 CGO_ENABLED=0 表示确保用到的 C 函数库包含到 Go run-time 中,程序运行时以静态方式内部调用。否则,由于 scratch 空镜像内没有 C 函数库,Go 程序动态调用时会出错;                 -ldflags '-w -s' 表示排除 Debug 信息,让编译出来的程序更小。-w 是排除 DWARF,-s 是排除 debug symbol;
            注:Go 语言调用 C 函数库出错的现象也会出现在 alpine 中,这是因为 alpine 的 C 函数库是精简版的。
        $ ./test
            Hello world - Go
        $ ll -h test
            -rwxrwxr-x 1 root root  1.2M  test
    2) 创建 Dockerfile
        $ cd ~/go         $ vim Dockerfile
            FROM scratch             COPY test /             CMD ["/test"]
    3) 创建 test 镜像,并运行容器
        $ cd ~/go
        # 创建镜像         $ docker build -t test:1.0 .
            Step 1/3 : FROM scratch
            --->
            Step 2/3 : COPY test /
            ---> cd67f4bfb544
            Step 3/3 : CMD ["/test"]
            ---> Running in c3cf81ea01e4
            Removing intermediate container c3cf81ea01e4
            ---> 535665c081c8
            Successfully built 535665c081c8
            Successfully tagged test:1.0

 

        $ docker images


            REPOSITORY      TAG      IMAGE ID       CREATED          SIZE             test            1.0      535665c081c8   29 seconds ago   1.18MB
        $ docker run --rm test:1.0
            Hello world - Go

 

3. 创建基于 Debian rootfs 的 Linux 镜像  

    由于 scratch 空镜像内,没有操作系统的根文件系统(rootfs),无法运行 sh 或 bash,无法进入容器内进行交互式调试。我们可以给基于 scratch 空镜像创建的镜像里,添加一个 rootfs。
    Docker Debain: https://docker.debian.net/     Docker Debain GitHub: https://github.com/debuerreotype/docker-debian-artifacts
    1)下载 rootfs                 这里选用了 https://docker.debian.net/ 页面上的 debian:bookworm-20230227,amd64 链接跳转到页面 https://github.com/debuerreotype/docker-debian-artifacts/tree/fe5738569aad49a97cf73183a8a6b2732fe57840/bookworm。
        下载 rootfs.tar.xz 文件到 ~/debian 目录下,文件大小 29.66MB。
    2) 创建 Dockerfile
        $ cd ~/debian         $ vim Dockerfile
            FROM scratch
            Add rootfs.tar.xz /
            WORKDIR /home/docker
            CMD /bin/bash

 

     3) 创建 Linux 镜像,并运行容器
        $ cd ~/debian
        # 创建镜像         $ docker build -t debian_local:1.0 .
            Step 1/4 : FROM scratch
            --->
            Step 2/4 : Add rootfs.tar.xz /
            ---> 806b049c2199
            Step 3/4 : WORKDIR /home/docker
            ---> Running in e4c0defe9fd3
            Removing intermediate container e4c0defe9fd3
            ---> a2bea1387c68
            Step 4/4 : CMD /bin/bash
            ---> Running in ea20508cb334
            Removing intermediate container ea20508cb334
            ---> fd4fa7caba5d
            Successfully built fd4fa7caba5d
            Successfully tagged debian_local:1.0

 

         $ docker images
            REPOSITORY      TAG      IMAGE ID       CREATED          SIZE             debian_local    1.0      fd4fa7caba5d   38 seconds ago   116MB
        $ docker run -itd --name debian-local-1.0 debian_local:1.0  
            0e6e3704225c5723349e8d1cc07fefefdf93d205cdabc6f938f3726482b0d918
        $ docker exec -it debian-local-1.0 /bin/bash
            root@0e6e3704225c:/home/docker# cd /
            root@0e6e3704225c:/# ls
            bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

            root@0e6e3704225c:/# cat /etc/issue
            Debian GNU/Linux bookworm/sid \n \l

 

标签:中以,1.0,scratch,28,debian,镜像,docker,hello
From: https://www.cnblogs.com/tkuang/p/17219527.html

相关文章

  • CVE-2023-22809 Sudoedit提权漏洞分析
    TRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChineseSimplifiedHungarianRussianC......
  • 2816. 判断子序列(双指针模板题)
    https://www.acwing.com/problem/content/2818/双指针模板题:i指针只有匹配到相等才++,j指针无论如何每次都++那么i==n时,意味着b序列中存在着a序列,且有序离散存放#inclu......
  • 最新HCL AppScan Standard 10.1.028223 安装及 许可证注册
    最新HCLAppScanStandard10.1.028223安装及许可证注册参考原文:《最新HCLAppScanStandard10.1.028223》1、软件介绍1.1、旧版界面1.2、新版本界面1.3:介绍HCLAppS......
  • PAT Basic 1028. 人口普查
    PATBasic1028.人口普查1.题目描述:某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。这里确保每个输入的日期都是合法的,但不一......
  • P7728 旧神归来 题解
    日常生活:写多项式——写多项式题解——颓——写多项式——写多项式题解——颓——……最近真的降智。大水题切不动。#查询gtm1514精神状态题解好像挺清新的。首先我......
  • P1075 [NOIP2012 普及组] 质因数分解 提交 333.88k 通过 126.26k 时间限制 1.00s 内存
    P1075[NOIP2012普及组]质因数分解[NOIP2012普及组]质因数分解题目描述已知正整数n是两个不同的质数的乘积,试求出两者中较大的那个质数。输入格式输入一个正整......
  • 第128篇:浏览器存储(cookie、webStorage、 IndexedDB)
    好家伙,本篇为《JS高级程序设计》第二五章“浏览器存储”学习笔记 我们先来讲个故事一个“薅羊毛”的故事(qq.com)概括一下,就是有个人通过网络平台非法购买了大量“c......
  • 【教学典型案例】28.生产环境nginx限制上传大小
    目录​​一:背景介绍​​​​二:Nginx限制上传大小​​​​1、Nginx官方文档说明​​​​2、设置参数​​​​1)、在server模块中设置​​​​2)、在http模块中设置​​​​三:问......
  • 洛谷-2822
    洛谷-2652key思路有个modk的想法很好,然后就是对于一遍一遍的询问进行前缀和优化,但有个问题就是算出来的s矩阵最开始是个下三角矩阵,但是根据前缀和公式来看,s[i][j]上方......
  • 利民发布 HR-10 2280 M.2 SSD 散热器,搭载双 AGHP 逆重力热管
    3月10日消息,利民现已发布新款HR-102280M.2SSD散热器,售价79元。据官方介绍,Thermalright利民HR-102280散热器采用了高质感电镀回流焊技术,采用大面积散热片,内......