暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

05-docker系列-使用dockerfile构建镜像

运维家 2022-02-12
209

声明:本文乃“运维家”原创,转载请注明出处,更多内容请关注公众号“运维家”。


主旨

上一篇文章介绍了使用commit方式来构建自定义镜像,那么本文来介绍下主流方式,如何使用dockerfile来构建镜像。

环境
    linux环境
    docker环境

    概念

    Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。


    下载镜像

    本文使用nginx镜像来做示范,故而需要先下载一个nginx镜像;

      [yunweijia@localhost ~]$ sudo docker pull nginx
      Using default tag: latest
      latest: Pulling from library/nginx
      5eb5b503b376: Pull complete
      1ae07ab881bd: Pull complete
      78091884b7be: Pull complete
      091c283c6a66: Pull complete
      55de5851019b: Pull complete
      b559bad762be: Pull complete
      Digest: sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
      Status: Downloaded newer image for nginx:latest
      docker.io/library/nginx:latest
      [yunweijia@localhost ~]$ sudo docker images
      REPOSITORY TAG IMAGE ID CREATED SIZE
      centos ceshi adeae577d8b3 4 hours ago 359MB
      nginx latest c316d5a335a5 2 weeks ago 142MB
      hello-world latest feb5d9fea6a5 4 months ago 13.3kB
      centos 7 eeb6ee3f44bd 4 months ago 204MB
      [yunweijia@localhost ~]$

      FROM和RUN

      文件名必须是Dockerfile,且该目录下不要存放无用的文件。

        [yunweijia@localhost ~]$ mkdir -pv docker/nginx
        mkdir: 已创建目录 "docker"
        mkdir: 已创建目录 "docker/nginx"
        [yunweijia@localhost ~]$ cd docker/nginx/
        [yunweijia@localhost nginx]$ vim Dockerfile
        FROM nginx
        RUN echo "这是运维家进行测试的一个nginx镜像" > /usr/share/nginx/html/index.html
        # 保存退出

        参数解释:

          FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
          RUN:用于执行后面跟着的命令行命令。有以下两种格式:
            shell格式:RUN <命令行命令>
              # 命令行命令就是在终端shell中执行的命令
            exec格式:RUN [“可执行文件”,“参数1”,“参数2”]
              # RUN ["./test.sh","yunweijia","ls"] 等同于 RUN ./test.sh yunweijia ls
          注意:Dockerfile的指令,每执行一次都会在docker上新建一层,这样子就会造成制作出来的镜像变的很大,我们争取能一行写完的内容,就不要写多行,这也是很多人制作完镜像之后发现自己的镜像特别大的原因所在。

          构建镜像:

          需要指定Dockerfile文件的目录。

            语法:docker bulid -t 镜像:版本号 Dockerfile文件目录
            [yunweijia@localhost nginx]$ sudo docker build -t nginx:yunweijia home/yunweijia/docker/nginx/
            Sending build context to Docker daemon 2.048kB
            Step 1/2 : FROM nginx
            ---> c316d5a335a5
            Step 2/2 : RUN echo "这是运维家进行测试的一个nginx镜像" > usr/share/nginx/html/index.html
            ---> Running in 0904cf0d2196
            Removing intermediate container 0904cf0d2196
            ---> 2c95163ff074
            Successfully built 2c95163ff074
            Successfully tagged nginx:yunweijia
            [yunweijia@localhost nginx]$ sudo docker images
            REPOSITORY TAG IMAGE ID CREATED SIZE
            nginx yunweijia 2c95163ff074 5 seconds ago 142MB
            centos ceshi adeae577d8b3 22 hours ago 359MB
            nginx latest c316d5a335a5 2 weeks ago 142MB
            hello-world latest feb5d9fea6a5 4 months ago 13.3kB
            centos 7 eeb6ee3f44bd 4 months ago 204MB
            [yunweijia@localhost nginx]$

            验证:

              [yunweijia@localhost nginx]$ sudo docker run -d nginx:yunweijia
              69f76ab38fb273a5ad7c423e5667b6e0c632fc3acbc057bd82c824957a5b6fe1
              [yunweijia@localhost nginx]$
              [yunweijia@localhost nginx]$ sudo docker ps
              CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
              69f76ab38fb2 nginx:yunweijia "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 80/tcp musing_liskov
              [yunweijia@localhost nginx]$ 
              [yunweijia@localhost nginx]$ sudo docker exec -it 69f76ab38fb2 /bin/bash
              root@69f76ab38fb2:/# cd usr/share/nginx/html/
              root@69f76ab38fb2:/usr/share/nginx/html# cat index.html
              这是运维家进行测试的一个nginx镜像
              root@69f76ab38fb2:/usr/share/nginx/html# exit
              exit
              [yunweijia@localhost nginx]$

              COPY

              复制文件,将宿主机的文件或者目录复制到容器指定目录中。

                语法:COPY [--chown=<user>:<group><源路径> <目标路径>
                  [--chown=<user>:<group>] :可选参数,用户改变复制到容器内文件的用户和组
                  <目标路径>:不需要提前创建好,如果不存在,会自动创建
                实例:
                  COPY /home/yunweijia/test.sh home/

                CMD
                    类似于RUN命令,不同之处如下:
                  CMD:在docker run 时运行。
                  RUN:是在 docker build时运行。
                      作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
                      注意:如果dockerfile中存在多个CMD指令,那么只有最后一个生效。
                    语法:
                    CMD <shell 命令>
                    CMD ["<param1>","<param2>",...]

                    ENTRYPOINT

                        类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序,这句话什么意思呢,就是说你ENTRYPOINT指定的东西,如果需要参数,那么你用docker run的时候可以再指定。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。

                        优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

                        注意:如果 dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

                      语法:
                        ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

                          可以搭配CMD命令使用,实例如下:
                        # 假设你通过以下Dockerfile文件,生成了一个nginx:ceshi镜像:
                        FROM nginx
                        ENTRYPOINT ["nginx","-c"]
                        CMD ["/usr/share/nginx/conf/nginx.conf]


                        # 不传参运行的时候
                        sudo docker run -d nginx:ceshi
                        # 容器中相当于执行了如下命令
                        nginx -c /usr/share/nginx/conf/nginx.conf


                        # 传参运行的时候
                        sudo docker run -d nginx:ceshi -c /home/nginx/nginx.conf
                        # 容器中相当于执行了如下命令
                        nginx -c /home/nginx/nginx.conf

                        ENV
                            设置环境变量
                          语法:
                          ENV <key> <value>
                          ENV <key1>=<value1> <key2>=<value2>...
                          实例:
                            ENV yunweijia 1.1.0
                            RUN echo "这个版本是$yunweijia" > /usr/share/nginx/html/index.html

                          ARG

                              构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

                              构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

                            语法:
                            ARG <参数名>[=<默认值>]


                            VOLUME

                                定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。这样子可以避免你把数据存放到docker容器里面,后面一不小心删除容器的情况。也可以避免容器随着数据的存放越来越大。
                              语法:
                              VOLUME ["<路径1>", "<路径2>"...]
                              VOLUME <路径>
                                  当然了,在启动容器的时候我们可以覆盖此项配置,使用 -v 参数即可修改挂载点。

                              EXPOSE

                                  申明端口,帮助镜像使用者理解守护端口,以方便配置映射;在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
                                语法:
                                EXPOSE <端口1> [<端口2>...]

                                WORKDIR

                                    指定工作目录,即切换目录,且此目录必须是提前创建好的。
                                  语法:
                                  WORKDIR <工作目录路径>

                                  USER
                                  用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
                                    语法:
                                      USER <用户名>[:<用户组>]

                                    HEALTHCHECK

                                        用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

                                      语法:
                                      HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
                                      HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
                                      HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

                                      ONBUILD

                                      用于延迟构建命令的执行。简单的来说,比如你此次创建的镜像A,使用了ONBUILD指定了一个命令,那么你在构建镜像A中是不会执行这个命令的;但是当有人用你的镜像A构建其他镜像的时候,就会执行ONBUILD指定的命令了。

                                        语法:
                                        ONBUILD <其它指令>


                                        LABEL

                                            LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式。

                                          语法:
                                          LABEL <key>=<value> <key>=<value> <key>=<value> ...
                                          实例:
                                            LABEL image.authors="运维家"


                                          至此,使用dockerfile构建镜像结束。后面的文章中我们将使用dockerfile构建nginx、redis等镜像。
                                          文章转载自运维家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                          评论