03 Docker高级实践

第三章 Docker高级实践

一、Dockerfile

在这一部分我们来介绍一些Docker的高级内容: Dockerfile和Docker compose。

1 Dockerfile简介

  1. 什么是Dockerfile

    类似于我们学习过的脚本,将我们在上面学到的docker镜像,使用自动化的方式实现出来。

  2. Dockerfile的作用

    1. 找一个镜像:ubuntu
    2. 创建一个容器: docker run ubuntu
    3. 进入容器: docker exec -it 容器命令
    4. 操作:各种应用配置....
    5. 构造新镜像: docker commit
  3. Dockerfile使用准则

    1. 大:首字母必须大写D
    2. 空:尽量将Dockerfile放在空目录中。
    3. 单:每个容器尽量只有一个功能。
    4. 少:执行的命令越少越好。
  4. Dockerfile分为四部分

    1. 基础镜像信息
    2. 维护者信息
    3. 镜像操作指令
    4. 容器启动时执行指令
  5. Dockerfile文件内容

    1. 首行注释信息
    2. 指令(大写)参数
  6. Dockerfile使用命令

    #构建镜像命令格式:
    docker build -t [镜像名]:[版本号][Dockerfile所在目录]
    #构建样例:
    docker build -t nginx:v0.2 /opt/dockerfile/nginx/
    
    #参数详解:
    	-t                      指定构建后的镜像信息,
    	/opt/dockerfile/nginx/  则代表Dockerfile存放位置,如果是当前目录,则用 .(点)表示
    

2 Dockerfile快速入门

接下来我们快速的使用Dockerfile来基于ubuntu创建一个定制化的镜像: nginx。

  • 创建文件目录
#创建Dockerfile专用目录
$ mkdir -p docker-file/dockerfile/nginx
$ cd ./docker-file/dockerfile/nginx/

#在其中创建Dockerfile文件
$ vim Dockerfile

  • 在Dockerfile中书写内容:
# 构建一个基于ubuntu的docker定制镜像
# 基础镜像
FROM ubuntu

# 镜像作者
MAINTAINER yangyi yangyi@163.com

# 执行命令
RUN mkdir hello
RUN mkdir world
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install nginx -y

# 对外端口
EXPOSE 80

  • 进行构建操作
#构建镜像
$ docker build -t ubuntu-nginx:v1.0 .  # 依赖当前文件夹下面的Dockerfile创建文件

#查看新生成镜像
$ docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
ubuntu-nginx      v1.0      0dcd373157ad   11 minutes ago   167MB

#查看构建历史
$ docker history 0dcd373157ad
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
0dcd373157ad   23 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
a4f1dd0a918d   23 minutes ago   /bin/sh -c apt-get install nginx -y             59.2MB    
0ffb9d0eee7b   24 minutes ago   /bin/sh -c apt-get update                       34.6MB    
99a68a02a088   27 minutes ago   /bin/sh -c sed -i 's/security.ubuntu.com/mir…   2.76kB    
393d63c34bee   27 minutes ago   /bin/sh -c sed -i 's/archive.ubuntu.com/mirr…   2.76kB    
1cafc34dadf0   27 minutes ago   /bin/sh -c mkdir world                          0B        
0361a0a98448   27 minutes ago   /bin/sh -c mkdir hello                          0B        
9db7f118dcc3   27 minutes ago   /bin/sh -c #(nop)  MAINTAINER yangyi yangyi@…   0B        
2b4cba85892a   2 weeks ago      /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      2 weeks ago      /bin/sh -c #(nop) ADD file:8a50ad78a668527e9…   72.8MB 

#注意:
因为容器没有启动命令,所以肯定访问不了

注:每次操作都是通过镜像生成容器,容器中进行操作之后,在生成镜像,将之前的镜像删除,如此循环往复,直到生成最终的结果。

  • 运行修改好的Dockerfile进行构建
# 构建一个基于ubuntu的docker定制镜像
# 基础镜像
FROM ubuntu

# 镜像作者
MAINTAINER yangyi yangyi@163.com

# 执行命令
RUN mkdir hello && mkdir world
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get install nginx -y

# 对外端口
EXPOSE 80

#运行Dockerfile
$ docker build -t ubuntu-nginx:v0.2 .

#查看历史信息
$ docker history ubuntu-nginx:v0.2

#对比两个镜像的大小
$ docker images

#深度对比连个镜像的大小
$ docker inspect a853de1b8be4
$ docker inspect eaba9bd1c4ac

注:命令越少,构建的镜像越小一下。【因为有了一些日志信息😄 】

Dockerfile构建过程

  • 从基础镜像1运行一个容器A
  • 遇到一条Dockerfile指令,都对容器A做一次修改操作
  • 执行完毕─条命令,提交生成一个新镜像2
  • 再基于新的镜像2运行一个容器B
  • 遇到一条Dockerfile指令,都对容器B做一次修改操作
  • 执行完毕─条命令,提交生成一个新镜像
  • ...

构建过程中,创建了很多镜像,这些中间镜像,我们可以直接使用来启动容器,通过查看容器效果,从侧面能看到 我们每次构建的效果。提供了镜像调试的能力。

