构建docker镜像

Posted raorao1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构建docker镜像相关的知识,希望对你有一定的参考价值。

一、通过docker commit命令构建镜像

  docker commit 构建镜像可以想象为是将运行的镜像进行重命名另存一份。我们先创建一个容器,并在容器里做出修改,就像修改代码一样,最后再将修改提交为一个镜像。

# docker run -i -t ubuntu /bin/bash
[email protected]:/# apt-get -yqq update
[email protected]:/# apt-get -y install apache2

  以上的操作我们启动了一个容器,并在里面安装了Apache。我们会将这个容器作为一个Web服务器来运行,所以我们想把它的当前状态保存下来。这样我们就不必每次都创建一个新容器并再次在里面安装Apache了。为了完成此项工作,需要先使用exit命令从容器里退出,通过docker ps -a命令查询待保存docker的CONTAUBER ID,之后再运行docker commit命令:

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
b437ffe4d630        ubuntu              "/bin/bash"         45 minutes ago      Exited (0) 10 seconds ago                       clever_pare        
b87f9dde62b0        devopsil/puppet     "/bin/bash"         2 days ago          Up 2 days                                       evil_archimedes    
 
# docker commit b437ffe4d630 test/apache2
9c30616364f44a519571709690e3c92a5cad4ad01c007d8126eb6d63670d33f4
 
# docker images test/apache2
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
test/apache2        latest              9c30616364f4        36 seconds ago      254.4 MB

  在使用docker commit命令中,指定了要提交的修改过的容器的ID(可以通过docker ps命令得到刚创建的容器ID),以及一个目标镜像仓库和镜像名,这里是test/apahce2。需要注意的是,docker commit提交的只是创建容器的镜像与容器的当前状态之间有差异的部分,这使得该更新非常轻量。通过docker images 可以查看新创建的镜像信息。也可以在提交镜像时指定更多的数据(包括标签)来详细描述所做的修改。

# docker commit -m="A new custom image" --author="Bourbon Tian" b437ffe4d630 test/apache2:webserver
27fc508c41d1180b1a421380d755cf00f9dfb6b0d354b9eccaec94ae58a06675

  这条命令里,我们指定了更多的信息选项:

  • -m 用来指定创建镜像的提交信息;
  • --author 用来列出该镜像的作者信息;
  • 最后在test/apache2后面增加了一个webserver标签。

  通过使用docker inspect命令来查看新创建的镜像的详细信息:

