计算机系统应用教程网站

网站首页 > 技术文章 正文

「技术指南」Dockerfile详解篇(一)

btikc 2024-09-27 01:13:37 技术文章 4 ℃ 0 评论

# Nginx默认配置修改 #


我们知道,在之前安装一个Nginx的话,安装完以后它通常不会运行在默认配置下,因此我们通常需要去改一改它的配置文件或者定义模块化配置文件,然后启动服务。


之前做法


第一种方式


启动容器Docker exec连进容器,在内部执行 vi ,再Reload重启。


第二种方式


假设我们把它对应的那个配置文件的路径做存储卷,从我们宿主机上加载文件,在宿主机上进行编辑,也能让它立即生效,启动容器之前先把它编辑好。


(容器启动之前,我们事先找一目录把配置文件准备好,然后启动容器时,把容器内的应用程序默认加载配置文件的路径与宿主机上的目录进行建立关联关系,然后去启动容器,也能加载到在宿主机上定制的配置文件。)


缺点

我们在宿主上做的编辑,能不能让它立即生效呢?
比如我们启动以后发现,有些参数还是需要改,改完以后依然需要重载才能生效。

自制镜像

法格式

基于容器


基于容器,先启动起来,交互式连入进来,做修改。改完以后,改的结果一定是保存在最上层的可写层的。这个时候我们把可写层保存在一个新镜像中,而后,我们再去创建容器时,根据我们自己所创建的镜像来使用。


缺点


做的镜像也是直接把文件备进镜像中的、写死在镜像中的。如果我们想再改是改不了的。

对运维来讲,运行过程当中去修改配置的需求是日常操作。

很多时候,需要随时进行修改,但那依然解决不了问题。而且这种备进镜像的设计方式,最悲惨的地方在于:一次更新,维护复杂。建议环境简单的时候可以使用。



# 基于Dockerfile #



Dockerfile,相当于是一个文档,客户可以基于Dockerfile生成新的容器。


Dockerfile
仅仅是用来制作镜像的源码文件,是构建容器过程中的指令,Docker能够读取Dockerfile的指定进行自动构建容器,基于Dockerfile制作镜像,每一个指令都会创建一个镜像层,即镜像都是多层叠加而成。


因此,层越多,效率越低,创建镜像,层越少越好,能在一个指令完成的动作尽量通过一个指令定义。



Docker镜像制作的工作逻辑


首先需要有一个制作镜像的目录,该目录下有个文件,名称必须为Dockerfile。


Dockerfile有指定的格式,#号开头为注释,指定默认用大写字母来表示,以区分指令和参数。


Docker build读取Dockerfile是按顺序依次Dockerfile里的配置,且第一条非注释指令必须是FROM开头,表示基于哪个基础镜像来构像,建新镜可以根据已存在的任意镜像来制作新镜像。



Dockerfile可以使用环境变量,用
ENV来定义环境变量,变量名支持Bash的变量替换,如${variable:-word},表示如果变量值存在,就使用原来的变量,变量为空时,就使用word的值作为变量的值,一般使用这个表示法。

${variable:+word},表示如果变量存在了,不是空值,那么变量将会被赋予为word对应的值,如果变量为空,那么依旧是空值。


.dcokerignore:把文件路径写入到.dockerignore,对应的路径将不会被打包到新镜像。


# 镜像相关的操作 #


镜像的生成途径


基于容器制作Dockerfile。



dockerfile 语法格式


dockerfile 语法格式
dockerfile 语法格式

#指令#


FROM


FROM指令是最重要的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境。

实践中,基准镜像可以是任何可用镜像文件。


默认情况下,Docker build会在Docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件。如果找不到指定的镜像文件,Docker build会返回一个错误信息。


FROM 语法


FROM <repository>[:<tag>] 或者


FROM <repository>@<digest>


<repository>:指定作为base image的名称


 <tag>:base image的标签,为可选项,省略时默认为 latest;


<digest>为校验码



MAINTANIER(已经废弃)

------>LABEL


它用于让镜像制作者提供本人的详细信息。

Dockerfile并不限制MAINTAINER指令可在出现的位置,但推荐将其放置于FROM指令之后。


语法


MAINTAINER <authtor's detail> l <author's detail>可是任何文本信息,但约定俗成地使用作者名称及邮件地址,如:

MAINTAINER "sunny <sunny@ghbsunny.cn>"


一般把MAINTAINER放在FROM后面。


LABEL


LABEL用于为镜像添加元数据,元数以键值对的形式指定:

LABEL <key>=<value> <key>=<value> <key>=<value> ...


使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。


推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。


如,通过LABEL指定一些元数据:

LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"


指定后可以通过Docker inspect查看:

    docker inspect itbilu/test
    "Labels": {
        "version": "1.0",
        "description": "这是一个Web服务器",
        "by": "IT笔录"
    },


COPY


COPY用于从 Docker主机复制文件至创建的新映像文件。

语法


COPY <src> ... <dest>或 . COPY ["<src>",... "<dest>"]


<src>:要复制的源文件或目录,支持使用通配符


 <dest>:目标路径,即正在创建的 image的文件系统路径;建议为 <dest>使用绝对路径,<dest>绝对路径为镜像中的路径,而不是宿主机的路径。否则, COPY指定则以 WORKDIR为其起始路径。

注意:在路径中有空白字符时,通常使用第二种格式 。



#文件复制准则#


<src>必须是Build上下文中的路径,即只能放在Workshop这个工作目录下,不能是其父目录中的文件。

如果<src>是目录,其内部文件或者子目录会被递归复制,但<src>目录自身不会被复制。

如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且dest目录必须以/结尾。

如果<dest>事先不存在,它将会被自动创建,这包括其父目录路径。


例子


创建一个目录img1,在该目录下新建index.html文件用于镜像制作的素材文件,在img1下新建Dockerfile文件,把index.html拷贝到新镜像里。

COPY是指在当前的img1工作目录中,准备好要添加到新镜像的文件放到这个img1下面。



COPY过程实际是基于Dockerfile在后台启动一个容器,把工作目录当做卷挂载到后台启动的容器,然后再把这些准备好的文件(img1目录下)拷贝到后台容器,基于这个容器制作新镜像。所以,镜像的制作过程是基于指定的镜像来制作。


COPY文件


    [root@node1 ~]# mkdir img1/
    [root@node1 ~]# cd img1/
    [root@node1 img1]# ls
    [root@node1 img1]# vim index.html
    <h1>zhujingxing </h1>
    [root@node1 img1]# vim Dockerfile
    # Description: test image
    FROM busybox:latest
    MAINTAINER "zisefeizhu <zisefeizhu@zhujingxing.com>"
    #LABEL maintainer="zisefeizhu <zisefeizhu@zhujingxing.com>"
    COPY index.html /data/web/html/




Dockerfile制作完成后,用命令build制作基于dockerfile的新镜像


    [root@node1 img1]# docker build  -t tinyhttpd:v0.1-1 ./
    Sending build context to Docker daemon  3.072kB
    Step 1/3 : FROM busybox:latest                                       //FROM
     ---> 59788edf1f3e
    Step 2/3 : MAINTAINER "zisefeizhu <zisefeizhu@zhujingxing.com>"      //MAINTAINER
     ---> Using cache
     ---> e0a3a7c1de10
    Step 3/3 : COPY index.html /data/web/html/                           //COPY
     ---> 35c00f8b6408 
    Successfully built 35c00f8b6408
    Successfully tagged tinyhttpd:v0.1-1
    [root@node1 img1]# docker image ls            //查看新生成的镜像
    REPOSITORY                                          TAG                 IMAGE ID            CREATED             SIZE
    tinyhttpd                                           v0.1-1              35c00f8b6408        9 seconds ago       1.15MB
    //启动新生成的镜像,在容器内部有目录/data/web/html/,并且有文件index.html
    [root@node1 ~]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-1 cat /data/web/html/index.html
    <h1>zhujingxing </h1>


COPY目录


[root@node1 img1]# cp -r /etc/yum.repos.d/ ./
[root@node1 img1]# ls 
Dockerfile  index.html  yum.repos.d
[root@node1 img1]# ls yum.repos.d/
CentOS-Base.repo  CentOS-Debuginfo.repo  CentOS-Media.repo    CentOS-Vault.repo  docker-ce.repo.cp
CentOS-CR.repo    CentOS-fasttrack.repo  CentOS-Sources.repo  docker-ce.repo     epel.repo
[root@node1 img1]# vim Dockerfile 
# Description: test image
FROM busybox:latest
MAINTAINER "zisefeizhu <zisefeizhu@zhujingxing.com>"
#LABEL maintainer="zisefeizhu <zisefeizhu@zhujingxing.com>"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
[root@node1 img1]# docker build  -t tinyhttpd:v0.1-2 ./
Sending build context to Docker daemon  28.67kB
Step 1/4 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/4 : MAINTAINER "zisefeizhu <zisefeizhu@zhujingxing.com>"
 ---> Using cache
 ---> e0a3a7c1de10
