Docker 镜像制作 与 数据管理

173 阅读11分钟

Docker 镜像制作类似于虚拟机的镜像(模版)制作,即按照公司的实际业务需求将需要安装的软件、相关配置等基础环境配置完成,然后将其做成镜像,最后再批量从镜像批量生成容器实例,这样可以极大的简化相同环境的部署工作。

Docker的镜像制作分为手动制作(基于容器)和自动制作(基于DockerFile),企业通常都是基于Dockerfile制作镜像。

  • 手动构建docker commit:下载官方或者别人制作好的镜像,通过修改现有容器,将之手动构建为镜像
  • 自动构建docker build:通过Dockerfile文件,批量构建为镜像

一、 手动构建镜像

将现有容器通过docker commit手动构建镜像

二、 自动构建镜像

利用DockerFile文件执行docker build自动构建镜像

1. Dockerfile介绍

DockerFile 是一种被Docker程序解释执行的脚本,由一条条的命令组成的,每条命令对应linux下面的一条命令,Docker程序将这些DockerFile指令再翻译成真正的linux命令,其有自己的书写方式和支持的命令,Docker程序读取DockerFile并根据指令生成Docker镜像,相比手动制作镜像的方式,DockerFile更能直观的展示镜像是怎么产生的,有了DockerFile,当后期有额外的需求时,只要在之前的DockerFile添加或者修改响应的命令即可重新生成新的Docker镜像,避免了重复手动制作镜像的麻烦,类似与shell脚本一样,可以方便高效的制作镜像Docker守护程序 Dockerfile 逐一运行指令,如有必要,将每个指令的结果提交到新镜像,然后最终输出新镜像的ID。Docker守护程序将自动清理之前发送的上下文。

注意:每条指令都是独立运行的,并会导致创建新镜像,比如 RUN cd /tmp 对下一条指令不会有任何影响。

2. Dockerfile文件格式

Dockerfile 是一个有特定语法格式的文本文件

Dockerfile文件说明:

  • 每一行以Dockerfile的指令开头,指令不区分大小写,但是惯例使用大写
  • 使用 # 开始作为注释
  • 每一行只支持一条指令,每条指令可以携带多个参数
  • 指令按文件的顺序从上至下进行执行
  • 每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令
  • 制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以为加速镜像制作,将最常变化的内容放下dockerfile的文件的后面

3. 构建镜像docker build命令

docker build命令使用Dockerfile文件创建镜像

命令格式:

docker build [OPTIONS] PATH | URL | -

//PATH | URL | -  可以使是本地路径,也可以是URL路径。若设置为 - ,则从标准输入获取Dockerfile的内容
命令选项含义
-f,--file stringDockerfile文件名,默认为 PATH/Dockerfile
--force-rm总是删除中间层容器,创建镜像失败时,删除临时容器
--no-cache不使用之前构建中创建的缓存
-q, --quiet=false不显示Dockerfile的RUN运行的输出结果
--rm=true创建镜像成功时,删除临时容器
-t,--tag list设置注册名称、镜像名称、标签。格式为 <注册名称>/<镜像名称>:<标签>(标签默认为latest)

4. Dockerfile 相关指令

4.1 FROM —— 指定基础镜像

定制镜像,需要先有一个基础镜像,在这个基础镜像上进行定制。

FROM 就是指定基础镜像,此指令通常必需放在Dockerfile文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的运行环境。

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

如何选择合适的镜像呢?

对于不同的软件官方都提供了相关的docker镜像,比如: nginx、redis、mysql、httpd、tomcat等服务类的镜像,也有操作系统类,如: centos、ubuntu、debian等。建议使用官方镜像,比较安全。

格式:

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]


//说明:  
--platform 指定镜像的平台,比如: linux/amd64, linux/arm64, or windows/amd64
tag 和 digest是可选项,如果不指定,默认为latest

例:

[root@localhost ~]#  mkdir /data/dockerfile/system/centos/centos7 -p
[root@localhost ~]#  cd /data/dockerfile/system/centos/centos7/
[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009

4.2 LABEL —— 指定镜像元数据

LABEL:说明信息,可以指定镜像元数据,如: 镜像作者等。docker inspect 命令可以查看LABEL信息。

一个镜像可以有多个label,还可以写在一行中,即多标签写法,可以减少镜像的的大小

//一行格式
LABEL multi.label1="value1" multi.label2="value2" other="value3"

//多行格式
LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

例:

[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \      //作者信息
      version="7.9.2009"  //版本信息

4.3 RUN —— 执行shell命令

RUN指令用来在构建镜像阶段,需要执行 FROM 指定镜像所支持的Shell命令。通常各种基础镜像一般都支持丰富的shell命令。

注意: 每个 RUN 都是独立运行的,和前一个 RUN 无关。RUN 可以写多个,每一个 RUN 指令都会建立一个镜像层,所以尽可能合并成一条指令,比如将多个shell命令通过 && 连接一起成为一条指令。

格式:

//shell 格式:相当于 /bin/sh -c <命令> 此种形式支持环境变量
RUN <命令> 

//exec 格式:此种形式不支持环境变量,注意!是双引号,不能是单引号
RUN ["可执行文件", "参数1", "参数2"]
//exec格式可以指定其它shell
RUN ["/bin/bash","-c","echo hello wang"]

例:

[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \
      version="7.9.2009"
RUN  cd /opt  &&  touch wj


[root@localhost centos7]#  docker build -t centos:7.9 .
#"docker build"命令使用Dockerfile文件创建镜像
#"-t"指定构建的镜像的名称和标签
#"centos"是镜像的名称
#"7.9"是标签
#"."是当前目录

[root@localhost centos7]#  docker run -it --name c1 centos:7.9  bash
[root@0b60dbd95701 /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@0b60dbd95701 /]# cd /opt
[root@0b60dbd95701 opt]# ls
wj
Dockerfile  1.png

4.4 ENV —— 设置环境变量

ENV 可以定义环境变量和值,会被后续指令(如:ENV,ADD,COPY,RUN等)通过$KEY${KEY}进行引用,并在容器运行时保持。

格式:

//变量赋值格式1:此格式只能对一个key赋值,<key>之后的所有内容均会被视作其<value>的组成部分
ENV <key> <value>   
//变量赋值格式2:此格式可以支持多个key赋值,定义多个变量,推荐使用,可以减少镜像层
ENV <key1>=<value1>  <key2>=<value2>  <key3>=<value3> ...
 
//引用变量
RUN $key .....

4.5 COPY —— 复制文本

复制本地宿主机的文件到容器中

格式:

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] //路径中有空白字符时,建议使用此格式

说明:

  • 可以是多个,可以使用通配符,通配符规则满足Go的filepath.Match
  • 必须是build上下文中的路径(为 Dockerfile 所在目录的相对路径),不能是其父目录中的文件
    • 只能复制与 Dockerfile 脚本文件同级的文件或者子目录中的文件⭐
  • 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
  • 如果指定了多个,或在中使用了通配符,则目标必须是一个目录,且必须以 / 结尾
    • 不加 / 类似于 改名 , 虽然不报错但是 效果不一样⭐
  • 可以是绝对路径或者是 WORKDIR 指定的相对路径
  • 使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
  • 如果事先不存在,它将会被自动创建,这包括其父目录路径,即递归创建目录

例:

  • 复制文件
[root@localhost ~]#  cd /data/dockerfile/system/centos/centos7/
[root@localhost centos7]#  ls
Dockerfile  index.html
[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \
      version="7.9.2009"
#RUN  cd /opt  &&  touch wj
COPY index.html /copytest/   
//复制宿主机的index.html文件到容器的copytest目录下;copytest目录事先不存在,会被自动创建


[root@localhost centos7]#  docker build -t c7:v2 .   //构建镜像
[root@localhost centos7]#  docker run -it  c7:v2
[root@7a60a11560f7 /]# ls
anaconda-post.log  bin  copytest  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@7a60a11560f7 /]# ls copytest/
index.html
  • 添加权限
[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \
      version="7.9.2009"
RUN  useradd lisi
COPY --chown=lisi:lisi index.html /copytest/
// --chown 选项添加权限

[root@localhost centos7]#  docker build -t c7:v3 .
[root@localhost centos7]#  docker run -it c7:v3
[root@b61558dc9256 /]# ls
anaconda-post.log  bin  copytest  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@b61558dc9256 /]# ll copytest/
total 4
-rw-r--r--. 1 lisi lisi 18 Aug  2 12:48 index.html
copy.png

4.6 ADD —— 复制和解压文件

该命令可认为是增强版的COPY,不仅支持COPY,还支持自动解压。

格式:

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

说明:

  • 可以是Dockerfile所在目录的一个相对路径;也可是一个 URL;还可是一个 tar 文件(自动解压)
  • 可以是绝对路径或者是 WORKDIR 指定的相对路径
  • 如果是目录,只复制目录中的内容,而非目录本身
  • 如果是一个 URL,下载后的文件权限自动设置为 600
  • 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为,如果以 / 结尾,则文件名URL指定的文件将被直接下载并保存为/< filename>
  • 如果是一个本地文件系统上的打包文件,如: gz, bz2 ,xz ,它将被解包,其行为类似于"tar -x"命令,但是通过URL获取到的tar文件将不会自动展开
  • 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾,则其被视作一个普通文件的内容将被直接写入到容器中

例:

[root@localhost centos7]#  ls
all.tar.gz  Dockerfile  index.html  test.txt

[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \
      version="7.9.2009"
ADD all.tar.gz /addtest/
//注意解压前 容器中要有相应的解压工具 !

[root@localhost centos7]#  docker build -t c7:v4 .
[root@localhost centos7]#  docker run -it c7:v4
[root@51762fe40af5 /]# ls
addtest  anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@51762fe40af5 /]# ls addtest/
index.html  test.txt
add.png

4.7 CMD —— 容器启动命令

一个容器中需要持续运行的进程一般只有一个,CMD 用来指定启动容器时默认执行的一个命令,且其运行结束后,容器也会停止,所以一般CMD 指定的命令为持续运行且为前台命令。

格式:

//使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量
CMD ["executable","param1","param2"] 

//在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量
CMD command param1 param2 

//提供给 ENTRYPOINT 命令的默认参数
CMD ["param1","param2"]

说明:

  • 如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT,那么开启容器时就会使用执行CMD指定的默认的命令
  • 前面介绍过的 RUN 命令是在构建镜像进执行的命令,注意二者的不同之处
  • 每个 Dockerfile 只能有一条 CMD 命令。如指定了多条,只有最后一条被执行
  • 如果用户启动容器时用 docker run xxx 指定运行的命令,则会覆盖 CMD 指定的命令

例:

CMD tail -f /etc/hosts

CMD  ["tail","-f","/etc/hosts"]
cmd.png

4.8 ENTRYPOINT —— 入口点

功能类似于CMD,配置容器启动后执行的命令及参数

格式:

// 使用 exec 执行
ENTRYPOINT ["executable", "param1", "param2"]

// shell中执行
ENTRYPOINT command param1 param2

说明:

  • ENTRYPOINT 不能被 docker run 提供的参数覆盖,而是追加,即如果docker run 命令有参数,那么参数全部都会作为ENTRYPOINT的参数
  • 如果docker run 后面没有额外参数,但是dockerfile中的CMD里有(即上面CMD的第三种用法),即Dockerfile中即有CMD也有ENTRYPOINT,那么CMD的全部内容会作为ENTRYPOINT的参数
  • 如果docker run 后面有额外参数,同时Dockerfile中即有CMD也有ENTRYPOINT,那么docker run后面的参数覆盖掉CMD参数内容,最终作为ENTRYPOINT的参数
  • 可以通过docker run --entrypoint string 参数在运行时替换,注意string不要加空格
  • 使用CMD要在运行时重新写命令本身,然后在后面才能追加运行参数,ENTRYPOINT则可以运行时无需重写命令就可以直接接受新参数
  • 每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效

例:

CMD   ["-g","daemon off;"]
ENTRYPOINT   ["/apps/nginx/sbin/nginx"]
//CMD和ENTRYPOINT一起出现,CMD将作为ENTRYPOINT后面的参数;执行的是 nginx -g daemon off

4.9 ARG —— 构建参数

ARG指令在 build 阶段指定变量,和ENV不同的是,容器运行时不会存在这些环境变量

格式:

ARG <name>[=<default value>]

4.10 VOLUME —— 匿名卷

在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等,一般会将宿主机上的目录挂载至 VOLUME 指令指定的容器目录。即使容器后期被删除,此宿主机的目录仍会保留,从而实现容器数据的持久保存。

宿主机目录为:/var/lib/docker/volumes/<volume_id>/_data

格式:

vOLUME <容器内路径>
VOLUME ["<容器内路径1>", "<容器内路径2>"...]

说明:

  • Dockerfile中的VOLUME实现的是匿名数据卷,无法指定宿主机路径和容器目录的挂载关系
  • 通过docker rm -fv <容器ID> 可以删除容器的同时删除VOLUME指定的卷

例:

[root@localhost centos7]#  vim Dockerfile
FROM  centos:7.9.2009
LABEL author="lkk" \
      version="7.9.2009"
VOLUME ["/data1","/data2"]
//在容器创建 /data1 ,/data2 两个挂载点


[root@localhost centos7]#  docker build -t c7:v8 .  //构建镜像
[root@localhost centos7]#  docker run -it c7:v8
[root@17a7ad939db0 /]# ls
anaconda-post.log  bin  data1  data2  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@17a7ad939db0 /]# cd /data1      //切换到data1下
[root@17a7ad939db0 data1]# touch 123  //新建一个文件
[root@17a7ad939db0 data1]# ls
123

[root@localhost ~]#  docker inspect 17a7ad939db0   //查看详细信息
[root@localhost ~]#  cd /var/lib/docker/volumes/eb8767aaaef967b95918e768e95c6027d2674472c83eba3e0ef06f4c31d89efe/_data
[root@localhost _data]#  ls   
123   //可以看到在容器中建立的文件,同样显示在了真机中

[root@localhost _data]#  docker rm -fv 17a7ad939db0  //删除容器的同时删除VOLUME指定的卷
17a7ad939db0
[root@localhost _data]#  ls
[root@localhost _data]#
[root@localhost ~]#  cd /var/lib/docker/volumes/eb8767aaaef967b95918e768e95c6027d2674472c83eba3e0ef06f4c31d89efe/_data
-bash: cd: /var/lib/docker/volumes/eb8767aaaef967b95918e768e95c6027d2674472c83eba3e0ef06f4c31d89efe/_data: 没有那个文件或目录
volume1.png volume2.png volume3.png

4.11 EXPOSE —— 暴露端口

指定服务端的容器需要对外暴露(监听)的端口号,以实现容器与外部通信。EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会真正暴露端口,即不会自动在宿主进行端口映射因此,在启动容器时需要通过 -P-p ,Docker 主机才会真正分配一个端口转发到指定暴露的端口才可使用。

格式:

EXPOSE <port>[/ <protocol>] [<port>[/ <protocol>] ..]
    
#说明:<protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议

注意: 即使Dockerfile没有 EXPOSE 端口指令,也可以通过docker run -p临时暴露容器内程序真正监听的端口,所以 EXPOSE 相当于指定默认的暴露端口,可以通过docker run -P 进行真正暴露。

例:

EXPOSE  80  443

4.12 WORKDIR —— 指定工作目录

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录,当容器运行后,进入容器内WORKDIR指定的默认目录。

WORKDIR 指定工作目录(或称当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会自行创建。

格式:

WORKDIR /path/to/workdir

例:WORKDIR /app

三、 Docker数据管理

1. 容器的数据管理介绍

Docker镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层中。

  1. 容器的数据分层目录:
  • LowerDir:image 镜像层,即镜像本身,只读
  • UpperDir:容器的上层,容器变化的数据存放在此处,可读写
  • MergedDir:容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和 upperdir 合并完成后给容器使用,最终呈现给用户的统一视图
  • WorkDir:容器在宿主机的工作目录,挂载后内容会被清空,且在使用过程中其内容用户不可见
  1. 容器数据持久保存方式

因为容器的数据是临时的,一旦容器被删除,数据将永久丢失。想要将容器中的数据持久化,可以将宿主机目录挂载到容器中。

Docker的数据类型分为两种:

  • 数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录 ,推荐使用此种方式,此方式较常用
  • 数据卷容器(Data Volume Container): 间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据 ,此方式不常用

2. 数据卷(Data Volume)

2.1 数据卷使用场景

  • 数据库
  • 日志输出
  • 静态web页面
  • 应用配置文件
  • 多容器间目录或文件共享

2.2 数据卷的特点

  • 数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用对数据卷更改数据在所有容器里面会立即更新。
  • 数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
  • 在容器里面的写入数据不会影响到镜像本身,即数据卷的变化不会影响镜像的更新
  • 依赖于宿主机目录,宿主机出问题,上面容器会受影响,当宿主机较多时,不方便统一管理
  • 匿名和命名数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,会拷贝到新初始化的数据卷中

2.3 数据卷使用方法

启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种:

  • 指定宿主机目录或文件 :指定宿主机的具体路径和容器路径的挂载关系
    • 容器和真机共用空间, 把容器的文件挂载到 真机的文件夹
  • 匿名卷 :不指定数据名称,只指定容器内目录路径充当挂载点,docker自动指定宿主机的路径进行挂载
  • 命名卷 :指定数据卷的名称和容器路径的挂载关系,和匿名卷在一个目录,只是取了一个自定义的名字

docker run 命令的以下格式可以实现数据卷:

-v, --volume=[host-src:]container-dest[:<options>]
<options>
ro 从容器内对此数据卷是只读,不写此项默认为可读可写
rw 从容器内对此数据卷可读可写,此为默认值

注意:\color{red}{注意:} 一般只建议在创建容器时进行挂载,不建议启动容器后再挂载。因为启动容器后再挂载的话,需要修改配置文件,且不一定能挂载成功。

2.3.1 方法1:指定宿主机目录或文件

格式:

-v   <宿主机绝对路径的目录或文件>:<容器目录或文件>[:ro]  
//将宿主机目录挂载容器目录,两个目录都可自动创建

例:

[root@localhost ~]#  docker  run -it --name t1 -v  /data:/opt  centos:7.9
// -it  表示使用交互式终端来运行容器
// --name t1  指定容器的名称为t1
// -v /data:/opt  将主机的/data目录挂载到容器中的/opt目录,实现主机和容器之间的文件共享
// centos:7.9 指定使用CentOS 7.9镜像来创建容器
2.3.2 方法2:匿名卷

格式:

-v <容器内路径>
//匿名卷只指定容器内路径,没有指定宿主机路径信息,宿主机自动生成/var/lib/docker/volumes/<卷ID>/_data目录,并挂载至容器指定路径

例:

docker run --name nginx -v /etc/nginx nginx
2.3.3 方法3:命名卷

命名卷将固定的存放在/var/lib/docker/volumes/<卷名>/_data

格式:

-v <卷名>:<容器目录路径>


docker volume create <卷名>
//可以通过该命令事先创建,如果没有事先创建卷名,docker run时也会自动创建卷,很少用

例:

[root@localhost _data]#  docker run -d -p 80:80 --name nginx01 -v vol1:/use/share/nginx/html nginx
//-d  在后台运行容器
//-p 80:80  将容器的80端口映射到主机的80端口
//--name nginx01  给该容器命名为nginx01
//-v vol1:/use/share/nginx/html  挂载到容器的/use/share/nginx/html目录
//nginx  运行的镜像为nginx
命名卷1-1.png 命名卷1-2.png

2.4 管理卷的操作

命令作用
docker volume create创建卷
docker volume inspect显示一个或多个卷的详细信息
docker volume  ls列出卷
docker volume prune删除所有匿名卷
docker volume rm移除一个或多个卷

3. 数据卷容器(Data Volume Container)

多个容器通过同一个数据卷容器为基点,实现所有容器数据共享

--volumes-from 选项用于在Docker容器之间共享卷(volume)。通过该选项,可以让一个容器共享另一个容器的卷,从而实现数据共享和持久化

docker run --volumes-from <容器名或容器ID> <要运行的镜像>这将创建一个新的容器,并使用指定的容器作为卷源,使得新的容器可以访问同一卷中的数据。这对于在不同容器之间共享数据或配置信息非常有用。

例:

[root@localhost _data]#  docker run -d --name vo-server -v  /data/testdir/:/usr/share/nginx/html/ nginx
35e51c8704c3565be5e2bc06bd22d527f74df01b9c9ca1fb9baa2029e64753b0
//运行一个名为vo-server的Nginx容器,将主机中的/data/testdir/目录挂载到容器中的/usr/share/nginx/html/目录,这样Nginx容器中的网页文件将和主机中的/data/testdir/目录进行双向同步
[root@localhost _data]#  echo "test page" > /data/testdir/index.html
//在主机中的/data/testdir/目录下创建一个名为index.html的文件,文件内容为test page

[root@localhost _data]#  docker run -d --name web1  --volumes-from vo-server -p 80:80  nginx
ea5f0a5c841a8b1a20af1361e2dee6d1a3d6f28250b385974b41d6fe8ae2337b
//运行一个名为web1的Nginx容器,使用--volumes-from选项将vo-server容器中挂载的卷共享给web1容器,同时将容器内部80端口映射到主机的80端口,以便外部访问Nginx服务

[root@localhost _data]#  docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS                               NAMES
ea5f0a5c841a   nginx     "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   web1
35e51c8704c3   nginx     "/docker-entrypoint.…"   11 minutes ago   Up 11 minutes   80/tcp                              vo-server
[root@localhost _data]#  docker inspect ea5f0a5c841a  //查看web1容器的详细信息
[root@localhost _data]#  curl 172.17.0.3   //测试容器之间通信
test page  //web1容器通过端口映射可以访问到vo-server容器中挂载的卷
--v1-1.png --v1-2.png --v1-3.png

总结

Dockerfile 指令作用
FROM iamge_name:tag声明基础镜像
MAINTAINER user_name声明镜像的作者
LABEL代替了MAINTAINER
ENV key value设置环境变量(可以写多条)
RUN command编译镜像时运行的脚本(可以写多条)
CMD设置容器的启动命令
ENTRYPOINT设置容器的入口程序
ADD source_dir/file dest_dir/file将宿主机的文件复制到镜像内,如果是一个压缩文件,将会在复制后自动解压。 支持URL路径下载源文件,但下载方式不能自动解压。
COPY source_dir/file dest_dir/file和ADD相似,将宿主机的文件复制到镜像内,但是如果有压缩文件并不能解压。不支持URL路径下载。
WORKDIR path_dir设置工作目录
ENV设置环境变量
ARG构建参数
VOLUME设置容器的挂载卷