一、dockerfile的参数指令

1、dockerfile介绍

dockerfile是用来构建镜像的,相当于手动docker commit -t xxx -a xxx
dockerFile:就是镜像的源码文件,通过docker build命令将dockerfile制作成镜像,当启动镜像的时候会运行镜像里面dockerfile的文件指令

Dockerfile是用来构建Docker镜像的源文件,是由一系列命令和参数构成的脚本。 
    构建三步骤:1、编写dockerfile文件;2、docker build生成镜像;3、docker run运行镜像

  dockerfile内容基础知识: 
        1、每条指令必须为大写字母且后面要跟随至少一个参数; 
        2、指令安装从上到下,顺序执行; 
        3#号表示注释; 
        4、 每条指令都会创建一个新的镜像层,并对镜像进行提交; 
 dockerfile执行的大致流程: 
        1、docker从基础镜像运行一个容器; 
        2、执行一条指令并对容器做修改; 
        3、执行类似docker commit的操作提交一个新的镜像层; 
        4、docker再基于刚提交的镜像运行一个新的容器; 
        5、执行dockerfile中的下一条指令直到所有指令都执行完成。 
    总结:从应用软件的角度来看,dockerfile,docker镜像与docker容器分别代表软件的三个不同阶段: 
        a) dockerfile是软件的原材料; 
        b)docker镜像是软件的交付品 
        c)docker容器则可以认为是软件的运行态。 
    dockerfile面向开发,docker镜像成为交付标准,docker容器则涉及部署与运维,三者缺一不可,合力充当docker体系的基石。 
image.png
    所以,以后开发向运维工程师就不再交部署文件了,而是交镜像。运维工程师拿到镜像,生成容器运行就可以了。

2、dockerfile保留字指令

FROM:基础镜像,当前新镜像是基于哪个镜像的 

MAINTAINER:镜像维护者的姓名和邮箱地址
举例:MAINTAINER xxx@163.com

RUN:容器启动后需要运行的命令,这个是在容器里面运行的命令
例如:RUN useradd wenqiang


ENV:用来在构建镜像过程中设置环境变量。 
举例:ENV MY_PATH /usr/mytest
ENV这个环境变量可以在后续的任何RUN指令中使用,其实就是定义了一个路径的变量,比如RUN cd $MY_PATH

WORKDIR:指定在容器创建后,终端默认登录进来的工作目录,一个落脚点,它也是CD命令
例如:WORDIR $MY_PATH

ADD:将宿主机目录下的文件拷贝到镜像里面并解压出来,ADD既有copy的功能又有解压缩的功能
例如:ADD /root/centos.tar.gz  /container

COPY:类似ADD,将宿主机目录下的文件拷贝到镜像里面,但是它只是拷贝,不会自动处理压缩包。
它的使用方法有两种:COPY src test 和 COPY ["src","dest"] 

VOLUME:创建容器数据卷,用于数据保存和持久化工作,这里不支持指定宿主机的挂载目录,该参数会在宿主机随机创建挂载目录防止容器删除数据无法恢复的问题发生 https://www.cnblogs.com/cheyunhua/p/16923339.html
例如:VOLUME ["/datavolumecontainer1"] 

CMD:容器启动时指定的COMMAND命令,会在启动容器docker run时候执行COMMAND命令。dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的CMD参数替换。 
例如:CMD /bin/bash
如果运行docker run -it -d --name="web1" httpd:2.4.3  /bin/batch,就会替换掉/bin/bash

ENTRYPOINT:容器启动时指定的COMMAND命令,会在启动容器的同时执行COMMAND命令。ENTRYPOIT的目的和CMD一样,ENTRYPOINT不会被docker run之后的CMD参数替换。
例如:ENTRYPOINT /bin/bash
即使运行docker run -it -d --name="web1" httpd:2.4.3 /bin/batch,也不会替换掉/bin/bash

EXPOSE:当前容器需要启动的端口号,容器内必须要有对应的服务,如果做好镜像通过docker run 不指定端口则不会对外暴露
例如:EXPOSE 6379

ONBUILD(触发器):当子镜像继承(FROM)父镜像的时候,子镜像启动的时候就会触发父镜像的ONBUILD参数。 
例如:父镜像是centos:7.5,父镜像的dockerfile如下
            FROM xxxx
            ONBUILD RUN echo "子镜像已经启动"
     子镜像的dockerfile内容如下,子镜像启动后会触发父镜像的ONBUILD参数 
                  FROM centos:7.5

二、通过dockerfile创建镜像

举例一

1、写一个简单的dockerfile

(1)准备源镜像(必须存在一个源镜像,需要以这个镜像为基础来制作新的镜像)
[root@localhost ~]# docker images|grep centos
centos                    latest              9f38484d220f        4 months ago        202MB

