Docker 镜像管理

认识Docker镜像

  创建镜像时需要制定使用哪个镜像。它会先从本地查找有没有这个镜像,如果不存在,就去官方Docker Hub仓库查找并下载到本机然后基于该镜像创建容器。

每个镜像有一个唯一的ID,也可以使用镜像的名字和版本号两部分组合唯一表示。如果省略版本号,默认使用最新版本(latest)

  docker images #查到本机已有的所有镜像

镜像分层

  镜像所占的磁盘空间远远小于所有镜像之和,原因是Docker镜像采用分层机制,相同部分独立成层,只需要存储一份就可以了大大节省了镜像空间。Docker

的镜像通过联合文件系统,将各层叠加在一起,在用户看来就像一个完整的文件系统,感觉不到分层的存在。

  docker history #docker history <image_name> #查询镜像分了多少层,每一层具体做了什么操作。

分层的镜像有两个特性:一是已有的分层只能读不能修改,另外一个是上层镜像的优先级高于底层镜像。

已有的分层不能修改,如果要修改,只能通过在镜像的基础上新增一个分层,存储修改后的文件,利用“上层镜像的优先级高于底层镜像”的原则,新增分层的文件会覆盖原有镜像。

从用户视角,就会看到修改后的文件内容,而原有的镜像内容没有变。

  容器时在镜像的基础上创建的,从文件系统的角度来讲,它是在分层镜像的基础上增加一个新的空白分层,这个新分层是可读写的。新创建的容器启动后是可写的。所有的写

操作都会存储在最上面的可读写层。

  docker commit #提交生成新镜像

  镜像A修改文件a.txt,生成形象AA。步骤如下:

  首先,基于镜像A创建一个新容器C.

  其次,在容器C中修改文件a.txt的内容。

  最后,通过docker commit 命令提交生成新的镜像AA。 但这种方式会让镜像的层越来越多,另外一种情况一旦基础镜像需要修改,基于他的上层应用镜像很多,如果每一个

上层镜像都通过这种容器方式生成新镜像,那么维护的工作量太大。

Dockerfile

      使用GUN的make工具能够比较方便构建一个工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。Makefile文件中描述了整个工程所有文件的编

译顺序、编译规则。Makefile有自己的书写格式、关键字、函数。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建哪些库文件、如何最后产生我们想要的可执

行文件尽管看起来可能很复杂,但是为工程编写makefile的好处是一旦提供一个正确的Makefile,就能够使用一行命令来完成“自动化编译”。编译整个工程所要做的唯一的一件事

就是在shell提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

  Dokcer 提供了和Makefile完全一样的机制来管理镜像,这就是Dokcerfile。它是Docker镜像的描述文件,通过Dockerfile做出来的,包含操作系统基础文件和软件运行环境,

它使用分层的存储方式。

  # base image,表示从centos这个基础镜像开始构建,centos是他的底层镜像
  FROM centos

  # MAINTAINER,指定该进行的创建者
  MAINTAINER json_hc@163.com

  # put nginx-1.12.2.tar.gz into /usr/local/src and unpack nginx
  ADD nginx-1.12.2.tar.gz /usr/local/src

  # running required command,运行shell命令,如果有多条命令可以用“&&”链接
  RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
  RUN yum install -y libxslt-devel -y gd gd-devel GeoIP GeoIP-devel pcre pcre-devel
  RUN useradd -M -s /sbin/nologin nginx

  # change dir to /usr/local/src/nginx-1.12.2
  WORKDIR /usr/local/src/nginx-1.12.2

  # execute command to compile nginx
  RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_module --with-http_realip_module --with-http_addition_module

  --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module

  --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module

  --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module && make && make install

  #设置环境变量

  ENV PATH /usr/local/nginx/sbin:$PATH

  #指定监听的端口

  EXPOSE 80

  #这个关键字和以上所有的关键字是有区别的,上面的关键字都是在构建镜像时执行,但这个关键字是预执行命令,在创建镜像时不执行,要等到使用该镜像时,容器启动后才执行

  ENTRYPOINT ["nginx"]

  CMD ["-g","daemon off;"]

从例子我们看到Dockerfile的语法规则:每行都以一个关键字为首行,如果一行内容过长,它使用“”把多行连接到一起。

docker build  -t  image_name #编译Dokcerfile,通过“-t”选项给镜像起一个名字。

有了新镜像,就可以通过docker run命令创建和使用新容器了。

项目中的镜像分层

  >>多个项目会共享基础镜像。

  >>每个镜像加一个可写层形成容器,多个容器组合在一起,对外提供某些特殊功能的服务。

  >>基于同一个镜像增加一个可写层,就可以为不同项目创建各自需要的容器。

对我们的启发是:当我们制作自己的应用镜像时,也尽量考虑使用相同的底层镜像,这样可以极大地降低后续的维护成本。

原文地址:https://www.cnblogs.com/jixp/p/9959415.html