1. 为什么需要容器数据卷

    角度:遇到问题,尝试以朴素的道理解决问题.问题复杂化,解决的方式也变得复杂

    问题的提出:docker将应用和环境打包成一个镜像,但是对于容器内的数据,如果不进行外部的保存,那么当容器删除后,数据也会丢失

    解决:通过docker的容器数据卷技术,实现容器数据的持久化和同步操作!同时容器间也是可以数据共享的!

    实现:目录的挂载,将我们容器内的目录,挂载到Linux上面,使两者之间相互对应

  2. 使用数据卷

    建议使用两个终端进行调试

    • docker run -v 主机目录地址:容器目录地址:将主机目录地址与对应的容器目录地址进行双向绑定

      v:类似vue的v-model双向绑定(注:v-bind和v-model的区别在于v-bind多用于单向绑定,比如字段的显示;v-model则多用于表单,比如input中输入的返回等)

      测试:

      #运行一个容器,同时制定行管的目录
      [root@iZwz908j8pbqd86doyrez5Z test]# docker run -d -it -v /test:/root/test -p 8081:8080 tomcat:9.0 /bin/bash
      a5c3db57e2b230db84a9d273e2379d55b47b47bc07f5630d16a35d1e5fc0c3b0
      [root@iZwz908j8pbqd86doyrez5Z test]# docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      a5c3db57e2b2 tomcat:9.0 "/bin/bash" 14 seconds ago Up 14 seconds 0.0.0.0:8081->8080/tcp sad_tu
      [root@iZwz908j8pbqd86doyrez5Z test]# docker attach a5c3db57e2b2 #从元数据中查看绑定情况
      "Mounts": [
      {
      "Type": "bind",
      "Source": "/root/test", //源文件位置(主机)
      "Destination": "/root/test", //目标文件位置(容器)
      "Mode": "",
      "RW": true,
      "Propagation": "rprivate"
      }
      ] #尝试从容器写入主机
      #容器
      [root@6eec281a5e9f test]# mkdir test1
      [root@6eec281a5e9f test]# ls
      test.java test1
      #主机
      [root@iZwz908j8pbqd86doyrez5Z test]# ls
      test1 test.java #尝试从主机写入容器
      #主机
      [root@iZwz908j8pbqd86doyrez5Z test]# touch a.tets
      [root@iZwz908j8pbqd86doyrez5Z test]# ls
      a.tets test1 test.java
      #容器
      [root@6eec281a5e9f test]# ls
      a.tets test.java test1

      注:

      • -it:以交互的形式打开终端,-d:在后台运行
      • 只有在运行时用-it...bash,才能在之后用attach打开一个命令行
      • 主次关系来说,其实还是主机的目录覆盖容器的目录

      优点:修改只需在本地修改即可,容器内会自动同步

  3. 安装mysql完成挂载

    mysql所有数据都在data目录下

    #下载镜像
    docker pull mysql:5.7 #在使用挂载对mysql的相关目录覆盖之前,我们需要保证目录中有所需要的东西
    #新建一下目录:/usr/arno/mysql/conf,/usr/arno/mysql/data
    #打开一个不需要挂载的mysql容器,将容器内对应的数据复制到新建的目录中
    [root@iZwz908j8pbqd86doyrez5Z conf]# docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker cp ad7db127211a:/etc/mysql/conf.d /usr/arno/mysql/conf
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker cp ad7db127211a:/var/lib/mysql /usr/arno/mysql/data #运行镜像(同时对mysql的conf和data进行了挂载)
    docker run -d -p 3310:3306 -v /usr/arno/mysql/conf:/etc/mysql/conf.d -v /usr/arno/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 #尝试通过navicat访问(需要配置阿里云安全组)
    #(1).连接成功(欧耶!)
    #(2).新建一个数据库(test) #查看主机中的data
    [root@iZwz908j8pbqd86doyrez5Z data]# ls
    auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
    ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
    ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test #查看容器中的数据库
    root@78c6defe3428:/var/lib/mysql# ls
    auto.cnf client-cert.pem ib_logfile0 ibtmp1 private_key.pem server-key.pem
    ca-key.pem client-key.pem ib_logfile1 mysql public_key.pem sys
    ca.pem ib_buffer_pool ibdata1 performance_schema server-cert.pem test #完美!

    注:

    • 通过hub.docker搜查mysql,以便完成mysql密码的配置$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
    • 注意:挂载的开始,主机的目录会覆盖容器的目录,所以你的目录必须一开始就要有对应的文件.解决方法就是运行一个不挂载的容器,然后将所有东西都用docker cp 容器id:目录 要主机目录命令拷贝到主机目录下(但更好的方法是使用下面的具名挂载)
  4. 具名挂载与匿名挂载

    #1.匿名挂载
    -v 容器内路径
    docker run -d -P --name nginx01 -v /etc/nginx nginx #查看所有挂载的卷
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker volume ls
    DRIVER VOLUME NAME
    local 2e364979e68adc93ea6ac8075250d0f41488c62b0345db8a917f8571df312992
    local 811aa7cb9f25b11fffb8a6e3490726f6d85b28f73147a7bceb8096288aa70163
    local c1abdabde73dcf238913e7f51aa4bcd726f170a474d3282f704f19bc86f40be0
    local f0e7e07b67bf298bdf8c3d420f93c5851c0cfa313669cfd1887f4a3210e73c62
    #匿名卷挂载形式(在-v时只写了容器内的路径,没有写容器外的路径) #通过原数据查看匿名挂载的卷
    "Mounts": [
    {
    "Type": "volume",
    "Name": "811aa7cb9f25b11fffb8a6e3490726f6d85b28f73147a7bceb8096288aa70163", #对应的匿名
    "Source": "/var/lib/docker/volumes/811aa7cb9f25b11fffb8a6e3490726f6d85b28f73147a7bceb8096288aa70163/_data",
    #匿名挂载对应的主机路径
    "Destination": "-etc/nginx", #匿名挂载对应的容器路径
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    } #2.具名挂载
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker run -d -P --name nginx02 -v volume:/etc/nginx nginx
    d4a2fed1744e7c8ed2e3febe35612842a01eb8379d159b437de752e0b6c25ca1
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker volume ls
    DRIVER VOLUME NAME
    local 2e364979e68adc93ea6ac8075250d0f41488c62b0345db8a917f8571df312992
    local 811aa7cb9f25b11fffb8a6e3490726f6d85b28f73147a7bceb8096288aa70163
    local c1abdabde73dcf238913e7f51aa4bcd726f170a474d3282f704f19bc86f40be0
    local f0e7e07b67bf298bdf8c3d420f93c5851c0cfa313669cfd1887f4a3210e73c62
    local volume #查看具名挂载的目录
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker inspect volume
    [
    {
    "CreatedAt": "2020-09-12T09:03:07+08:00",
    "Driver": "local",
    "Labels": null,
    "Mountpoint": "/var/lib/docker/volumes/volume/_data",
    "Name": "volume",
    "Options": null,
    "Scope": "local"
    }
    ] #查看元数据中的挂载
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker inspect nginx02
    "Mounts": [
    {
    "Type": "volume",
    "Name": "volume",
    "Source": "/var/lib/docker/volumes/volume/_data", #主机目录
    "Destination": "/etc/nginx", #容器目录
    "Driver": "local",
    "Mode": "z",
    "RW": true,
    "Propagation": ""
    }
    ]

    注:

    • -P(大p):随机映射端口

    • 所有的docker容器内的卷,没有指定目录的情况下都是docker 在/var/lib/docker/volume/xxxx/_data

    • 挂载形式 指定挂载路径 有名字
      匿名挂载 false false
      指定路径挂载 true false
      具名挂载 true true

    如何区分具名挂载,匿名挂载,还是具名指定路径挂载?

    -v 容器内路径 #匿名挂载

    -v 卷名:容器内路径 #具名挂载

    -v /宿主机路径:/容器内路径 #指定路径挂载

    拓展:

    # 通过-v容器内路径,ro/rw改变读写权限
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx #只读
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx #只写

    注:只读的挂载卷只能通过宿主机来操作

  5. 初始Dockerfile

    Dockerfile就是用来构建docker镜像的构建文件和命令脚本.由于镜像是分层的,每个命令也对应一层

    #创建一个名为docker file1的文件,同时进入编辑
    vim dockerfile1 #写命令(指令大写)
    FROM centos #以centos为基础
    VOLUME ["volumen01","volume02"] #在生成时挂载卷,匿名挂载,volume01/volume02是内部的文件
    CMD echo "----end----"
    CMD /bin/bash #以指令台的形式打开
    #保存退出:esc -> :wq #查看编写的文件脚本
    car dockerfile1 #生成dockerfile
    [root@iZwz908j8pbqd86doyrez5Z test]# docker build -f dockerfile1 -t arno/centos:1.0 .
    Sending build context to Docker daemon 3.584kB
    Step 1/4 : FROM centos
    ---> 0d120b6ccaa8
    Step 2/4 : VOLUME ["volumen01","volume02"]
    ---> Running in e9fd99177a57
    Removing intermediate container e9fd99177a57
    ---> 4b51c5ece9de
    Step 3/4 : CMD echo "---end---"
    ---> Running in 17fc5ba5da77
    Removing intermediate container 17fc5ba5da77
    ---> ba8b29cc064e
    Step 4/4 : CMD /bin/bash
    ---> Running in 047d5ced7a4b
    Removing intermediate container 047d5ced7a4b
    ---> bbbedbad86c6
    Successfully built bbbedbad86c6
    Successfully tagged arno/centos:1.0
    #-f 生成的文件
    #-t 生成的文件名:tag 生成的文件位置(当时当前目录) #运行容器
    [root@iZwz908j8pbqd86doyrez5Z test]# docker run -it arno/centos:1.0 /bin/bash
    [root@652cd9f64f74 /]# ls
    bin etc lib lost+found mnt proc run srv tmp var volumen01
    dev home lib64 media opt root sbin sys usr volume02#可以看到有volume01和volume02两个文件 #查看挂载的数据卷
    [root@iZwz908j8pbqd86doyrez5Z ~]# docker inspect 652cd9f64f74
    "Mounts": [
    {
    "Type": "volume",
    "Name": "7fe986067800aa48085b302336faa270d7df53ba65d4eb3e0964eaee6f50796a", #匿名
    "Source": "/var/lib/docker/volumes/7fe986067800aa48085b302336faa270d7df53ba65d4eb3e0964eaee6f50796a/_data",
    "Destination": "volume02",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    },
    {
    "Type": "volume",
    "Name": "a5e71c3f49495c1b02fa559b92fb65ecc6dee0a1ce7fd3d2fa77b2dc1341e739", #匿名
    "Source": "/var/lib/docker/volumes/a5e71c3f49495c1b02fa559b92fb65ecc6dee0a1ce7fd3d2fa77b2dc1341e739/_data",
    "Destination": "volumen01",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    }
    ], #测试
    #在容器中生成一个/volumen01/test.txt文件
    [root@652cd9f64f74 /]# cd volumen01
    [root@652cd9f64f74 volumen01]# touch test.txt
    [root@652cd9f64f74 volumen01]# ls
    test.txt
    #在主机中查看(直接复制元数据中mounts的source路径即可)
    [root@iZwz908j8pbqd86doyrez5Z _data]# cd /var/lib/docker/volumes/a5e71c3f49495c1b02fa559b92fb65ecc6dee0a1ce7fd3d2fa77b2dc1341e739/_data
    [root@iZwz908j8pbqd86doyrez5Z _data]# ls
    test.txt
    #验证完毕!
  6. 数据卷容器

    多个容器间的数据共享

    注意容器数据卷和数据卷容器的区别:

    • 容器的数据卷
    • 数据卷的容器:子容器挂载父容器(数据卷的容器)的数据,实现数据的同步
    #使用
    [root@iZwz908j8pbqd86doyrez5Z _data]# docker run -d -it --name docker01 arno/centos:1.0
    [root@iZwz908j8pbqd86doyrez5Z _data]# docker run -it --name docker02 --volumes-from docker01 arno/centos:1.0 #docker01的数据挂载到docker02上 #验证
    [root@iZwz908j8pbqd86doyrez5Z _data]# docker attach docker01
    [root@5bd780fa7cad /]# ls
    bin etc lib lost+found mnt proc run srv tmp var volumen01
    dev home lib64 media opt root sbin sys usr volume02
    [root@5bd780fa7cad /]# cd volumen01
    [root@5bd780fa7cad volumen01]# touch test.txt
    [root@5bd780fa7cad volumen01]# ls
    test.txt
    [root@iZwz908j8pbqd86doyrez5Z _data]# docker attach docker02
    [root@56e0c6ac0d64 /]# ls
    bin etc lib lost+found mnt proc run srv tmp var volumen01
    dev home lib64 media opt root sbin sys usr volume02
    [root@56e0c6ac0d64 /]# cd volumen01
    [root@56e0c6ac0d64 volumen01]# ls
    test.txt #查看元数据
    [root@iZwz908j8pbqd86doyrez5Z _data]# docker inspect docker01
    "Mounts": [
    {
    "Type": "volume",
    "Name": "9c60002316aa06044c718bd6728a9c4e71865b3127773461f65a82354e26d70c",
    "Source": "/var/lib/docker/volumes/9c60002316aa06044c718bd6728a9c4e71865b3127773461f65a82354e26d70c/_data",
    "Destination": "volume02",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    },
    {
    "Type": "volume",
    "Name": "e0584a1a806735c297b08629bb9ab4b1d419bbdc9a61fb5f526618a6096802b0",
    "Source": "/var/lib/docker/volumes/e0584a1a806735c297b08629bb9ab4b1d419bbdc9a61fb5f526618a6096802b0/_data",
    "Destination": "volumen01",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    }
    ], [root@iZwz908j8pbqd86doyrez5Z _data]# docker inspect docker02
    "Mounts": [
    {
    "Type": "volume",
    "Name": "9c60002316aa06044c718bd6728a9c4e71865b3127773461f65a82354e26d70c",
    "Source": "/var/lib/docker/volumes/9c60002316aa06044c718bd6728a9c4e71865b3127773461f65a82354e26d70c/_data",
    "Destination": "volume02",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    },
    {
    "Type": "volume",
    "Name": "e0584a1a806735c297b08629bb9ab4b1d419bbdc9a61fb5f526618a6096802b0",
    "Source": "/var/lib/docker/volumes/e0584a1a806735c297b08629bb9ab4b1d419bbdc9a61fb5f526618a6096802b0/_data",
    "Destination": "volumen01",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
    }
    ], #可以看到匿名挂载下,挂载的是同一个路径

    注:

    • 虽然挂载的时候有主次的关系,但是数据是互通的
    • 删除父容器,子容器内的数据还是能访问到,因为各个容器的数据卷真实主机地址的文件位置没有删
    • 主机->父容器->子容器,主机挂载数据卷到父容器,父容器作为数据卷容器对子容器挂载
    • 挂载的时候,本地一定会有对应的卷

Docker——容器数据卷的更多相关文章

  1. 『现学现忘』Docker基础 — 28、Docker容器数据卷介绍

    目录 1.什么是Docker容器数据卷 2.数据卷的作用 3.数据卷的使用 1.什么是Docker容器数据卷 Docker容器数据卷,即Docker Volume(卷). 当Docker容器运行的时候 ...

  2. docker 12 docker容器数据卷

    数据卷概念 ♣我们知道,当我们把一个运行中的容器关闭后,容器里的数据就没有了(如果你做了docker commit操作,数据会保留到新的镜像里面).所以我们就需要用容器数据卷把容器数据进行持久化储存. ...

  3. Docker容器数据卷

    ⒈Docker容器中数据如何持久化? ①通过commit命令使容器反向为镜像 ②以容器数据卷的方式将数据抽离 ⒉容器数据卷的作用? ①容器数据的持久化 ②容器间继承.共享数据 ⒊能干嘛? 卷就是目录或 ...

  4. Docker容器数据卷(七)

    Docker致力于: 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的 容器之间希望有可能共享数据 Docker容器产生的数据,如果不通过docker co ...

  5. 5、docker容器数据卷: -v添加共享传递容器数据卷

    1.是什么 1.docker理念 先来看看Docker的理念:*  将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的*  容器之间希望有可能共享数据 2.保 ...

  6. Docker 容器数据卷(Data Volume)与数据管理

    卷(Volume)是容器中的一个数据挂载点,卷可以绕过联合文件系统,从而为Docker 提供持久数据,所提供的数据还可以在宿主机-容器或多个容器之间共享.通过卷,我们可以可以使修改数据直接生效,而不必 ...

  7. Docker容器数据卷-Volume详解

    Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume).数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享.数据 ...

  8. docker学习笔记-04:docker容器数据卷

    一.容器数据卷是什么 1.为了保存docker容器运行时产生的数据,做数据的持久化,我们需要用到容器数据卷.因为如果不通过docker commit 生成新的镜像,那么当容器被删除时,数据自然就没有了 ...

  9. 『现学现忘』Docker基础 — 29、Docker容器数据卷的应用

    目录 1.验证容器和宿主机之间数据共享 2.容器停止退出后,主机修改后数据是否同步 3.带只读权限的挂载数据卷 1.验证容器和宿主机之间数据共享 通过上面的操作,接下来我们演示一下通过数据卷的挂载,实 ...