(2)在docker宿主机创建一个dockerfile文件
[root@localhost ~]# cat /root/dockerfile 
#指定基础镜像
FROM centos
#镜像维护者
MAINTAINER wenqiangit@163.com
#定义环境变量
ENV MY_PATH /tmp
#指定用户登陆进容器的所在目录
WORKDIR $MY_PATH
#指定启动容器后执行的命令
RUN yum -y install vim net-tools
RUN mkdir ./testDIR
#指定启动容器时需要启动的端口,内部必须有80服务,可通过docker ps查看
EXPOSE 80
#指定启动容器时指定的COMMAND环境,可通过docker ps查看
CMD /bin/bash

(3)通过docker build命令将dockerfile制作成镜像
[root@localhost ~]# mkdir /test; cd /test
[root@localhost test]# docker build -t mr.wen-centos:latest -f /root/dockerfile .
......
......
Successfully built 72c6fd40312c
Successfully tagged mr.wen-centos:latest
-------------------------------------------------
解释:
docker build    #创建镜像文件
-t              #为创建的镜像起个新的名字
-f              #指定dockerfile文件的绝对路径,如果使用ADD COPY最好在一个空目录下通过 . 执行build
.               #点表示会将当前路径下的所有内容发送给docker daemon用来构建镜像上下文环境,所以制作镜像时最好找一个空目录

(4)查看做好的镜像
[root@localhost ~]# docker images
REPOSITORY        TAG           IMAGE ID         CREATED           SIZE
mr.wen-centos     latest        cc19126fce77     5 minutes ago     369MB

(5)启动容器并查看启动状态
[root@localhost ~]# docker run -it -d --name="web1" mr.wen-centos
015b02b9b30f7e125b2cc6154a05952389b1c0d11b7839fb8459830c8d582250
[root@localhost ~]# docker ps                                                 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAS
015b02b9b30f        mr.wen-centos       "/bin/sh -c /bin/bash"   8 seconds ago       Up 6 seconds        80/tcp              we1

(6)进入容器验证
[root@localhost ~]# docker exec -it web1 /bin/bash
[root@015b02b9b30f tmp]# pwd
/tmp                                  #用户登录进容器的所在目录
[root@015b02b9b30f tmp]# ls           
testDIR                               #启动容器后创建的目录
#启动容器后安装的vim 和 ifconfig命令
[root@015b02b9b30f tmp]# rpm -qa |grep -E "vim|ifconfig"    
vim-minimal-7.4.160-5.el7.x86_64
vim-common-7.4.160-6.el7_6.x86_64
vim-filesystem-7.4.160-6.el7_6.x86_64
vim-enhanced-7.4.160-6.el7_6.x86_64

举例二
1、通过dockerfile脚本制作带有容器数据卷功能的镜像
0、必须存在一个源镜像,需要以这个镜像为基础来制作新的镜像

[root@localhost ~]# docker images|grep centos
centos                    latest              9f38484d220f        4 months ago        202MB

1、创建dockerfile文件

[root@localhost ~]# cat dockerfile
# volume test
FROM centos      #指定新镜像来源于哪个镜像,需要先指定一个原始镜像
VOLUME ["/datavolumecontainer1"]  #当运行新镜像时会在容器内创建容器数据卷,对应宿主机目录通过docker inspect查看
CMD echo "finished,-----------SUCCESS1"  #启动新镜像时执行的命令
CMD /bin/bash                            #启动新镜像时指定的COMMAND
```
2、创建新的镜像文件
```
[root@localhost ~]# mkdir /test ; cd /test
[root@localhost ~]# docker build -t wen-centos -f /root/dockerfile .
Sending build context to Docker daemon    198MB
Step 1/4 : FROM centos
 ---> 9f38484d220f
............
............
Step 4/4 : CMD /bin/bash
 ---> Running in 766fb3995cf6
Removing intermediate container 766fb3995cf6
 ---> 7fd6ac8acc2f
