zoukankan      html  css  js  c++  java
  • 构建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
  • 相关阅读:
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车按键启动和蜂鸣器报警
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    asp中设置session过期时间方法总结
    asp中设置session过期时间方法总结
    ASP.NET关于Session_End触发与否的问题
  • 原文地址:https://www.cnblogs.com/raorao1994/p/9750605.html
Copyright © 2011-2022 走看看