5.dokcer的数据卷

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但是不属于联合文件系统,因此能够绕过Union File System提供的一些用于持续存储或共享文件的特性

卷的设计目的就是数据持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷


特点:
1.数据卷可在容器之间共享或重用数据
2.卷中的更改可以直接生效
3.数据卷中的更改不会包含在镜像的更新中
4.数据卷的声明周期一致持续到没有容器使用它为止

功能:
    1.容器间的持久化
    2.容器间的继承和数据共享

直接通过命令实现共享

1.如何实现宿主机和容器间的文件共享:docker run -it -v /宿主机文件夹的绝对路径:容器文件的绝对路径 镜像名称
    [root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume centos
    这个语句的作用是启动centos镜像,并宿主机根目录下创建:hostDataValume文件夹,在centos容器根目录下创建containerDataValume 文件夹,这两个文件夹实现了文件共享,
         即宿主机在hostDataValume创建文件或更改文件,centos容器中的containerDataValume 也会做对应的更改
        centos容器中也是同理
    容器中的根目录:
        [root@3038c21a010f /]# ls
        bin  containerDataValume(发现其创建了文件夹)  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    宿主机根目录:
        [root@wmd03 /]# ls
        bin  boot  dev  etc  home  hostDataValume(也创建了该文件夹)  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    这两个文件夹实现了文件共享
    
    
2.创建一个只读的文件夹
    [root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume:ro centos
    这样的结果是docker容器中的containerDataValume文件夹中的文件只读,不能创建也不能更改,只有宿主机可以
    示例:
        [root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume:ro centos
        [root@6af3e954d88f /]# ls
        bin  containerDataValume  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
        [root@6af3e954d88f /]# cd containerDataValume/
        [root@6af3e954d88f containerDataValume]# touch text.text
        touch: cannot touch 'text.text': Read-only file system---->不需要创建

3.这里有意思的是:这里容器停止了,在停止期间,宿主机在共享文件夹做的更改,容器再此启动后会同步过来...

如何使用dockerFile创建数据卷(宿主机的共享文件夹)

1.编写一个Dockerfile
    [root@wmd03]mkdir mydocker
    [root@wmd03]vim Dockerfile
        # volume test
        FROM centos
        VOLUME ["/dataVolumeContainer01","/dataVolumeContainer02"]--->这里是创建的docker容器的数据卷,并没有宿主机的对应位置
        CMD  echo "成功的创建了容器的数据卷!"
        CMD /bin/bash

2.使用build生成镜像:后面的点必须有
    [root@wmd03 myDockerFile]# docker build -f /myDockerFile/dockerFile -t wmd/centos .
    Sending build context to Docker daemon  2.048kB
    Step 1/4 : FROM centos
     ---> 0d120b6ccaa8
    Step 2/4 : VOLUME ["/dataVolumeContainer01","/dataVolumeContainer02"]
     ---> Running in 1fe005128a1d
    Removing intermediate container 1fe005128a1d
     ---> c013893a5550
    Step 3/4 : CMD  echo "成功的创建了容器的数据卷!"
     ---> Running in d589954d3f5b
    Removing intermediate container d589954d3f5b
     ---> 1fab8c265711
    Step 4/4 : CMD /bin/bash
     ---> Running in 883b7580f8dd
    Removing intermediate container 883b7580f8dd
     ---> cecc006ec033
    Successfully built cecc006ec033
    Successfully tagged wmd/centos:latest
    
3.查询镜像:
    [root@wmd03 myDockerFile]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    wmd/centos(有)      latest              cecc006ec033        21 seconds ago      215MB
    centos              latest              0d120b6ccaa8        2 months ago        215MB
    
4.运行镜像:
    [root@wmd03 myDockerFile]# docker run  -it wmd/centos
    [root@03285be9b93c /]# ls
    bin  dataVolumeContainer01(创建成功)  dataVolumeContainer02(创建成功)  dev	etc  home  lib	lib64  lost+found  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var


5.问题:查找容器数据卷对应的宿主机文件夹位置:
    [root@wmd03 ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    5c00dad91191        wmd/centos          "/bin/sh -c /bin/bash"   29 seconds ago      Up 28 seconds                           hardcore_engelbart
    [root@wmd03 ~]# docker inspect 5c00dad91191
        。。。
         "Volumes": {
                "/dataVolumeContainer01": {},
                "/dataVolumeContainer02": {}
            },
        。。。
    发现对应关系为空:但是宿主机的对应文件夹在/var/lib/docker/volumes文件夹下,并且可以形成共享关系,但是这里查询不出,问题没有得到解决

数据卷之间的继承和共享

数据卷之间可以存在继承关系,实现共同的文件共享
示例如下:
    1.创建第一个数据卷:
        [root@wmd03 ~]# docker run -it --name dc01 wmd/centos  指定名称创建第一个容器,并发现创建了(dataVolumeContainer01  dataVolumeContainer02)
        [root@0e8d9d653926 /]# ls
        bin  dataVolumeContainer01  dataVolumeContainer02  dev	etc  home  lib	lib64  lost+found  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var
    2.在dataVolumeContainer02创建文件
        [root@0e8d9d653926 /]# cd dataVolumeContainer02/
        [root@0e8d9d653926 dataVolumeContainer02]# touch dc01.txt
        [root@0e8d9d653926 dataVolumeContainer02]# ls
        dc01.txt
        
    3.创建第二个容器,数据卷继承容器1
        [root@wmd03 ~]# docker run -it --name dc02 --volumes-from dc01 wmd/centos
        [root@683cd6dff487 /]# ls (发现也创建了dataVolumeContainer01和dataVolumeContainer02,并且在dataVolumeContainer02中有2步骤创建的文件)
        bin  dataVolumeContainer01  dataVolumeContainer02  dev	etc  home  lib	lib64  lost+found  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var
        [root@683cd6dff487 /]# cd dataVolumeContainer02/
        [root@683cd6dff487 dataVolumeContainer02]# ls
        dc01.txt
        
    4.创建第三个容器,数据卷继承容器2
        [root@wmd03 ~]# docker run -it --name dc03 --volumes-from dc02 wmd/centos
        [root@92a0731aacb4 /]# ls (发现也创建了dataVolumeContainer01和dataVolumeContainer02,并且在dataVolumeContainer02中有2步骤创建的文件)
        bin  dataVolumeContainer01  dataVolumeContainer02  dev	etc  home  lib	lib64  lost+found  media  mnt  opt  proc  root	run  sbin  srv	sys  tmp  usr  var
        [root@92a0731aacb4 /]# cd dataVolumeContainer02/
        [root@92a0731aacb4 dataVolumeContainer02]# ls
        dc01.txt
        
结论:有继承关系的数据卷实现了文件共享
问题:
    1.删除1容器,即23容器的父类,23容器的数据卷是否还存在
        答案:存在,并且如果在2容器中做的更改,3容器数据卷也会做对应改变,反之,在3容器中数据卷做的更改,2容器数据卷也会更改,这是个双向通道!
    2.在子数据卷做的更改,父数据卷是否会改变
        答案:会的,这是个双向通道,存在数据卷继承关系的容器,不论哪个容器数据卷做了更改,其他容器的数据卷都会做对应更改

Dokefile解析

是什么
    Dockfile事用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
步骤:
    1.手动编写一个dockefile文件,当然要符合dockefile的规范
    2.有了这个文件后,直接docker buil的命令执行,获取一个自定义的镜像
    3.run
    
以我们熟悉的centos系统的Dockfile文件作为例子:https://github.com/CentOS/sig-cloud-instance-images/blob/12a4f1c0d78e257ce3d33fe89092eee07e6574da/docker/Dockerfile
内容如下:
      FROM scratch (scratch是所有镜像的父类)
      ADD centos-8-x86_64.tar.xz / 
      LABEL org.label-schema.schema-version="1.0" org.label-schema.name="CentOS Base Image" org.label-schema.vendor="CentOS" org.label-schema.license="GPLv2"  org.label-schema.build-date="20200809"
      CMD ["/bin/bash"]
      
docker运行DockerFile的大致流程:
    1.dokcer从基础镜像运行一个容器(基础镜像就是From后面的)
    2.执行一个指令并对容器进行更改
    3.执行类似docker commit的操作,提交更改,并形成一个新的镜像(这里很重要:意思是dockfile的每个语句,对容器做出更改,都会提交生成新的镜像)
    4.docker再基于方才提交的镜像生成一个新的容器
    5.执行dockerfile的下一条指令,直到所有指令都执行完毕!
    结论:
        基于上述的流程,dockerfile会生成一个一层一层的镜像!

1.Doclfile的保留子指令

1.FROM 基础镜像,当前新镜像是基于哪个镜像的
2.MAINTAINER 镜像维护者的姓名和邮箱地址
3.RUN  容器构建时需要运行的命令
4.EXPOSE 当前容器对外暴露的端口
5.WORKDIR 指定再创建容器后,终端莫瑞诺登录的进来的工作目录,一个落脚点
6.ENV 用来再构建镜像过程中设置环境变量
7.ADD 将宿主机目录下的文件拷贝近镜像,且ADD命令会自动处理URL和解压tar压缩包
8.COPY 类似于ADD,拷贝文件和目录到镜像,但是不会解压
        将从构建上下文目录中<源路径>的文件/目录 复制到新的一层的镜像内的<目标路径>位置

9.VOLUME 容器数据卷,用于数据保存和持久化工作
10.CMD 
    指定一个容器启动要运行的命令
    Dockfile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
    
11.ENTRYPOINT 
    指定一个容器启动时要运行的命令
    ENTRYPOINT 的目的和CMD一样,都是在指定容器启动程序及参数,但是这个是追加
    
12.ONBUILD 当构建一个被继承的Dockfile是运行命令,父镜像在被子继承后,父镜像的onbuild被触发

    
        
            
                
                    
                        
使用实例:
        FROM cenos  -->继承centos
        MAINTAINER wmd  --->作者
        ENV MYPATH /usr/local  --->定义一个MYPATH的变量
        WORKDIR $MYPATH  --->定义落脚点:因为每次-it运行centos镜像时,出现的交互页面路径都是根路径:/,设置这个后,再进入就是/usr/local
        
        RUN yum -y install vim   --->执行命令:安装vim,因为docker中的centos容器不能使用vim命令,现下载
        RUN yum -y install net-tools  --->执行命令:安装网络工具,因为docker中的centos容器不能使用ifconfig,现在下载
        
        EXPOSE 80  -->对外暴露的端口为80

 

posted @ 2022-05-26 20:07  努力的达子  阅读(27)  评论(0编辑  收藏  举报