Successfully built 7fd6ac8acc2f
Successfully tagged wen/centos:latest
-------------------------------------------------
解释:
docker build    #创建镜像文件
-t              #为创建的镜像起个新的名字
-f              #指定dockerfile文件的绝对路径
.               #点表示会将当前路径下的所有内容发送给docker daemon用来构建镜像上下文环境,所以制作镜像时最好找一个空目录
```
3、查看新创建的镜像
```
[root@localhost ~]# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
wen-centos                latest              fdeebdd83abb        18 seconds ago      202MB
```
4、启动新创建的镜像到容器
```
[root@localhost ~]# docker run -it -d --name="wen" wen-centos
f1993ecda05ef3f78a13698f20c79cadfae05deb23fdc55ff172ca8d6a4f92ba
[root@localhost ~]# docker ps
CONTAINER ID    IMAGE     COMMAND   CREATED   STATUS    PORTS         NAMES
f1993ecda05e    wen-centos     "/bin/sh -c /bin/bash"   10 seconds ago   Up 8 seconds    wen
```
5、进入容器查看容器数据卷
```
[root@localhost ~]# docker exec -it wen /bin/bash
[root@f1993ecda05e /]# cd datavolumecontainer1/
[root@f1993ecda05e datavolumecontainer1]# touch container123.txt
```
6、回到docker宿主机,查看对应宿主机的目录
```
[root@localhost ~]# docker inspect wen
"Mounts": [
            {
                "Type": "volume",
                "Name": "b87ad29eae31da426cf835048f1afe3865e1e89984638d847d7743cc15e9718b",
                "Source": "/var/lib/docker/volumes/b87ad29eae31da426cf835048f1afe3865e1e89984638d847d7743cc15e9718b/_data",
                "Destination": "/datavolumecontainer1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
```
7、进入宿主机目录
```
[root@localhost ~]# cd /var/lib/docker/volumes/b87ad29eae31da426cf835048f1afe3865e1e89984638d847d7743cc15e9718b/_data
[root@localhost _data]# ls
container123
```



举例三
1、CMD 和 ENTRYPOINT区别
```
CMD:手动加入的命令优先级最高并且会覆盖dockerfile中指定的CMD命令
ENTRYPOINT:手动加入的命令不会覆盖dockerfile中指定的ENTRYPOINT命令
```
一、CMD使用案例
```
(1)创建dockerfile文件
[root@localhost ~]# cat /tmp/dockerfile1 
FROM centos   #基础镜像
CMD ls        #启动容器的时候会执行ls命令

(2)制作镜像
[root@localhost ~]# cd /soft/   #进入空目录
[root@localhost soft]# docker build -t "test1:1.1" -f /tmp/dockerfile1 .

(3)查看镜像
[root@localhost soft]# docker images test1
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
test1               1.1                 a4f17c68e6b7        About a minute ago   202MB

(4)正常启动镜像,会看到执行ls命令成功
[root@localhost soft]# docker run -it --name="test1" test1:1.1
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

(5)启动镜像的时候再加一些命令,会覆盖掉dockerfile里面的命令
[root@localhost soft]# docker run -it --name="test3" test1:1.1 df -mh
Filesystem               Size  Used Avail Use% Mounted on
overlay                   17G  7.2G  9.9G  43% /
tmpfs                     64M     0   64M   0% /dev
```
                        
二、ENTRYPOINT使用案例
```
(1)创建dockerfile文件
[root@localhost ~]# cat /tmp/dockerfile2
FROM centos     #基础镜像
ENTRYPOINT ls   #启动容器的时候会执行ls命令

(2)制作镜像
[root@localhost ~]# cd /soft/   #进入空目录
[root@localhost soft]# docker build -t "test2:2.2" -f /tmp/dockerfile2 .

(3)查看镜像
[root@localhost ~]# docker images test2
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test2               2.2                 cf9a5fc10942        29 seconds ago      202MB

(4)正常启动镜像,会看到执行ls命令成功
[root@localhost ~]# docker run -it --name="test6" test2:2.2
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

(5)启动镜像的时候再加一些命令,不会生效,仍然会执行dockerfile中的命令
[root@localhost ~]# docker run -it --name="test11" test2:2.2 df -mh
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

```
举例四
1、ONBUILD的案例
ONBUILD:子镜像继承父镜像启动时会触发ONBUILD参数
一、制作父镜像
```
(1)编写父镜像dockerfile文件
[root@localhost ~]# cat /tmp/father-dockerfile 
FROM centos
ONBUILD RUN echo "the sun is running"   #子镜像启动时会触发这条规则
(2)制作成父镜像
[root@localhost ~]# docker build -f /tmp/father-dockerfile -t father:1.1 .
(3)查看父镜像
[root@localhost ~]# docker images father
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
father              1.1                 a35800001969        About a minute ago   202MB
```
二、制作子镜像
```
(1)编写子镜像dockerfile文件
[root@localhost ~]# cat /tmp/son-dockerfile 
FROM father:1.1      #继承了父镜像
CMD /bin/bash
(2)制作成子镜像
[root@localhost ~]# docker build -f /tmp/son-dockerfile -t son:1.1 .
Sending build context to Docker daemon  198.1MB
Step 1/2 : FROM father:1.1
# Executing 1 build trigger
 ---> Running in 4ae1e72554fc
the sun is running                                  #看这里已经触发了父镜像ONBUILD规则
Removing intermediate container 4ae1e72554fc
 ---> 4af663723acb
Step 2/2 : CMD /bin/bash
 ---> Running in a14b92a1b7fe
Removing intermediate container a14b92a1b7fe
 ---> 053bc677f372
Successfully built 053bc677f372
Successfully tagged son:1.1
(3)查看子镜像
[root@localhost ~]# docker images son
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
son                 1.1                 053bc677f372        About a minute ago   202MB

```


























点击阅读全文
Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