• 5.Docker数据管理


    Docker数据管理

    在生产环境中使用 Docker涉及容器的数据管理操作,需要对数据进行持久化或者需要在多个容器之间进行数据共享。

    容器中的管理数据主要有两种方式:

    • 数据卷 (Data Volumes): 容器内数据直接映射到本地主机环境;

      在容器内创建数据卷, 并且把本地的目录或文件挂载到容器内的数据卷中。

    • 数据卷容器 (Data Volume Containers): 使用特定容器维护数据卷。

      使用数据卷容器在容器和主机、 容器和容器之间共享数据, 并实现数据的备份和恢复。

    1、数据卷

    数据卷(Data Volumes)是一个可供容器使用的特殊目录映射进容器,它将主机操作系统目录直接类似于Linux中的mount行为。

    数据卷特性:

    • 数据卷可以在容器之间共享和重用, 容器间传递数据将变得高效与方便;
    • 对数据卷内数据的修改会立马生效, 无论是容器内操作还是本地操作;
    • 对数据卷的更新不会影响镜像, 解耦开应用和数据;
    • 卷会一直存在, 直到没有容器使用, 可以安全地卸载它。

    1.1、创建数据卷

    volume子命令管理数据卷

    [root@localhost ~]# docker volume create -d local test
    test
    #查看/var/lib/docker/volumes路径下,会发现所创建的数据卷位置
    [root@localhost ~]# ls -l /var/lib/docker/volumes/
    drwx-----x. 3 root root     19 56 23:03 test
    

    docker volume还支持inspect(查看详细信息)、ls (列出已有数据卷)、prune(清理无用数据卷)、rm(删除数据卷)等。

    [root@localhost ~]# docker volume inspect test
    [
        {
            "CreatedAt": "2024-05-06T23:03:37-04:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/test/_data",
            "Name": "test",
            "Options": null,
            "Scope": "local"
        }
    ]
    [root@localhost ~]# docker volume ls
    DRIVER    VOLUME NAME
    local     3c5f45922be6ba271bd6f40bfb160d55d6552e46a2b0155ed6c31fee47dbf430
    local     baf0e871e0586fdc374d0451354c488a413270ccc8cb4e7c53a47510c30b01ad
    local     test
    [root@localhost ~]# docker volume prune
    WARNING! This will remove anonymous local volumes not used by at least one container.
    Are you sure you want to continue? [y/N] y
    Total reclaimed space: 0B
    

    1.2、绑定数据卷

    在创建容器时将主机本地的任意路径挂载到容器内作为数据卷,这种形式创建的数据卷称为绑定数据卷。

    docker [container] run命令可以使用-mount选项来使用数据卷。

    -mount选项支持三种类型的数据卷:

    • volume: 普通数据卷,映射到主机 /var/lib/docker/volumes路径下;
    • bind: 绑定数据卷, 映射到主机指定路径下;
    • tmpfs: 临时数据卷,只存在于内存中。

    举例:使用 training/webapp镜像创建一个Web容器,并创建一个数据卷挂载到容器的/opt/webapp目录。

    [root@localhost ~]$ mkdir /webapp
    [root@localhost ~]$ docker run -d -it -P --name web --mount type=bind,source=/webapp,destination=/opt/webapp ubuntu /bin/bash
    #等价于使用旧的 -v标记可以在容器内创建一个数据卷
    $ docker run -d -it -P --name web -v /webapp:/opt/webapp ubuntu /bin/bash
    #测试
    [root@localhost ~]# cd /webapp/
    [root@localhost webapp]# touch a
    [root@localhost webapp]# ls
    a  
    [root@localhost ~]# docker exec -it adc2b32202cd /bin/bash
    root@adc2b32202cd:/# cd /opt/webapp/
    root@adc2b32202cd:/opt/webapp# ls
    a
    

    用户可以放置一些程序或数据到本地目录中实时进行更新,然后在容器内运行和使用。本地目录的路径必须是绝对路径,容器内路径可以为相对路径。如果目录不存在,Docker会自动创建。

    查看数据卷是否挂载成功:

    docker inspect 容器名称
    

    Docker挂载数据卷的默认权限是读写(rw), 用户也可以通过ro指定为只读,容器内对所挂载数据卷内的数据就无法修改。

    $ docker run -d -it -P --name web -v /webapp:/opt/webapp:ro ubuntu /bin/bash
    

    直接挂载一个文件到容器,使用文件编辑工具,包括 vi或者sed --in-place 的时候,可能会造成文件 inode的改变。从Docker 1. 1 .0起,这会导致报错误信息。所以推荐的方式是直接挂载文件所 在的目录到容器内。

    💡Docker挂载主机目录访问如果出现cannot open directory .: Permission denied

    解决办法:在挂载目录后多加一个–privileged=true参数即可。

    原因是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

    2、数据卷容器

    数据卷容器是专门提供数据卷给其他容器挂载的容器。如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。

    1. 创建一个数据卷容器dbdata, 并在其中创建一个数据卷挂载到/dbdata

      [root@localhost ~]# mkdir /dbdata
      [root@localhost ~]# docker run -it -v /dbdata --name dbdata ubuntu
      root@529ee7fec788:/# ls
      bin  boot  dbdata  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
      
    2. 可以在其他容器中使用–volumes-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器并从dbdata容器挂载数据卷。

      [root@localhost ~]# docker run -it -d --volumes-from dbdata --name db1 ubuntu
      63241c4a05903f0dad1a13ded4d4390b2978ab801bb999773d8459f2e3b786e6
      [root@localhost ~]# docker run -it -d --volumes-from dbdata --name db2 ubuntu
      51cc6dadb57707bfb39e0a8d9c3e79d7bcde52a82c4fb1e971c51898c5681079
      
      [root@localhost ~]# docker exec -it db1 /bin/bash
      root@63241c4a0590:/# ls
      bin  boot  dbdata  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
      

      在数据卷容器dbdata中挂载目录创建文件后,在db1和db2中可以看到和使用。

    🔔可以多次使用--volumes-from参数来从多个容器挂载多个数据卷,还可以从其他已经挂载了容器卷的容器来挂载数据卷。使用--volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态。

    如果删除了挂载的容器(包括dbdata、db1和db2), 数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式使用docker rm -v命令来指定同时删除关联的容器。

    [root@localhost ~]# docker run -it -d --name db3 --volumes-from db1 ubuntu
    f739ab152a712eeb3dda3f079c490d06338bfb8f89137f7abc3ccb6f110e0f0b
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE        COMMAND                   CREATED         STATUS          PORTS                                       NAMES
    f739ab152a71   ubuntu       "bash"                    2 seconds ago   Up 2 seconds                                                db3
    51cc6dadb577   ubuntu       "bash"                    2 hours ago     Up 52 seconds                                               db2
    63241c4a0590   ubuntu       "bash"                    2 hours ago     Up 53 seconds                                               db1
    529ee7fec788   ubuntu       "bash"                    3 hours ago     Up 58 seconds                                               dbdata
    [root@localhost ~]# 
    [root@localhost ~]# docker exec -it db3 /bin/bash
    root@f739ab152a71:/# 
    root@f739ab152a71:/# ls
    bin  boot  dbdata  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    root@f739ab152a71:/# exit
    exit
    
    [root@localhost ~]# docker rm -v db1 db3
    Error response from daemon: cannot remove container "/db1": container is running: stop the container before removing or force remove
    Error response from daemon: cannot remove container "/db3": container is running: stop the container before removing or force remove
    [root@localhost ~]# docker stop db1
    db1
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE        COMMAND                   CREATED              STATUS              PORTS                                       NAMES
    f739ab152a71   ubuntu       "bash"                    About a minute ago   Up About a minute                                               db3
    51cc6dadb577   ubuntu       "bash"                    2 hours ago          Up 2 minutes                                                    db2
    529ee7fec788   ubuntu       "bash"                    3 hours ago          Up 2 minutes                                                    dbdata
    [root@localhost ~]# docker stop db3
    db3
    [root@localhost ~]# docker rm -v db1 db3
    db1
    db3
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE        COMMAND                   CREATED       STATUS          PORTS                                       NAMES
    51cc6dadb577   ubuntu       "bash"                    2 hours ago   Up 2 minutes                                                db2
    529ee7fec788   ubuntu       "bash"                    3 hours ago   Up 2 minutes                                                dbdata
    

    3、利用数据卷容器迁移数据

    3.1、备份

    备份dbdata数据卷容器内的数据卷

    docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar
    cvf /backup/backup.tar /dbdata
    

    理解:

    1. 专门启动一个worker容器,将当前目录映射到容器的/backup目录下;
    2. 使用--volumes-from dbdata参数来让worker容器挂载dbdata容器的数据卷;
    3. 将worker容器中的/dbdata目录压缩存储至backup目录下;
    4. 此时查看宿主机本地目录,可以查看到压缩包。

    3.2、恢复

    1.创建一个带有数据卷的容器dbdata2

    $ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
    

    2.创建另一个新的容器, 挂载dbdata2的容器, 并使用untar解压备份文件到所挂载的容器卷中

    $ docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar -C /dbdata
    #等价于
    $ docker run --mount source=dbdata2,target=/dbd --mount type=bind,source=$(pwd),target=/backup busybox tar xvf /backup/backup.tar -C /dbd
    

    总结

    ​ 数据卷机制为数据管理提供了方便的操作支持 。通过数据卷和数据卷容器对容器内的数据进行共享、备份和恢复等操作, 这些机制即使容器在运行中出现故障,用户也不必担心数据发生丢失, 只需要快速地重新创建容器即可。

    ​ 在生产环境中推荐在使用数据卷或数据卷容器之外,定期将主机的本地数据进行备份, 或者使用支持容错的存储系统, 包括 RAID 或分布式文件系统。
    ​ 另外, 有些时候不希望将数据保存在宿主机或容器中, 还可以使用 tmpfs类型的数据卷, 其中数据只存在内存中, 容器退出后自动删除。

  • 相关阅读:
    anaconda 虚拟环境中安装nginx
    c# 读写内存映射文件
    原生js实现扫雷
    【Python】turtle库的介绍及使用
    兼容MacOS和FreeBSD软件包的开源ravynOS操作系统
    镜头相关知识
    苍穹外卖-01
    无货源操作方式
    2022网络搭建国赛题交换机安全配置
    深入理解计算机网络—5物理层
  • 原文地址:https://blog.csdn.net/qq_36593748/article/details/138549013