• 第十一章 Dockerfile构建镜像


    一、Dockerfile含义

    Dockerfile 由一行行命令语句组成, 并且支持以#开头的注释行。一般而言, Dockerfile 主体内容分为四部分:基础镜像信息、 维护者信息、 镜像操作指令和容器启动时执行指令。
    
    #1.Dockerfile是什么?
    构建镜像所使用的指令配置文件
    
    #2.Dockerfile基础部分
    1、基础镜像,构建一个镜像所依赖的镜像(必须)
    2、构建镜像的指令,按照我们需求自定义镜像
    3、指定镜像启动命令,(指定容器启动的方式)
    
    #3.使用Dockerfile需要注意的几点
    1、dockerfile必须命名为`Dockerfile`
    2、尽量将Dockerfile放在空目录中,如果目录中必须有其他文件,则使用.dockerignore文件。
    3、避免安装不必须的包。
    4、每个容器应该只关注一个功能点。
    5、最小化镜像的层数。
    6、多行参数时应该分类。这样更清晰直白,便于阅读和review,另外,在每个换行符前都增加一个空格。
    7、对构建缓存要有清楚的认识。
    

    二、Dockerfile的使用

    #1.格式:
    	docker build [参数] [dockerfile的路径]
    
    #2.原理
    	在构建docker镜像的时候,实际上将当前目录移动到了一个虚拟目录当中,所有的操作路径都是以虚拟路径为准。
    
    #3.参数:
    	-c : 指定使用CPU大小
    	-f : 指定dockerfile路径
    	-t : 指定构建后的镜像名称
    

    三、Dockerfile文件说明

    Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。
    

    1、FROM指令:指定基础镜像,必须为第一个命令

    #1.解释:
    	指定构建镜像的基础镜像(有且只能有一个基础镜像)
    
    #2.格式:
    	FROM [基础镜像]:[镜像版本号]
    	FROM <image>
    	FROM <image>:<tag>
    	FROM <image>@<digest>
    
    #3.示例:
      FROM mysql:5.6
    
    #4.注:
      tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
    

    2、MAINTAINER指令:维护者信息

    #1.解释:
    	指定维护者信息(现在已经淘汰)
    
    #2.格式:
    	MAINTAINER [名字] [des] [...]
        MAINTAINER <name>
    
    #3.示例:
        MAINTAINER Jasper Xu
        MAINTAINER sorex@163.com
        MAINTAINER Jasper Xu <sorex@163.com>
    

    3、RUN指令:构建镜像时执行的命令

    #1.解释:
    	RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
    
    #2.执行方式:
    1.shell执行
    格式:
    	RUN [linux命令]
        RUN <command>
        
    2.exec执行
    格式:
        RUN ["executable", "param1", "param2"]
    
    #3.示例:
        RUN ["executable", "param1", "param2"]
        RUN apk update
        RUN ["/etc/execfile", "arg1", "arg1"]
        
    #4.注:
    	RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
    

    4、ADD指令:将本地文件添加到容器中

    #1.解释:
    	将本地文件添加到容器中,添加文件到镜像中,ADD指令有一个自动解压的功能(tar),ADD指令可以下载互联网上的文件但是不解压。
    
    #2.格式:
    	ADD [宿主主机文件路径(必须使用相对路径)]  [添加到镜像中的文件路径]
    	ADD <src>... <dest>
        ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
    
    #3.示例:
        ADD hom* /mydir/          # 添加所有以"hom"开头的文件
        ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
        ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
        ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/
        
    # 添加文件到容器当中
    ADD ./1.txt /root
    
    # 添加一个压缩包,测试是否会自动解压
    ADD etcd-v3.0.17-darwin-amd64.zip /opt
    
    # 在网上下载文件至镜像中(不会自动解压)
    ADD https://mirrors.huaweicloud.com/etcd/v3.0.17/v3.0.17.tar.gz  /opt
    
    # 测试正则
    ADD etcd-v3.0.17* /tmp/
    
    # 测试ADD文件
    ADD mysql.txt /root/
    
    #4.注:
    	ADD指令支持正则(路径必须以/结尾)
    

    5、COPY指令 :功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

    #1.解释:
    	复制一个文件到镜像中
    
    #2.格式:
    	COPY [宿主主机文件路径(必须使用相对路径,只能向下找文件)]  [添加到镜像中的文件路径]
    	COPY < src>… < dest>|[“< src>”,… “< dest>”]
    
    #3.示例:
        # 测试COPY正则
        COPY etcd-v3.0.17* /etc/
    
        # 测试COPY文件
        COPY mysql.txt /opt/
        
        # 测试COPY
        COPY ./1.txt /opt
    
        # 测试COPY解压功能
        COPY etcd-v3.0.17-linux-amd64.tar.gz /opt
        
    #4.注:
    	COPY指令没有解压功能.
    	COPY指令不支持互联网下载.
    	COPY指令支持正则.
    	
    ps:指令逻辑和ADD十分相似,同样Docker Daemon会从编译目录寻找文件或目录,dest为镜像中的绝对路径或者相对于WORKDIR的路径
    

    6、CMD指令: 构建容器后调用,也就是在容器启动时才进行调用

    #1.解释:
    	指定容器启动时默认命令
    
    #2.格式:
        CMD ["executable","param1","param2"] (执行可执行文件,优先)
        CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
        CMD command param1 param2 (执行shell内部命令)
    
    #3.示例:
        CMD echo "This is a test." | wc -
        CMD ["/usr/bin/wc","--help"]
    	CMD /bin/bash
    	CMD ["nginx","-g","daemon off;"]
    	
    #4. 注:   
    	CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
    

    7、LABEL指令:用于为镜像添加元数据

    #1.解释:
    	使用LABEL指定元数据时
    	
    #2.格式:
        LABEL <key>=<value> <key>=<value> <key>=<value> ...
        
    #3.示例:
      LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
      LABEL key=value
      
    #4.注:
      使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
    

    8、ENV指令:设置环境变量

    #1.解释:
    	指定环境变量
    	
    #2.格式:
        ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
        ENV <key>=<value> ...  #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
    
    #3.示例:
    	ENV myName John Doe
    	
        ENV myDog Rex The Dog
        
        ENV myCat=fluffy
        
    	ENV NGINX_WORKER=5
            [root@docker ~/docker/nginx]# docker exec wizardly_cannon printenv
            PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            NGINX_WORKER=5
            
    	ENV NGINX_DES nginx server is very 666
    		[root@docker ~/docker/nginx]# docker exec amazing_driscoll printenv
            PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            NGINX_DES=nginx server is very 666
            
     #4.查看环境变量
     [root@m01 ~]# docker exec {containerID} env
    

    9、EXPOSE指令:指定于外界交互的端口

    #1.解释:
    	指定向外暴露的端口
    
    #2.格式:
        EXPOSE <port> [<port>...]
    
    #3.示例:
        EXPOSE 80 443
        
        EXPOSE 8080 
        
        EXPOSE 11211/tcp 11211/udp
    
    	EXPOSE 80 443 1000 10000
        [root@docker ~/docker/nginx]# docker run -d test/nginx:v12 
        e4f0b3a673dd9c83d2ecdb40c1726d3bed595890eeb9eab7fefb3218eb5650dc
        [root@docker ~/docker/nginx]# docker ps
        CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                                  NAMES
        e4f0b3a673dd   test/nginx:v12   "/docker-entrypoint.…"   3 seconds ago    Up 3 seconds    80/tcp, 443/tcp, 1000/tcp, 10000/tcp   naughty_fermat
        
        
        EXPOSE 80 443 1000/udp 10000
        [root@docker ~/docker/nginx]# docker ps
        CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                                  NAMES
        e1e4f2c18f40   test/nginx:v13   "/docker-entrypoint.…"   48 seconds ago   Up 48 seconds   80/tcp, 443/tcp, 10000/tcp, 1000/udp   hungry_aryabhata
    
    
    #4.注:  
            EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
    

    10、VILUME指令: 用于指定持久化目录

    #1.解释:指定挂载点
    
    #2.格式:
      VOLUME ["/path/to/dir"]
    
    #3.示例:
      VOLUME ["/data"]
      
      VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
    
      VOLUME /data
      docker inspect test/nginx:v14
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "b9b87662e3296ea94db87b48ef642933751f53fe7bf715026f59043bc65335f0",
                    "Source": "/var/lib/docker/volumes/b9b87662e3296ea94db87b48ef642933751f53fe7bf715026f59043bc65335f0/_data",
                    "Destination": "/data",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    
    #4.注:  
    	一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
    		1.卷可以容器间共享和重用
    		2.容器并不一定要和其它容器共享卷
    		3.修改卷后会立即生效
    		4.对卷的修改不会对镜像产生影响
    		5.卷会一直存在,直到没有任何容器在使用它
    		6.共享存储卷:docker run --valumes-from [共享容器的名称] [镜像名称]
    		docker run -d --volumes-from upbeat_mcclintock test/nginx:v16
    		7.如果使用-v参数,将挂载指定的目录,不使用则自动生成挂载。
    

    11、ARG指令:1.1、 用于指定传递给构建运行时的变量

    #1.解释:
    	设置运行时参数,一般是在构建时使用
    
    #2.格式:
    	ARG key  : 需要用到docker build --build-arg key=value
    	ARG key=value
    	ARG <name>[=<default value>]
    
    #3.示例:
    	[root@docker ~/docker/nginx]# docker exec 7ed524e38ac8 cat log
    	value
    	
     	ARG site
     	
     	ARG build_user=www
    

    12、ONBUILD指令:用于设置镜像触发器

    #1.解释:
    	镜像触发器(当当前镜像作为基础镜像时,执行)
    
    #2.格式:
    	ONBUILD [dockerfile指令]
    	ONBUILD [INSTRUCTION]
    	ONBUILD RUN touch 1.txt
    
    #3.示例:
      ONBUILD ADD . /app/src
      ONBUILD RUN /usr/local/bin/python-build --dir /app/src
    
    #4.注:  
        当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
    

    13. WORKDIR:工作目录,类似于cd命令

    #1.格式:
      WORKDIR /path/to/workdir
    
    #2.示例:
      WORKDIR /a (这时工作目录为/a)
      WORKDIR b (这时工作目录为/a/b)
      WORKDIR c (这时工作目录为/a/b/c)
      
    #3.注:  
       通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
    

    四、Dockerfile构建镜像案例一

    1.新建Dockerfile

    1.新建目录
    [root@m01 ~]# mkdir /docker/
    [root@m01 ~]# cd /docker
    
    2.新建Dockerfile
    [root@m01 /docker]# cat Dockerfile 
    #Is my first nginx Dockerfile
    # Version 1.0
    
    # Base images 基础镜像
    FROM centos
    
    #MAINTAINER 维护者信息
    MAINTAINER jh
    
    #ADD  文件放在当前目录下,拷过去会自动解压
    ADD nginx-1.18.0.tar.gz /usr/local/  
    ADD epel-release-latest-7.noarch.rpm /usr/local/  
    
    #RUN 执行以下命令
    
    RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
    RUN yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake wget httpd-tools vim tree && yum clean all
    RUN useradd -s /sbin/nologin -M www
    
    #WORKDIR 相当于cd
    WORKDIR /usr/local/nginx-1.18.0 
    
    RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_addition_module --with-http_auth_request_module --without-http_gzip_module && make && make install
    
    RUN echo "daemon off;" >> /etc/nginx.conf
    
    #ENV 设置环境变量
    ENV PATH /usr/local/nginx/sbin:$PATH
    
    #EXPOSE 映射端口
    EXPOSE 80
    
    #CMD 运行以下命令
    CMD ["nginx"]
    

    2.上传相关安装包

    [root@m01 /docker]# rz
    -rw-r--r-- 1 root root       918 Jan 14 20:59 Dockerfile
    -rw-r--r-- 1 root root     15448 Jan 14 19:44 epel-release-latest-7.noarch.rpm
    -rw-r--r-- 1 root root   1039530 Jan 14 19:44 nginx-1.18.0.tar.gz
    

    3.创建镜像

    [root@m01 /docker]# docker build -t centos_nginx:v4 .
    [root@m01 /docker]# docker images
    REPOSITORY     TAG       IMAGE ID       CREATED         SIZE
    centos_nginx   v4        f87c2b493910   7 minutes ago   483MB
    centos         latest    300e315adb2f   5 weeks ago     209MB
    

    4.备份镜像

    [root@m01 /docker]# docker save f87c2b493910 > centos_nginx:v4.tar
    

    5.运行容器

    [root@m01 /docker]# docker run -d -p81:80 centos_nginx:v4 nginx -g "daemon off;"
    535f5d0f2829c1d4642020f03e8d48616f31edfe111bab02173f0815892d3698
    

    五、Dockerfile构建镜像案例二

    1.新建Dockerfile

    1.新建目录
    [root@m01 ~]# mkdir /docker/
    [root@m01 ~]# cd /docker
    
    2.新建Dockerfile
    [root@m01 /docker]# vim Dockerfile 
    #Is my first nginx Dockerfile
    # Version 1.0
    
    # Base images 基础镜像
    FROM centos
    
    #MAINTAINER 维护者信息
    MAINTAINER Jin Hui
    
    #ADD  下载相关文件放在当前目录下,不会自动解压
    ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/
    ADD https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm /usr/local/ 
    
    #RUN 执行以下命令
    RUN tar xf /usr/local/nginx-1.18.0.tar.gz -C /usr/local/
    RUN rpm -ivh /usr/local/epel-release-latest-8.noarch.rpm
    RUN yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake wget httpd-tools vim tree && yum clean all
    RUN useradd -s /sbin/nologin -M www
    
    #WORKDIR 相当于cd
    WORKDIR /usr/local/nginx-1.18.0 
    
    #RUN 执行以下命令
    RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_addition_module --with-http_auth_request_module --without-http_gzip_module && make && make install
    
    #ENV 设置环境变量
    ENV PATH /usr/local/nginx/sbin:$PATH
    
    #EXPOSE 映射端口
    EXPOSE 80
    
    #CMD 运行以下命令
    CMD ["nginx","-g","daemon off;"]
    

    2.构建镜像

    [root@m01 /docker]# docker build --no-cache -t centos_nginx:v1 .
    [root@m01 /docker]# docker images
    REPOSITORY     TAG       IMAGE ID       CREATED         SIZE
    centos_nginx   v1        ca2a0d26d619   21 minutes ago  521MB
    centos         latest    300e315adb2f   5 weeks ago     209MB
    

    3.备份镜像

    [root@m01 /docker]# docker save ca2a0d26d619 > centos_nginx:v1.tar
    

    4.运行容器

    [root@m01 /docker]# docker run -d -p 80:80  --name nginx centos_nginx:v1
    dd014764a0d192cb6185d3db92e34a8e0358cf125c20d0a68a80b6a598e84c63
    

    5.测试镜像

    [root@docker100 ~/1]# curl  127.0.0.1:80
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
             35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
  • 相关阅读:
    【视频教学】Maclean教你用Vbox在Linux 6.3上安装Oracle 11gR2 RAC
    了解你所不知道的SMON功能(十二):Shrink UNDO(rollback) SEGMENT
    大叔问题定位分享(41)logstash消费kafka延迟
    大叔经验分享(122)linux系统蓝牙失效
    大叔问题定位分享(42)yarn被利用提交getshell任务挖矿
    大叔问题定位分享(43)hbase大面积重启
    arcgis 栅格转Point点
    arcgis建立渔网(fishnet)
    Docker容器:将带UI的程序直接转为Web应用,so easy
    架构漫谈(五):什么是软件
  • 原文地址:https://www.cnblogs.com/jhno1/p/15266704.html
Copyright © 2020-2023  润新知