3 基础指令详解

  • FROM

    FROM
    #格式:
    	FROM <image>
    	FROM <image>:<tag>
    #解释:
    	#FROM 是 Dockerfile 里的第一条而且只能是除了首行注释之外的第一条指令
    	#可以有多个FROM语句,来创建多个image
    	#FROM 后面是有效的镜像名称,如果该镜像没有在你的本地仓库,那么就会从远程仓库Pull取,如果远程也没有,就报错失败
    	#下面所有系统可执行指令,都在FROM的镜像中执行。
    
  • MAINTAINER

    MAINTAINER
    #格式:
    	MAINTAINER <name>
    #解释:
    	#指定该dockerfile文件的维护者信息。类似我们在docker commit 时候使用-a参数指定的信息
    
  • RUN

    RUN
    #格式:
    	RUN <command> (shell模式)
    	RUN["executable", "param1", "param2"] (exec 模式)
    #解释:
    	#表示当前镜像构建时候运行的命令,如果有确认输入的话,一定要在命令中添加 -y【确认,确认软件是否安装等等】
    	#如果命令较长,那么可以在命令结尾使用 \ 来换行
    	#生产中,推荐使用上面数组的格式
    #注释:
    	#shell模式:类似于 /bin/bash -c command
    #举例: RUN echo hello
    	#exec模式:类似于 RUN["/bin/bash", "-c", "command"]
    	#举例: RUN["echo", "hello"]
    
  • EXPOSE

    EXPOSE
    #格式:
    	EXPOSE <port> [<port>...]
    #解释:
    	#设置Docker容器对外暴露的端口号,Docker为了安全,不会自动对外打开端口,如果需要外部提供访问,还需要启动容器时增加-p或者-P参数对容器的端口进行分配。
    

4 运行时指令详解

  • CMD

    CMD
    #格式:
        CMD ["executable","param1","param2"] (exec 模式)推荐
        CMD command param1 param2 (shell模式)
        CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数;
        
    #解释:
        #CMD指定容器启动时默认执行的命令
        #每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行
        #如果你在启动容器的时候使用docker run 指定的运行命令,那么会覆盖CMD命令。
        #举例: CMD ["/usr/sbin/nginx","-g","daemon off;"]
        "/usr/sbin/nginx" nginx命令
        "-g" 设置配置文件外的全局指令
        "daemon off;" 后台守护程序开启方式 关闭
        
    #CMD指令实践:
        #修改Dockerfile文件内容:
        #在上一个Dockerfile文件内容基础上,末尾增加下面一句话:
        CMD ["/usr/sbin/nginx","-g","daemon off;"]
        #构建镜像
        $ docker build -t ubuntu-nginx:v0.3 .
        #根据镜像创建容器,创建时候,不添加执行命令【就会执行CMD中的】
        $ docker run --name unginx-1 -itd ubuntu-nginx:v0.3
        #根据镜像创建容器,创建时候,添加执行命令/bin/bash【会覆盖Dockerfile中的CMDg】
        $ docker run --name unginx-2 -itd ubuntu-nginx:v0.3 /bin/bash
        #查看启动的容器
        $ docker ps
        #发现两个容器的命令行是不一样的
        $ docker ps -a
        CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS                  PORTS     NAMES
    a68ffd3e38b2   ubuntu-nginx:v3.0   "/bin/bash"              18 minutes ago   Up 18 minutes           80/tcp    unginx-2
    15c04f36bd02   ubuntu-nginx:v3.0   "/usr/sbin/nginx -g …"   20 minutes ago   Up 20 minutes           80/tcp    unginx-1
    

    切换到新的路径下

    进行Dockerfile文件修改

    构建新的镜像ubuntu-nginx:v3.0

    使用两种方式生成容器:

  • ENTRYPOINT

    ENTRYPOINT
    #格式:
        ENTRYPOINT ["executable", "param1","param2"] (exec 模式)
        ENTRYPOINT command param1 param2 (shell 模式)
    #解释:
        #和CMD 类似都是配置容器启动后执行的命令,并且不会被docker run提供的参数覆盖。
        #每个Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。
        #生产中我们可以同时使用ENTRYPOINT 和CMD,
        #想要在docker run 时被覆盖,可以使用"docker run --entrypoint"
    #ENTRYPOINT指令实践:
        #修改Dockerfile文件内容:
        #在上一个Dockerfile 文件内容基础上,修改末尾的CMD 为ENTRYPOINT:
        ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
        
        #构建镜像
        $ docker build -t ubuntu-nginx:v0.4 .
        #根据镜像创建容器,创建时候,不添加执行命令
        $ docker run --name unginx-3 -itd ubuntu-nginx:v0.4
        #根据镜像创建容器,创建时候,添加执行命令/bin/bash
        $ docker run --name unginx-4 -itd ubuntu-nginx:v0.4 /bin/bash
    	
    	#查看ENTRYPOINT是否被覆盖
    	$ docker ps -a
    
    	#根据镜像创建容器,创建时候,使用--entrypoint参数,添加执行命令/bin/bash
    	$ docker run --entrypoint "/bin/bash" --name nginx-5 -itd ubuntu-nginx:v0.4
    	
    	#查看ENTRYPOINT是否被覆盖
    	$ docker ps
    	CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS                      PORTS     NAMES
    6d54b6ff0209   ubuntu-nginx:v4.0   "/bin/bash"              2 minutes ago    Up 2 minutes                80/tcp    unginx-5
    
    

    切换到新的路径下

    进行Dockerfile修改

    构建新的镜像ubuntu-nginx:v4.0

    使用两种方式生成容器:

    两种方式之间的区别

    如果想覆盖掉entrypoint

posted @ 2023-05-02 10:20  YangYi215  阅读(50)  评论(0编辑  收藏  举报