• Docker中数据卷(Volume)的使用


    数据卷有两种形式,一种是容器中的某个目录,它可以被别的容器引用,只要有一个容器引用了这个数据卷,数据就不会被删除;另一种数据卷是将容器中的数据卷和宿主机的目录进行挂载。
    数据卷可以在多个容器之间共享,修改数据卷不会影响镜像。

    创建数据卷

    docker run -itd --name data1 -v /opt/data ubuntu:18.04 : 创建一个带有数据卷的容器,数据卷的位置是/opt/data,目录不存在会自动创建,该容器的数据卷可以被其他容器引用(容器有读写权限)

    docker run -itd --name data1 -v /opt/data ubuntu:18.04
    87e1508b7825e9e24a90eb7e0c6998aff987634405903163c9329856b3f249a1
    
    [root@localhost dockerdir]# docker inspect 87e1508b7825 | grep volumes
    "Source": "/var/lib/docker/volumes/a0fb7c1f9c33efe41600fab9eaa612d409c75ce2e077107f1c8f5d798499bb57/_data",
    
    [root@localhost dockerdir]# cd /var/lib/docker/volumes/a0fb7c1f9c33efe41600fab9eaa612d409c75ce2e077107f1c8f5d798499bb57/_data
    [root@localhost _data]# echo "afjsldajf;lasjkfd;lakdsjf;lajf;ljdsalfj" >> data.txt
    
    [root@localhost _data]# docker exec -it 87e1508b7825 bash
    root@87e1508b7825:/# cd /opt/data
    root@87e1508b7825:/opt/data# cat data.txt
    afjsldajf;lasjkfd;lakdsjf;lajf;ljdsalfj
    

    挂载宿主机的目录到数据卷

    • docker run -itd --name data2 -v $(pwd):/opt/data ubuntu:18.04 : 将当前目录(或文件)挂载到容器的opt/data目录(或文件)下。宿主的目录(或文件)必须要已经存在,而容器中的目录(或文件)会自动创建。

    查看数据卷在宿主机中对应的目录
    docker inspect data|grep /var/lib/docker/volumes

    [root@localhost dockerdir]# docker run -itd --name data2  -v $(pwd):/opt/data ubuntu:18.04
    a6969d01a4778884d75b4a2820c7d1835ee659c40516b6bb7cab1268f49a90d1
    [root@localhost dockerdir]# echo "this is data" >> data2.txt
    
    [root@localhost dockerdir]# docker exec -it data2 bash
    root@a6969d01a477:/opt/data# cat data2.txt 
    this is data
    
    • docker run -it --name data3 -v $(pwd)/dockerdir1:/opt/data1 -v $(pwd)/dockerdir2:/opt/data2 ubuntu:18.04 : 挂载多个目录。

    另外,可以在-v后用ro和wo表示在容器中只读和只写($(pwd):/opt/data:ro),不加表示不限制

    引用数据卷

    • docker run -itd --name data4 --volumes-from data3 ubuntu:18.04 : 从data3中引用数据卷,可以继续引用data4,也可以直接应用data3。一次性将data3的两个数据卷都引用了过来
    • 只要依然有容器在使用这些数据卷,数据就不会丢失。除非没有容器引用它。
    [root@localhost dockerdir]# docker run -itd --name data4 --volumes-from data3 ubuntu:18.04
    
    [root@localhost dockerdir]# docker inspect data3 | grep Source
                    "Source": "/root/dockerdir/dockerdir1",
                    "Source": "/root/dockerdir/dockerdir2",
    
    [root@localhost dockerdir]# docker inspect data4 | grep Source
                    "Source": "/root/dockerdir/dockerdir2",
                    "Source": "/root/dockerdir/dockerdir1",
    

    备份数据卷

    思路是,先引用需要的数据卷。再自己把宿主机上的某个地址dir1挂载到容器的dir2上,然后在容器里面,将数据卷中的内容都打包放到dir2中。这样在宿主机中就可以得到这些打包好的数据。

    docker run -itd --rm --name data5 --volumes-from data3 -v $(pwd):/opt/backup ubuntu:18.04 tar cvf /opt/backup/data5_backup.tar /opt/data1 /opt/data2 : 引用data3的两个数据卷,在将数据打包放到于外部挂载的opt/backup/目录上,这样就可以直接在外部拿到这些数据。--rm 容器用完就自动删除。

    [root@localhost dockerdir]# docker run -itd --rm --name data5 --volumes-from data3 -v $(pwd):/opt/backup ubuntu:18.04 tar cvf /opt/backup/data5_backup.tar /opt/data1 /opt/data2
    
    [root@localhost dockerdir]# ls 
    data2.txt  data5_backup.tar  dockerdir1  dockerdir2  Dockerfile
    

    恢复数据

    与数据挂载的用法类似,将备份文件所在的目录与容器中的目录挂载起来。在容器中解压备份文件到数据卷中,就可以完成数据的恢复。这部分可以活学活用,用法极多。

    # 创建一个容器,他有两个数据卷
    [root@localhost dockerdir]# docker run -itd --name data5 --privileged=true -v $(pwd)/dockerdir1:/opt/data1 -v $(pwd)/dockerdir2:/opt/data2 ubuntu:18.04
    
    # 备份数据卷的内容
    [root@localhost dockerdir]# docker run -it --rm --volumes-from data5 -v $(pwd):/opt/backup ubuntu:18.04 tar cvf /opt/backup/data5_backup.tar /opt/data1 /opt/data2
    
    # 删除目录中的文件,在容器中不可删除目录,但是目录中的文件已经被删除了。在宿主中可以删除目录
    root@aefbfa71f132:/opt# rm -rf data2
    rm: cannot remove 'data2': Device or resource busy
    root@aefbfa71f132:/opt# ls data2
    
    # 恢复数据
    [root@localhost dockerdir]# docker run -it --rm --name recover1 --volumes-from data5 -v $(pwd):/opt/backup ubuntu:18.04 tar xvf /opt/backup/data5_backup.tar -C /
    opt/data1/
    opt/data1/data
    opt/data2/
    opt/data2/file_in_data5.dat
    
    root@aefbfa71f132:/opt# ls data2
    file_in_data5.dat
    

    由于selinux的作用,如果将容器数据卷挂载到宿主机的目录上,在容器中将无法操作数据卷,解决方法是给容器加上一个优先级 --privileged=true

    docker run -itd --name data5 --privileged=true -v $(pwd)/dockerdir1:/opt/data1 -v $(pwd)/dockerdir2:/opt/data2 ubuntu:18.04

    参考资料

    https://www.cnblogs.com/mydba-j/articles/9797931.html

  • 相关阅读:
    7.4 List集合
    vue学习笔记
    javaWEB中web.xml配置文件相关
    maven常用dos命令
    Oracle,sqlserver,mySQl的区别和联系:
    oracle数据库视图,序列,索引的sql语句查看
    java 异常处理
    线程专题
    package、folder和source folder的区别
    Java内存分配之堆、栈和常量池
  • 原文地址:https://www.cnblogs.com/twilight0402/p/13412957.html
Copyright © 2020-2023  润新知