linuxea:白话容器之使用dockerfile创建简单镜像1(18)


我们在安装一个nginx的时候,通常需要进行定制化模块和配置参数等。在nginx打包时候会使用一些默认的参数来定义并启动。

通常我们在使用一个容器的时候,要么进入容器内修改配置文件,而后重载,在没有使用容器的时候,一般我们通过nginx reload加载,但是在容器中,不得已删除在启动。

并且在dockerhub上拖一个nginx镜像的时候,不一定是符合我们需要的,我们可以进行修改,而后在commit,将可写层在打包,基于容器的自定义方式,但是这样比nginx relaod更加麻烦了,镜像的体积处理不当也会变的特别大。

配置文件打包进容器后,要修改也是一件麻烦事。特别是当在一个环境里面,我们可能多次使用,变更。如:测试,开发,生产等。这样的配置变更是常规的操作,那就意味着需要重新构建多个镜像,这显然是又增加了操作,这样的环境中配置文件写入到容器内在有些时候是不可取的,当然如果有一定的需求,也是可以接受。

其实可以自己制作镜像,封装应用程序到镜像中,存储卷将配置文件挂载到相应目录,这样也是可以的。

那么在docker是如何解决的?

仍然以nginx为例,如果此刻我需要一个虚拟主机,有一个域名,一个端口,一个目录,在nginx配置文件中的conf.d下,我们保存一个文件server.conf,内容如下:

{
    server_name $NGINX_SERVER_NAME;
    listen $NGINX_IP:$NGINX_PORT;
    root $DOC_ROOT
}

相信你也看到了,以这种变量的方式,在容器内部应用程序启动之前,使用一个程序,这个程序根据镜象中的某个文件,在镜象启动的时候向内部传递变量。这个程序将用户传递的变量替换保存在上述的server.conf文件中,而后由这个程序在启动主进程,而后退出。

  • 有一个进程启动另外一个进程并替换当前进程,exec

使用配置文件的方式需要一个文件。当然,也可以直接加载系统当前环境变量中的数据,而后替换。这也是其中的表现之一。

通常也会有默认的参数,如果不进行变量替换,也会有默认的参数启动。

I. dockerfile

此前我们知道,制作镜像的方式有两种,一种基于镜像,一种基于dockerfile,而docker镜像构建之前都已经试过。

dockerfile包含制作镜像的代码,包含命令指令,通过指令运行一些命令。
dockerfile由两类组成,注释信息和指令(参数)。

  • 在dockerfile文件中指令是大写的,但是并不区分
  • dockerfile执行的顺序是从上往下执行的,第一个非注释行必须是FROM
  • dockerfile的目录必须是独有的
  • dockerfile文件首字母必须是大写(Dockerfile)
  • dockerfile中引用的文件,必须在同Dockerfile目录,或者目录下的目录或者文件

dockererignore

dockererignore

dockerfile还支持一个隐藏文件.dockererignore file。在.dockererignore当中可以写入很多文件,支持通配符

但凡写入到dockererignore的文件路径,在打包的时候都不会包含进去

而后通过docker build命令在dockerfile的独有目录下进行打包,打标签,推送镜像到仓库。

相比之前的镜像中使用docker打包可写层,而在基于dockerfile制作镜像的时候,不用启动容器,但是这个过程是docker build来完成。而docker build也是隐藏式的启动一个容器,只不过这个容器不是用我们自己手动去启动而已。

而dockerfile中的命令是在dockerfile中FROM的基础镜像之上运行的,如果基础镜像中没有dockerfile中的命令,是无法正常执行的。那么你可能需要进行安装才可以使用。

Environment replacement

Environment replacement

之前说的环境变量是使用环境变量来做一些替换,在启动容器时候的环境变量,这里的环境变量是说dockerfile中的环境变量,和docker build有关,并且和shell非常相像,如:

ENV NGINXPORT=80

引用时候,直接引用,也可以加花括号

$NGINXPORT AND ${NGINXPORT}

并且还支持shell一样的两种变量替换的特殊格式,如下:

${variable:-word}
${variable:+word}

${variable:-word}: 这种说明,如果variable未设置或为空,就默认值为word,如果设定就替换设定值

${variable:+word}:这种说明,如果variable值不是空,有值的时候就显示为word

FROM

  • FROM

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

实践中,基准镜像可以是任何可用镜像文件,默认i情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件。

如果找不到指定的镜像文件,docker build会返回一个错误信息。

语法格式:

 FROM <repository>[:<tag>]
 FROM <repository>@:<digest>

FROM <repository>[:<tag>] 镜象仓库: 标签,这个标签是可以省略的,省略时默认为latest;

FROM <repository>@:<digest> 镜象仓库:哈希码

MAINTAINER

  • MAINTAINER

MAINTAINER用于让Dockerfile制作者提供本人的详细信息,在Dockerfile中MAINTAINER并不限制出现在那个位置,我们建议你放在FROM后面

 MAINTANIER "www.linuxea.com"

