zoukankan      html  css  js  c++  java
  • Docker笔记(八):数据管理

    前面(哪个前面我也忘了)有说过,如果我们需要对数据进行持久化保存,不应使其存储在容器中,因为容器中的数据会随着容器的删除而丢失,而因通过将数据存储于宿主机文件系统的形式来持久化。在Docker容器中管理数据主要有数据卷、宿主机目录挂载两种方式。

    1. 数据卷的方式

    数据卷是一个特殊的文件目录(或文件),具备如下特性:

    1. 可以在容器之间共享和重用

    2. 对数据卷的修改会立马生效
    3. 数据卷的更新,不会影响到镜像
    4. 数据卷默认会一直存在,不会随容器的删除而消亡

     

    1.1 创建数据卷

    可以使用docker volume create 数据卷名称的命令来创建一个数据卷,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume create volume1
    volume1

    1.2 查看数据卷

    创建完后,这个数据卷具体对应宿主机哪个文件目录在上面是没法得知的,可以通过 docker volume inspect 数据卷名称来查看,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume inspect volume1
    [
        {
            "CreatedAt": "2019-08-12T19:43:47+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/volume1/_data",
            "Name": "volume1",
            "Options": {},
            "Scope": "local"
        }
    ]
    可以看到数据卷volume1对应的文件目录是“/var/lib/docker/volumes/volume1/_data”。

    docker inspect xxx这个命令挺有用的,不论是查看镜像相关信息(docker image inspect 镜像名/镜像ID),还是查看容器相关信息(docker container inspect 容器名/容器ID),都可以使用,其中的image,container,volume是可以省略的,只要xxx部分不冲突就行。
    可以通过docker volume ls 命令来查看所有数据卷,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume ls
    DRIVER              VOLUME NAME
    local               volume1

    1.3 使用数据卷

    可以在启动容器时通过 -v 或 –mount 的方式将一个数据卷挂载到容器的某个目录

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v volume1:/vol1 ubuntu:18.04
    b060e793d44de2ca871da257b47598334658952943a13d1c478df5c3ae91a01c

    按照 -v 数据卷名:容器目录 的格式,也可以使用 –mount 按照 --mount source=数据卷名,target=容器目录 的格式,如我们再启动一个挂载相同数据卷的容器 ubuntu2,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount source=volume1,target=/vol2 ubuntu:18.04
    b30971f8a4bbadee10774fce0b4568b5b7b1c9cde36f4bf84ac911a4cdaf6c8d

    可以在数据卷所在目录中创建一个文件来看看效果,先创建文件 hello.txt

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# cd /var/lib/docker/volumes/volume1/_data
    [root@iZwz9dbodbaqxj1gxhpnjxZ _data]# touch hello.txt
    [root@iZwz9dbodbaqxj1gxhpnjxZ _data]# ls
    hello.txt

    然后通过docker exec来查看容器ubuntu1目录/vol1,及容器ubuntu2目录/vol2的内容

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu1 ls /vol1
    hello.txt
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu2 ls /vol2
    hello.txt

    可以看到通过挂载目录 /vol1, /vol2 都可以访问到数据卷volume1对应目录下的内容。这就像linux的软链接一样,将容器目录链接到了数据卷目录。并且上述示例也说明,同一个数据卷是可以在被多个容器共享的。

    数据卷的共享也可以通过 volumes-from 容器名称/容器ID 参数来实现,如

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 --volumes-from ubuntu2 ubuntu:18.04
    bb5c6d61a1e6eeb18ba8c889e471b2f3215f97efca79b311eeca5968b2700df8
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 ls /vol2
    hello.txt

    通过--volumes-from ubuntu2来直接使用ubuntu2挂载的容器配置。

     

    1.4 删除数据卷

    数据卷不会随着容器的删除而自动删除。如果一个数据卷还被某个容器使用,则不能删除;如果一个数据卷只被一个容器使用,则可在删除容器时通过指定 -v 参数同时删除其挂载的数据卷;

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker rm -v ubuntu3
    ubuntu3

    可以通过 docker volume rm 数据卷名称 来删除某个数据卷;

    可以通过 docker volume prune 清理掉所有未被任何容器使用的数据卷。

     

    2. 宿主机目录挂载方式

    在容器启动时,使用 -v 宿主机目录:容器目录 或 --mount type=bind,source=宿主机目录,target=容器目录的参数格式指定将宿主机目录挂载到容器目录上。宿主机目录必须是绝对路径。两者之间的区别是 -v 如果在宿主机目录不存在时会自动创建目录,而--mount不会。如,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v /root/v1:/vol1 ubuntu:18.04
    25c91911709eebc9290b47b483666f7b7be840df947117f7cad323583905b9f1
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04
    docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /root/v2.
    See 'docker run --help'.
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# mkdir /root/v2
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04
    5a57285e9261d048dc71cf0476055a290f80538afff2cefd2a24f8b4468b5171

    /root/v1,/root/v2都没有事先创建,用 -v 不会报错,会自动创建; --mount则会报错,目录必须先存在。docker不仅支持目录的挂载,也支持文件的挂载,如,

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run --rm -it -v $HOME/.bash_history:/root/.bash_history ubuntu:18.04 bash
    root@3ae4ed4e687d:/# history
        1  ll webapps/
        2  ll confluence/images/

    通过将宿主机当前用户的历史操作文件挂载到容器的root用户下的历史操作文件,可在容器中通过history命令查看到宿主机的操作历史。可通过 docker inspect来查看容器的挂载情况

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker inspect ubuntu1
    --省略了其它信息--
    "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/root/v1",
                    "Destination": "/vol1",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    --省略了其它信息--
    可在“Mounts”部分看到挂载信息。

     

    3. 只读控制

    有时候,为了数据安全,我们不允许容器对挂载目录的内容进行修改,即对容器来说,挂载目录是只读的,这可以通过在挂载参数后面加限制实现。

    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 -v /root/v1:/vol1:ro ubuntu:18.04
    25eca348ed307afcbef92bc03f0a1304b31b52e6db1fa07772b5dbd1040ff7b6
    [root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 bash
    root@25eca348ed30:/# touch /vol1/hello.txt
    touch: cannot touch '/vol1/hello.txt': Read-only file system
    -v是在后面加ro(read-only),--mount则是形如--mount type=bind,source=宿主机目录,target=容器目录,read only的格式,可自行试验。

    加了read only的挂载我们再通过docker inspect命令查看,可看到两者之间的差异 —— Mode与RW的值。

    "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/root/v1",
                    "Destination": "/vol1",
                    "Mode": "ro",
                    "RW": false,
                    "Propagation": "rprivate"
                }
            ],

    4. 总结

    如果要对数据进行持久化管理或在容器之间共享数据,则需要将数据通过数据卷或宿主机目录(或文件)挂载的方式来将数据存储于宿主机上,使得数据的生命周期独立于容器的生命周期。这类似于我们不要把重要文件放在系统盘,而应放在其它数据盘一样,因为系统盘会由于重装系统或系统故障导致文件丢失。本文对Docker的数据管理进行了整理,后续对Docker的网络配置管理部分进行整理,欢迎持续关注。

    相关阅读

    Docker笔记(一):什么是Docker
    Docker笔记(二):Docker管理的对象
    Docker笔记(三):Docker安装与配置
    Docker笔记(四):Docker镜像管理
    Docker笔记(五):整一个自己的镜像
    Docker笔记(六):容器管理
    Docker笔记(七):常用服务安装——Nginx、MySql、Redis

    本文发表于微信公众号:“空山新雨的技术空间”

    作者:空山新雨
    欢迎关注,转发,推荐,你的支持是我持续创作的动力

  • 相关阅读:
    异常显示页面
    SpringBoot项目打包的两种类型1-WAR方式
    SpringBoot项目打包的两种类型1-JAR方式
    Spring Boot项目打包部署
    json转义处理
    xadmin使用
    nginx 反向代理
    python 队列、栈
    Django logging配置
    Tensorflow学习教程------普通神经网络对mnist数据集分类
  • 原文地址:https://www.cnblogs.com/spec-dog/p/11343794.html
Copyright © 2011-2022 走看看