Step 3/4 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 35c00f8b6408
Step 4/4 : COPY yum.repos.d /etc/yum.repos.d/
 ---> 6250436df8e7
Successfully built 6250436df8e7
Successfully tagged tinyhttpd:v0.1-2


[root@node1 ~]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-2 ls /etc/yum.repos.d/
CentOS-Base.repo
CentOS-CR.repo
CentOS-Debuginfo.repo
CentOS-Media.repo
CentOS-Sources.repo
CentOS-Vault.repo
CentOS-fasttrack.repo
docker-ce.repo
docker-ce.repo.cp
epel.repo


ADD


ADD指令类似于 COPY指令, ADD支持使用 TAR文件和 URL路径。

语法


. ADD <src> ... <dest>或


. ADD ["<src>",... "<dest>"]


操作准则


操作准则同COPY指令的4点准则。

如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载,并保存为<dest>/<filename>注意,URL不能是FTP格式的URL。


如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于“tar -x”命令,然后,通过URL获取到的TAR文件将不会自动展开。

如果<src>有多个,其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果<dest>不以/结尾,则其被视作一个普通文件,<src>的内容将被直接写入到<dest>。


例子




[root@node1 img1]# vim Dockerfile 
ADD http://nginx.org/download/nginx-1.15.5.tar.gz /usr/local/src/


[root@node1 img1]# docker build  -t tinyhttpd:v0.1-3 ./
Step 5/5 : ADD http://nginx.org/download/nginx-1.15.5.tar.gz /usr/local/src/
Downloading  1.025MB/1.025MB
 ---> 77406c81872f
Successfully built 77406c81872f
Successfully tagged tinyhttpd:v0.1-3


[root@node1 ~]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-3 ls /usr/local/src
nginx-1.15.5.tar.gz


[root@node1 img1]# wget http://nginx.org/download/nginx-1.15.5.tar.gz


[root@node1 img1]# vim Dockerfile 
ADD nginx-1.15.5.tar.gz /usr/local/src/
[root@node1 img1]# docker build  -t tinyhttpd:v0.1-4 ./
Step 5/5 : ADD nginx-1.15.5.tar.gz /usr/local/src/
 ---> ff39a60ceccb
Successfully built ff39a60ceccb
Successfully tagged tinyhttpd:v0.1-4
[root@node1 ~]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-4 ls /usr/local/src
nginx-1.15.5


WORKDIR


WORKDIR为工作目录,指当前容器环境的工作目录,用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和 ADD指定设定工作目录

语法


 WORKDIR  <dirpath>


在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个 WORKDIR指令指定的路径。

另外, WORKDIR也可调用由 ENV指定定义的变量。例如:

WORKDIR /var/log
WORKDIR  $STATEPATH


例子


指定WORKDIR为/usr/local,相当于是容器启动后,会把工作目录切换到/usr/local这个WORKDIR路径下,而不是默认的根目录。

如下例子,则相对路径 ./src/ 的绝对路径为容器的/usr/local/src,制作镜像时,把Nginx包拷贝到/usr/local/src,把tomcat包解压到/usr/local/src下面

[root@node1 img1]# vim Dockerfile


FROM busybox:1.27.2


MAINTAINER "zisefeizhu <zisefeizhu@zhujingxing.com>"


WORKDIR "/usr/local"


ADD http://nginx.org/download/nginx-1.14.0.tar.gz  ./src/


ADD apache-tomcat-8.0.47.tar.gz ./


启动容器并检查


[root@node1 img1]# docker run -it --rm --name testworkdir testworkdir:v1


/usr/local # ls


apache-tomcat-8.0.47  src


/usr/local # ls src


nginx-1.14.0.tar.gz


/usr/local #


容器启动后,工作路径直接切换为/usr/local

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表