作家
登录

理解Docker的多阶段镜像构建

作者: 来源: 2017-11-14 09:05:22 阅读 我要评论

# docker build -t myrepo/myhttpserver-alpine:latest -f Dockerfile.alpine . 
  • Sending build context to Docker daemon  6.151MB 
  • Step 1/5 : FROM alpine:latest 
  •  ---> 053cde6e8953 
  • Step 2/5 : COPY ./myhttpserver /root/myhttpserver 
  •  ---> ca0527a62d39 
  • Step 3/5 : RUN chmod +x /root/myhttpserver 
  •  ---> Running in 28d0a8a577b2 
  •  ---> a3833af97b5e 
  • Removing intermediate container 28d0a8a577b2 
  • Step 4/5 : WORKDIR /root 
  •  ---> 667345b78570 
  • Removing intermediate container fa59883e9fdb 
  • Step 5/5 : ENTRYPOINT /root/myhttpserver 
  •  ---> Running in adcb5b976ca3 
  •  ---> 582fa2aedc64 
  • Removing intermediate container adcb5b976ca3 
  • Successfully built 582fa2aedc64 
  • Successfully tagged myrepo/myhttpserver-alpine:latest 
  •  
  • # docker images 
  • REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE 
  • myrepo/myhttpserver-alpine   latest              582fa2aedc64        4 minutes ago       16.3MB 
  • 16.3MB,Size切实其实降下来了!我们基于该image启动一个容器,看竽暌功用运行是否有什愦问题:

    1. # docker run myrepo/myhttpserver-alpine:latest 
    2. standard_init_linux.go:185: exec user process caused "no such file or directory" 

    容器启动掉败了!为什么呢?因为alpine image并非ubuntu情况的同构image。我们鄙人面具体解释。

    二、异构的镜像构建

    我们的image builder: myrepo/golang-builder:latest是基于golang:latest这个image。 golang base image 有两个模板:Dockerfile-debain.template和Dockerfile-alpine.template。而golang:latest是基于debian模板的,与ubuntu兼容。构建出来的myhttpserver对动态共享链接库的情况如下:

    1. # ldd myhttpserver 
    2.     linux-vdso.so.1 =>  (0x00007ffd0c355000) 
    3.     libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ffa8b36f000) 
    4.     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffa8afa5000) 
    5.     /lib64/ld-linux-x86-64.so.2 (0x000055605ea5d000) 

    debian 系的linux distribution应用了glibc。但alpine则不合, alpine 应用的是 musl libc 的实现,是以当我们运行膳绫擎的那个容器时,加载器因找不到myhttpserver依附的libc.so.6而掉败退出。

    这种构建情况与运行情况不兼容的情况我这里称之为“异构的镜像构建”。那么若何解决这个问题呢?我们持续看:

    1、静态构建

    在主流编程说话中,Go的移植性已经是数一数二的了,尤其是Go 1.5之后,Go将runtime中的C代码都用Go重写了,对libc的依附已经降到最低了,但如有一些feature供给了两个版本的实现:C实现和Go实现。并且默认情况下,即在CGO_ENABLED=1的情况下,法度榜样和预编译的标准库都采取了C的实现。关于这方面的具体阐述请拜见我之前写的《也谈Go的可移植性》一文,这里就不赘述了。于是采取了不合libc实现的debian系和alpine系天然存在不兼容的情况。要解决这个问题,我们起首推敲对Go法度榜样进行静态构建,然后将静态构建后的Go应用放入alpine image中。


      推荐阅读

      Mobile Pwn2Own世界黑客大赛攻破iOS11,iPhone X被远程越狱

    Tech Neo技巧沙龙 | 11月25号,九州云/ZStack与您一路商量云时代收集界线治理实践 信赖会有越来越多的年青人参加到收集安然行业中来,以“没有收集安然就没有国度安然”为指导,>>>详细阅读


    本文标题:理解Docker的多阶段镜像构建

    地址:http://www.17bianji.com/lsqh/38807.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)