随机推荐

  1. python基础语法_字符串编码

    Python常用字符编码 http://www.cnblogs.com/schut/p/8406897.html   Python常见字符编码间的转换   在字符串写入文件时,有时会因编码问题导致无法 ...

  2. Java一维与二维数组的拷贝与排序

    Java一维与二维数组的拷贝与排序 目录 Java一维与二维数组的拷贝与排序 Arrays.sort() 一维数组升序排序 二维数组按行升序排序 二维数组按列升序排序 Java中的数组 Java中数组 ...

  3. KC705E增强版基于FMC接口的 Kintex-7 XC7K325T PCIeX8 接口卡

    一.板卡概述 本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8.64bit DDR3容量 ...

  4. windows设备相关位图与设备无关位图

    windows支持两种位图格式,DDB(device-dependent bitmap),DIB(device-independent bitmap).设备相关位图用于windows显示系统中,其图像 ...

  5. opencv笔记--Active contours

    Active Contours 也称作 Snake,通过定义封闭区域曲线的能量函数,并使其最小化得到最终曲线. Active Contours 被用作物体边界精确定位上,opencv 给出了一个实现, ...

  6. Note -「Min_25 筛」“你就说这素因子你要不要吧?你要不要?”

      赛上想写,Track Lost 了属于是. \(\mathscr{Intro}\)   Min_25 筛是用于求积性函数前缀和,同时顺带求出一些"有意思"的信息的筛法.   一 ...

  7. shell脚本批量配置多台主机静态ip

    关于脚本 服务器使用之前,都需要先配置静态IP,那就将这种简单重复的工作,交给脚本来处理吧,让我们运维有更多的时间喝茶看报刷微博 脚本使用 sh ssh.sh ip.txt ssh.sh 为脚本的名称 ...

  8. 利用shell脚本使用kubeadm部署kubenetes 1.18.6集群环境

    # README # 此脚本需要在master节点上使用 # 注意root密码,请提前修改 # 个人实验环境,注意机器最低配置:master(2G内存,1cpu2核心,否则集群会创建失败),node( ...

  9. 关于NSMutableAttributedString进行富文本 UILabel 的制作

    //1.初始化与其他无异 NSMutableAttributedString *AttributedStr2 = [[NSMutableAttributedString alloc]initWithS ...

  10. Linux之history使用技巧

    背景: 正常情况下,Linux系统中输入 history  只显示序号和历史命令如下图,但是当我们想要根据历史命令来排查一些故障问题时,无法精确获取该命令执行的详细信息,包括执行时间.执行的用户.是哪 ...