# docker inspect test/apache2:webserver
[
{
    "Id": "27fc508c41d1180b1a421380d755cf00f9dfb6b0d354b9eccaec94ae58a06675",
    "Parent": "f5bb94a8fac47aaf15fb4e4ceb138d59ac2fcf004cd3f277cebe2174fd7a6c70",
    "Comment": "A new custom image",
    "Created": "2017-05-17T07:29:46.000512241Z",
    "Container": "b437ffe4d63047dd34653f5256bb6eda54acfd3db99f72f2262a9b9af7f31334",
...

  如果想从刚创建的镜像运行一个容器,可以使用docker run命令:

# docker run -t -i test/apache2:webserver /bin/bash

 

二、通过docker build命令和 Dockerfile 文件创建docker镜像

  Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像,之后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像。

# mkdir /opt/static_web
# cd /opt/static_web/
# vim Dockerfile

  首先创建一个名为static_web的目录用来保存Dockerfile,这个目录就是我们的构建环境(build environment),Docker则称此环境为上下文(context)或者构建上下文(build context)。Docker会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程。这样Docker守护进程就能直接访问你想在镜像中存储的任何代码、文件或者其他数据。这里我们还创建了一个Dockerfile文件,我们将用它构建一个能作为Web服务器的Docker镜像。

# Version: 0.0.1
FROM ubuntu:latest  #Docker从基础镜像运行一个容器。
MAINTAINER Bourbon Tian "[email protected]"  #设置镜像信息。
RUN apt-get update  #更新
RUN apt-get install -y nginx #安装nginx 
RUN echo Hi, I am in your container > /usr/share/nginx/html/index.html   #修改文件
EXPOSE 80 #指定80端口开放

  Dockerfile由一系列指令和参数组成。每条指令都必须为大写字母,切后面要跟随一个参数。Dockerfile中的指令会按照顺序从上到下执行,所以应该根据需要合理安排指令的顺序。每条指令都会创建一个新的镜像层并对镜像进行提交。Docker大体上按照如下流程执行Dockerfile中的指令。

从上面可以看出,如果你的Dockerfile由于某些原因(如某条指令失败了)没有正常结束,那你也可以得到一个可以使用的镜像。这对调试非常有帮助:可以基于该镜像运行一个具备交互功能的容器,使用最后创建的镜像对为什么你的指令会失败进行调试。

Dockerfile也支持注释。以#开头的行都会被认为是注释,# Version: 0.0.1这就是个注释

 

  FROM:

  每个Dockerfile的第一条指令都应该是FROM。FROM指令指定一个已经存在的镜像,后续指令都是将基于该镜像进行,这个镜像被称为基础镜像(base iamge)。在这里ubuntu:latest就是作为新镜像的基础镜像。也就是说Dockerfile构建的新镜像将以ubuntu:latest操作系统为基础。在运行一个容器时,必须要指明是基于哪个基础镜像在进行构建。

  MAINTAINER:

  MAINTAINER指令,这条指令会告诉Docker该镜像的作者是谁,以及作者的邮箱地址。这有助于表示镜像的所有者和联系方式

  RUN:

  在这些命令之后,我们指定了三条RUN指令。RUN指令会在当前镜像中运行指定的命令。这里我们通过RUN指令更新了APT仓库,安装nginx包,并创建了一个index.html文件。像前面说的那样,每条RUN指令都会创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交,之后继续执行Dockerfile中的下一个指令。

  EXPOSE:

  EXPOSE指令是告诉Docker该容器内的应用程序将会使用容器的指定端口。这并不意味着可以自动访问任意容器运行中服务的端口。出于安全的原因,Docker并不会自动打开该端口,而是需要你在使用docker run运行容器时来指定需要打开哪些端口。

  执行docker build命令时,Dockerfile中的所有指令都会被执行并且提交,并且在该命令成功结束后返回一个新镜像。

# cd static_web
# docker build -t="test/static_web" .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
...
Successfully built 94728651ce15

  上面命令中最后的“.”告诉Docker到当前目录中去找Dockerfile文件。也可以指定一个Git仓库地址来指定Dockerfile的位置,这里Docker假设在Git仓库的根目录下存在Dockerfile文件:

# docker build -t="test/static_web:v1" [email protected]:test/static_web

 

  构建出错:

# docker build -t="test/static_web" .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:latest
 ---> f5bb94a8fac4
Step 1 : MAINTAINER Bourbon Tian "[email protected]"
 ---> Using cache
 ---> ce64f2e75a74
Step 2 : RUN apt-get update
 ---> Using cache
 ---> e98d2c152d1d
Step 3 : RUN apt-get install -y ngin
 ---> Running in 2f16c5f11250
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package ngin
The command /bin/sh -c apt-get install -y ngin returned a non-zero code: 100

 

  在构建镜像时,由于RUN语句错误或者其他错误导致构建失败时,可以我们需要调试一下这次失败,我们可以通过docker run命令来基于这次构建到目前为止已经成功的最后一步创建一个容器,这里它的ID是e98d2c152d1d:

# docker run -t -i e98d2c152d1d /bin/bash
[email protected]:/# apt-get install -y ngin
Reading package lists... Done
Building dependency tree      
Reading state information... Done
E: Unable to locate package ngin

 

以上是关于构建docker镜像的主要内容,如果未能解决你的问题,请参考以下文章

构建docker镜像

docker构建镜像

构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式

Docker删除报错:Error response from daemon: conflict: unable to delete 08b152afcfae (must be forced)(代码片段

docker镜像构建

使用Jenkins构建Docker镜像 --SpringCloud