一.Dockerfile合理分层

Dockerfile的写法不合理,有时候会导致镜像膨胀,由于Docker是分层设计,而在Dockerfile中,每一条指令都拥有自己的context,而执行到下一条指令时,则会将下一层的构建层叠加到上一层上。因此,假如你在上一层指令做了一些包下载操作安装操作,然后在下一层再做清理,其实没什么用,只能说明你下一层引入的diff是0而已。

可以实验一下:

对照组A:下载清理操作全在同一层

FROM centos
MAINTAINER ** RUN yum -y update
RUN yum -y install wget RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.tar.gz" -O /tmp/jdk8_x64.tar.gz && gunzip /tmp/jdk8_x64.tar.gz && tar -C /opt -xf /tmp/jdk8_x64.tar && ln -s /opt/jdk1..0_121 /opt/jdk && yum clean all && rm -fr /tmp/*

对照组B:下载清理操作放在不同层

FROM centos
MAINTAINER ** RUN yum -y update
RUN yum -y install wget RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-linux-x64.tar.gz" -O /tmp/jdk8_x64.tar.gz && gunzip /tmp/jdk8_x64.tar.gz && tar -C /opt -xf /tmp/jdk8_x64.tar && ln -s /opt/jdk1..0_121 /opt/jdk
RUN yum clean all
RUN rm -fr /tmp/*

分别执行构建操作,得到的镜像差异很大,其中test1为对照组A的构建结果,test2为对照组B的构建结果,两者相差400M.

alex@ubuntu:~/workspace/docker_project$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test2 latest a65c6cced43b minutes ago 1.1 GB
test1 latest 67897397b053 minutes ago MB

二.CMD跟ENTRYPOINT的合理使用

举个例子,假设你需要容器启动时,去执行一个后台常驻脚本,那我们一般想到的是在CMD中执行脚本即可。

假设对照组A的Dockerfile:

FROM centos
MAINTAINER ** EXPOSE
WORKDIR / CMD [ "/bin/bash","-c","/usr/bin/python2.7 -m SimpleHTTPServer" ]

那正常镜像构建成功后,启动容器

alex@ubuntu:~/test$ docker build -t test1 .
Sending build context to Docker daemon 2.048 kB
Step / : FROM centos
---> 98d35105a391
Step / : MAINTAINER shufeng, shufeng.lsf@alibaba-inc.com
---> Using cache
---> 054ed64f1b34
Step / : EXPOSE
---> Running in e706b62c3c16
---> f1fd512940dc
Removing intermediate container e706b62c3c16
Step / : WORKDIR /
---> daa58d7899df
Removing intermediate container 5c51961e6e87
Step / : CMD /bin/bash -c /usr/bin/python2. -m SimpleHTTPServer
---> Running in 5dfa9742ccaf
---> 6ff71edb9bad
Removing intermediate container 5dfa9742ccaf
Successfully built 6ff71edb9bad

启动容器:

alex@ubuntu:~/test$ docker run -it -d -p : 6ff71edb9bad
a4318a775ec005473f6bc9342cd3c14b55981b334cc6160e7ea17e802f6eff15

查看一下映射情况

可以发现映射成功了。但这样启动有适合什么情况呢,只适合后台启动的情况,让我们试试另一种启动容器的方式

alex@ubuntu:~/test$ docker run -it -d -p : 6ff71edb9bad /bin/bash
0fdaf33f00fb9307394e4b91577af026627801ab6364ef6729aaf9754eb84455
alex@ubuntu:~/test$
alex@ubuntu:~/test$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.

可以发现当我需要在容器启动后进入命令行时,/bin/bash的操作直接将CMD的指令覆盖了。因此,这时候需要用ENTRYPOINT来代替CMD,对应的Dockerfile如下。

FROM centos
MAINTAINER ** EXPOSE
WORKDIR /
ENTRYPOINT ["/bin/bash","-c","/usr/bin/python2.7 -m SimpleHTTPServer"]

在这里说下CMD跟ENTRYPOINT的区别。

docker run命令行可以覆盖CMD指令,而ENTRYPOINT则不会,此外,可以通过docker run在命令行中指定的参数,来传递给ENTRYPOINT指令中指定的命令,这样就可以达到动态执行的效果。

Docker镜像压缩的更多相关文章

  1. 玩转docker镜像和镜像构建

    摘要 本文从个人的角度,讲述对于docker镜像和镜像构建的一些实践经验.主要内容包括利用docker hub进行在线编译,下载镜像,dind的实践,对于镜像的一些思考等.本文是对当时微信分享内容的一 ...

  2. 记一次,Docker镜像1G多精简至300+M的过程

    记一次,Docker镜像1G多精简至300+M的过程 一.业务场景描述 二.Docker时区不一致,相差8小时 三.通过Docker发布的服务上传文件上传不上去 四.上传的图片带水印,水印中包含的字体 ...

  3. 理解Docker(2):Docker 镜像

    本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  4. [P4基础]p4app的Docker镜像仓使用详解

    How to use the p4lang/p4app Docker image 本文参考 孙勇峰博客 和 p4app README 以及 p4app Dockerfile 结合自己的理解做一些记录, ...

  5. docker镜像保存及导出(save,export)

    前言:有时自己的做好的docker镜像,想将这个docker容器弄到其他服务器上去运行:或者已经运行的容器,将其弄导出,运行到其他地方进行测试 1.查看要要保存的镜像的ID docker  image ...

  6. 004.Docker镜像管理

    一 镜像基本操作 镜像是一个包含程序运行必要依赖环境和代码的只读文件,其本质是磁盘上一系列文件的集合.它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 1 ...

  7. docker镜像基本操作一

    获取镜像 首先说明一下如何从Docker hub中获取高质量的镜像,从Docker镜像库获取镜像的命令是docker pull .其命令格式为: docker pull [选项] [Docker Re ...

  8. Docker for Windows(三)Docker镜像与容器的区别&常用命令

    Docker镜像(Image)是一堆只读文件(read-only layer),容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是 ...

  9. Docker镜像构建(五)

    Docker 镜像介绍 Docker镜像构建分为两种,一种是手动构建,另一种是Dockerfile(自动构建) 手动构建docker镜像 案例:我们基于centos镜像进行构建,制作自己的nginx镜 ...

随机推荐

  1. JS中函数参数和函数返回值的理解

    函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能 ...

  2. iOS arc下控制某一文件为非arc

    选中文件加上编译参数 -fno-objc-arc即可.

  3. rips中如何使用PHP虚拟机自带函数--token_get_all

    这两天在看rips源码,发现,它在审计php代码时调用了php虚拟机自带的token_get_all此函数. 这一函数会将php源码按照内置的规则进行归纳,并输出成数组格式. 如: <?php ...

  4. 【PHP系列】PHP推荐标准之PSR-3,日志记录器接口

    上节聊完了PHP官方的相关代码规范,下面给大家带来了PHP系列的PHP推荐标准的另外两个,PSR-3,PSR-4. 首先,我们先来了解下PSR-3是怎么回事. PHP-FIG发布的第三个推荐规范与前两 ...

  5. Angular2 路由问题修复 、求解

    Angular2 提供了比angular1 更为强大的路由功能,但是在具体使用路由过程中,可是出现了很多路由不按照预想的方式执行的问题.为了说明今天的问题,我特地新建了一个测试工程.欢迎交流. 首先介 ...

  6. 获取博客积分排名,存入数据库,读取数据进行绘图(python,selenium,matplotlib)

    该脚本的目的:获取博客的排名和积分,将抓取时间,排名,积分存入数据库,然后把最近的积分和排名信息进行绘图,查看积分或者排名的变化情况. 整个脚本的流程:是利用python3来编写,利用selnium获 ...

  7. 隐马尔可夫模型(HMM)攻略

    隐马尔可夫模型 (Hidden Markov Model,HMM) 最初由 L. E. Baum 和其它一些学者发表在一系列的统计学论文中,随后在语言识别,自然语言处理以及生物信息等领域体现了很大的价 ...

  8. maven 项目发布时,无法引用 修改的domain 问题

    其实是在bo 的smart-score 里面引用了这个interface    所以还要把 smart -Score 重新发布一下.让这个smart 引用 新的 Player-service  中的i ...

  9. Bootstrap学习-排版

    1.标题 <h1>~<h6>,所有标题的行高都是1.1(也就是font-size的1.1倍). 2.副标题 <small>,行高都是1,灰色(#999) <h ...

  10. 读书笔记 effective c++ Item 31 把文件之间的编译依赖降到最低

    1. 牵一发而动全身 现在开始进入你的C++程序,你对你的类实现做了一个很小的改动.注意,不是接口,只是实现:一个私有的stuff.然后你需要rebuild你的程序,计算着这个build应该几秒钟就足 ...