LABEL

  • LABEL

在较为新的版本上,LABEL替换了MAINTAINER,而LABEL是让用户给镜象指定很多元数据:

<key>=<value> <key>=<value> <key>=<value> <key>=<value> <key>=<value> <key>=<value>

MAINTAINER的信息可以作为LABEL的一个键值对,并且MAINTAINER在最新版本中是可以兼容的

COPY

  • COPY

用于将宿主机的文件复制到创建的新镜象中。在Dockerfile的当前目录中,将某一个文件或者几个文件复制到目标镜象的文件中

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

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

dest:目标路径,即正在创建的image的文件系统路径,建议为使用绝对路径,否则,COPY制定则以WORKDIR为起始路径。

文件复制准则:

  • 必须是build上下文中的路径,不能说其父目录中的文件
  • 如果是是目录,则其内部文件或者子目录会被递归复制,但目录自身不会被复制
  • 如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以/结尾
  • 如果事先不存在,他将会自动创建,这包括其父目录路径

我们复制一个文件

COPY index.html /data/wwwroot

到此为止就已经可以做一个镜象

[root@linuxEA_10_10_240_145 /data/linuxea]$ cat Dockerfile 
# describe : test
FROM busybox:latest
MAINTAINER www.linuxea.com
LABEL maintainer="www.linuxea.com"
COPY index.html /data/wwwroot/index.html

在当前目录创建一个index.html

[root@linuxEA_10_10_240_145 /data/linuxea]$ echo linuxea-`date` >> ./index.html
[root@linuxEA_10_10_240_145 /data/linuxea]$ cat ./index.html
linuxea-2018年 12月 06日 星期四 19:52:14 CST

II. build

build的时候,使用-t 命名,并且COPY的文件应该和Dockerfile在同级目录,而后build,如下:

[root@linuxEA_10_10_240_145 /data/linuxea]$ docker build  -t marksugar/httpd:1 ./
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/4 : MAINTAINER www.linuxea.com
 ---> Using cache
 ---> 7f12e197dfba
Step 3/4 : LABEL maintainer="www.linuxea.com"
 ---> Using cache
 ---> c28e9c23ae2f
Step 4/4 : COPY index.html /data/wwwroot/index.html
 ---> f51ffe499c66
Successfully built f51ffe499c66
Successfully tagged marksugar/httpd:1

当进行4步后,已经打包完成

[root@linuxEA_10_10_240_145 /data/linuxea]$ docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
marksugar/httpd                                         1               f30285688fca        2 minutes ago       1.15MB

而后我们查看下刚才创建的文件是否已经被打包到/data/wwwroot/index.html中

使用cat /data/wwwroot/index.html,如下

[root@linuxEA_10_10_240_145 /data/linuxea]$ docker run --name linuxea1 --rm marksugar/httpd:1 cat /data/wwwroot/index.html
WARNING: IPv4 forwarding is disabled. Networking will not work.

linuxea-2018年 12月 06日 星期四 19:52:14 CST

如上,已经被成功打包。

那如果我要COPY目录的话,就需要这样来写,如,copy /etc/zabbix/目录到容器中,如下:

先复制目录到当前目录下,也就是和Dockerfile同级目录

[root@linuxEA_10_10_240_145 /data/linuxea]$ cp -r /etc/zabbix/ ./

Dockerfile如下:

[root@linuxEA_10_10_240_145 /data/linuxea]$ cat Dockerfile
# describe : test
FROM busybox:latest
MAINTAINER www.linuxea.com
LABEL maintainer="www.linuxea.com"
COPY index.html /data/wwwroot/index.html
COPY zabbix /data/wwwroot/zabbix/

而后build

[root@linuxEA_10_10_240_145 /data/linuxea]$ docker build  -t marksugar/httpd:2 ./
Sending build context to Docker daemon  33.28kB
Step 1/5 : FROM busybox:latest
 ---> 59788edf1f3e
Step 2/5 : MAINTAINER www.linuxea.com
 ---> Using cache
 ---> 7f12e197dfba
Step 3/5 : LABEL maintainer="www.linuxea.com"
 ---> Using cache
 ---> c28e9c23ae2f
Step 4/5 : COPY index.html /data/wwwroot/index.html
 ---> Using cache
 ---> f51ffe499c66
Step 5/5 : COPY zabbix /data/wwwroot/zabbix/
 ---> eb31fdcfcd13
Successfully built eb31fdcfcd13
Successfully tagged marksugar/httpd:2

验证/data/wwwroot/zabbix目录下的文件是否存在

[root@linuxEA_10_10_240_145 /data/linuxea]$ docker run --name linuxea1 --rm marksugar/httpd:2 ls /data/wwwroot/zabbix
WARNING: IPv4 forwarding is disabled. Networking will not work.
scripts
zabbix_agentd.conf
zabbix_agentd.d
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2019-01-10分类: Docker

标签: 白话容器, dockerfile

发表评论