• 构建docker镜像


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

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

    # docker run -i -t ubuntu /bin/bash
    root@b437ffe4d630:/# apt-get -yqq update
    root@b437ffe4d630:/# 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 "bourbon@1mcloud.com"  #设置镜像信息。
    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" git@github.com: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 "bourbon@1mcloud.com"
     ---> 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
    root@55aee4322f77:/# apt-get install -y ngin
    Reading package lists... Done
    Building dependency tree      
    Reading state information... Done
    E: Unable to locate package ngin
  • 相关阅读:
    hihocoder [Offer收割]编程练习赛14 投掷硬币
    hihocoder [Offer收割]编程练习赛14 小Hi和小Ho的礼物
    CodeForces
    [HNOI2004] 打砖块
    CodeForces
    hdu4028 The time of a day[map优化dp]
    hdu5009 Paint Pearls[指针优化dp]
    hdu4719 Oh My Holy FFF[线段树优化dp]
    hdu1024 Max Sum Plus Plus[降维优化好题(貌似以后可以不用单调队列了)]
    hdu3709 Balanced Number[数位dp]
  • 原文地址:https://www.cnblogs.com/raorao1994/p/9750605.html
Copyright © 2020-2023  润新知