zoukankan      html  css  js  c++  java
  • Docker镜像构建的两种方式(六)

    镜像构建介绍

    在什么情况下我们需要自己构建镜像那?

    (1)当我们找不到现有的镜像,比如自己开发的应用程序

    (2)需要在镜像中加入特定的功能

    docker构建镜像有两种方式:docker commit命令与Dockerfile构建文件

    docker commit构建镜像

    dockercommit构建进行主要有三步:

    • 运行容器
    • 修改容器
    • 将容器保存为新的镜像

    比如在centos镜像中安装vim编辑器并存为新的镜像

    (1)运行容器

    [root@ken1 docker]# docker run -it centos
    Unable to find image 'centos:latest' locally
    latest: Pulling from library/centos
    a02a4930cb5d: Pull complete 
    Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
    Status: Downloaded newer image for centos:latest

    (2)安装vim编辑器

    vim编辑器确认没有安装

    [root@69f501e858a6 /]# vim
    bash: vim: command not found

    进行安装

    [root@69f501e858a6 /]# yum install vim -y

    (3)保存为新得镜像

    首先查看当前运行的镜像

    [root@ken1 ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    69f501e858a6        centos              "/bin/bash"         2 minutes ago       Up 2 minutes                            quizzical_torvalds

    使用commit存为新的镜像

    [root@ken1 ~]# docker commit 69f501e858a6 centos-vim
    sha256:42083b89a179368bc29a8f40d14f8824990183c8e4b28fd84411d440c26342e5

    69f501e858a6是运行容器的ID使用name下面的名称也行
    centos-vim是新镜像的名字

    查看一下是否有了centos-vim镜像

    重新启动新的镜像,验证是否可以使用vim编辑器

    可以发现新的镜像可以使用vim编辑器了

    [root@ken1 ~]# docker run -it centos-vim 
    [root@61d090898bad /]# vim
    [root@61d090898bad /]# vim test

    上面演示了如何使用commit创建新的镜像,但是docker并不建议使用这种方式创建镜像,原因如下:

    • 这是一种手工创建镜像的方式,容器出错,而且效率低且可重复性弱
    • 更重要的是。使用者并不知道镜像是如何创建出来的。里面是否有恶意程序

    Dockerfile构建镜像

    第一个Dockerfike

    第一步:创建一个新的目录

    [root@ken1 ~]# mkdir /test

    第二步:编写Dockerfile

    名称就叫Dockerfile,且第一个D需要大写

    [root@ken1 ~]# cat Dockerfile
    FROM centos
    RUN yum install vim -y

    FROMcentos表示使用centos这个基础镜像

    RUN表示在centos上安装vim编辑器

    第三步:构建镜像

    [root@ken1 ~]# docker build -t centos-vim2 .

    -t后面指定新的镜像的标签名(tag)

    . 最后的一个点指明docker context为当前目录。docker默认会从build context中查找 Dockerfile文件,我们也可以通过-f参数指定Dockerfile的位置

    第四步:查看镜像

     查看镜像分层结构

    docker history会显示镜像的构建历史,也就是Dockerfile的执行过程。

    Dcokerfile常用指令

      1.FROM

    指定base镜像

      2. MAINTAINER

    设置镜像的作者。可以是任意的字符

      3.COPY

    将文件从build context复制到镜像

    COPY支持两种格式:COPY src dest 和 COPY [“src”,”dest”]

    注意:src只能制动build context中的文件或目录即在和Dockerfile同目录下才可以

      4.ADD

    与COPY类似,从build context复制文件到镜像。

    不同的是,如果src是归档文件(tar,zip,tgz,xz),文件会被自动接要到dest

      5.ENV

    设置环境变量,环境变量可被后面的指令使用,例如:

    ENV name ken RUN echo $name

      6.EXPOSE

    指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来

      7.VOLUME

    将文件或目录声明为volume

      8.WORKDIR

    为后面的RUN,ENTRYPINT,ADD,COPY指令设置镜像中的当前工作目录

      9.RUN

    在容器中运行指定的命令

      10.CMD

    容器启动时运行指定的命令

    dockerfile中可以多个CMD指令,但是只要最后一个生效。CMD可以被docker run之后的参数替换

      11.ENTRYPOINT

    设置容器启东市的命令

    dockerfile中可以有多个ENTRYPOINT,但是只有最后一个生效。

    CMD或者docker run之后的参数会被当做参数传递给ENTERYPOINT.

    Dockerfile演示

    下面演示一个比较全面的dockerfile

     
    [root@ken1 test]# cat Dockerfile 
    #my Dockerfile
    FROM busybox
    MAINTAINER ken
    WORKDIR /ken
    RUN touch test
    COPY ["ken1","."]
    ADD ["wordpress.tar.gz","."]
    ENV name "ken"
     

    注意:Dockerfile支持以#开头的注释

    构建镜像

     
    [root@ken1 test]# docker build -t myimage .
    Sending build context to Docker daemon  4.281MB
    Step 1/7 : FROM busybox
     ---> 3a093384ac30
    Step 2/7 : MAINTAINER ken
     ---> Running in 2a73a83507ce
    Removing intermediate container 2a73a83507ce
     ---> 8c3df9b3d823
    Step 3/7 : WORKDIR /ken
     ---> Running in 31c6f9fe2195
    Removing intermediate container 31c6f9fe2195
     ---> a458cf986072
    Step 4/7 : RUN touch test
     ---> Running in e1b08ebd363c
    Removing intermediate container e1b08ebd363c
     ---> 41601920009a
    Step 5/7 : COPY ["ken1","."]
     ---> 2ebfa0933fca
    Step 6/7 : ADD ["wordpress.tar.gz","."]
     ---> d0ad29d3aa34
    Step 7/7 : ENV name "ken"
     ---> Running in fceae6e20e63
    Removing intermediate container fceae6e20e63
     ---> 7efe0600e48f
    Successfully built 7efe0600e48f
    Successfully tagged myimage:latest
     

    查看镜像

    运行该镜像

    [root@ken1 test]# docker run -it myimage
    /ken # ls
    ken1       test       wordpress
    /ken # echo $name
    ken
    •  可以发现当前工作目录为/ken,且自动创建
    • ken1是我们从docker context目录中复制过去的
    • test是使用touch创建的
    • wordpres压缩包已经被自动解压
    • $name为变量值为ken

     RUN,CMD,ENTRYPOINT

    这三个指令看上去很类似,很容易混淆,简单来说:

    • RUN:执行命令创建新的镜像层,RUN经常用于安装软件包
    • CMD:设置容器启动后默认执行的命令及参数,但CMD能够被docker run后面跟的命令行参数替换
    • ENTRYPOINT:配置容器启动时运行的命令
    1. 使用 RUN 指令安装应用和软件包,构建镜像。
    2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。
    3. 如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

    Shell和Exec格式

    可以用两种方式制定RUN,CMD,ENTRYPOINT要运行的命令:shell格式以及exec格式

    shell举例:

    RUN echo "hello world"
    CMD echo "hello world"
    ENTRYPOINT echo "hello world"

    当指令执行时,shell格式底层会调用/bin/sh -c [command].例如下面的dockerfile片段:

    ENV name ken  
    
    ENTRYPOINT echo "Hello, $name"

    执行 docker run <image> 将输出:

    Hello, ken

    注意环境变量 name 已经被值 ken替换。

    下面来看 Exec 格式。

    Exec 格式

    <instruction> [“executable”, “param1”, “param2”, …]

    例如:

    RUN ["yum", "install", "python3"]  
    
    CMD ["/bin/echo", "Hello world"]  
    
    ENTRYPOINT ["/bin/echo", "Hello world"]

    当指令执行时,会直接调用 <command>,不会被 shell 解析。
    例如下面的 Dockerfile 片段:

    ENV name ken
    
    ENTRYPOINT ["/bin/echo", "Hello, $name"]

    运行容器将输出:

    Hello, $name

    注意环境变量“name”没有被替换。
    如果希望使用环境变量,照如下修改

    ENV name ken  
    
    ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

    运行容器将输出:

    Hello, ken

    CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。

  • 相关阅读:
    使用 yo 命令行向导给 SAP UI5 应用添加一个新的视图
    SAP Fiori Elements 应用的 manifest.json 文件运行时如何被解析的
    SAP UI5 标准应用的多语言支持
    微软 Excel 365 里如何设置下拉菜单和自动高亮成指定颜色
    SAP Fiori Elements 应用里的 Title 显示的内容是从哪里来的
    本地开发好的 SAP Fiori Elements 应用,如何部署到 ABAP 服务器上?
    如何在 Cypress 测试代码中屏蔽(Suppress)来自应用代码报出的错误消息
    教你一招:让集群慢节点无处可藏
    应用架构步入“无服务器”时代 Serverless技术迎来新发展
    MySQL数据库事务隔离性的实现
  • 原文地址:https://www.cnblogs.com/it-peng/p/11388240.html
Copyright © 2011-2022 走看看