Docker的进阶理解笔记一(数据管理)

Docker 数据管理

当我们的某个运行中的Docker Container修改容器内部的数据时,新的数据存在哪里呢?数据文件如何在Container中存储的?我们先看一下下图
在这里插入图片描述
通过上图,我们看到容器存储的数据,主要是两总方式,一种是直接写到Container的文件系统中,另一种是是存储到数据卷

1直接写到Container容器内部

Docker镜像是分成设计的,镜像是只读的,通过镜像启动容器时(使用命令docker run),容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层中。

添加了一层可读写的文件系统是啥意思?其实本质就是,创建并启动一个容器时,docker先拷贝一份镜像的文件系统,这层文件系统是只读的,不能修改的。然后在创建另外一个独立的目录,这个目录才是保存着修改的文件,这里是可读写的。而我们在使用docker exec -it <containerName> /bin/bash 命令进入容器内部时,会看到另外一个合并的文件系统,即镜像的文件系统目录+那个可读写的文件目录。

那么上面说的这几个文件目录在哪里,都打包在该容器的某个数据库文件中? 其实,这几个目录真的存在,而且有对应的docker主机下的目录。 所谓的包了一层其实是抽象概念,真实的是,他们分别是不同的几个文件夹。那他们在哪里呢?

我们通过docker inspect <containerName|Id>查看某个容器的详情

docker inspect 2afe764a900a
[
    {
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/e19ce17e6eff2d080d61ee5ad0979cd77d559119640b4c7b4d375ef51c79c2ce-init/diff:/var/lib/docker/overlay2/dfd5f693e66868f1a57ee34f20d79900f03e3e5d78cb869fb99c4da5482f91bf/diff:/var/lib/docker/overlay2/4df66261ce4e6c19b9906bc6811ee4f92e05f9909642b52afe0eb207f1f3a746/diff",
                "MergedDir": "/var/lib/docker/overlay2/e19ce17e6eff2d080d61ee5ad0979cd77d559119640b4c7b4d375ef51c79c2ce/merged",
                "UpperDir": "/var/lib/docker/overlay2/e19ce17e6eff2d080d61ee5ad0979cd77d559119640b4c7b4d375ef51c79c2ce/diff",
                "WorkDir": "/var/lib/docker/overlay2/e19ce17e6eff2d080d61ee5ad0979cd77d559119640b4c7b4d375ef51c79c2ce/work"
            },
            "Name": "overlay2"
        }
    }
]

通过查看容器详情的GraphDriver.Data,我们可以知道有下面几个重要目录

  • LowerDir:image 镜像层(镜像本身,只读)
  • UpperDir:容器的上层(读写)
  • MergedDir:容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和upperdir 合并给容器使用
  • WorkDir:容器在 宿主机的工作目录

所以,每一个容器运行的分层的文件系统,其实都可以在宿主机中找到对应的(通常在docker安装目录下/var/lib/docker/overlay2)

更神奇的是,当你在UpperDir中修改了任何数据,进入容器内部,也跟着修改,同理在容器的任何修改,都将回写到该目录下(与挂在数据卷后的效果一样的,只是,挂着数据卷才是官方推荐的正道),理解了这一点后很重要,我们对Docker 容器的理解又深入了一点;这也就是为什么Docker运行的效率高。其实Docker本质就是直接使用主机下的资源。

2 写到数据卷中

我们知道容器的设计之初就是用来经常删除创建的,所以直接把数据写到容器内,很容易不小心被删除。所以,一般重要的数据,都会挂着一个数据卷。也就是,把主机上的一个目录,映射或挂载到容器内部。

其实当我们理解了前面的介绍后,就无所谓内部外部了,本质都是操作主机上的某些目录;但是,抽象的思维很重要,必须要顺从docker容器的思维,区分内部与外部。

这里我们需要注意的是,docker提供三种写入到数据卷的类型,如下图

  • bind muount #挂载任意目录或文件
  • Volumes #固定路径的目录,docker管理
  • tmpfs mounts #存放宿主机内存中
    在这里插入图片描述

详情见docker官方介绍 关于存储数据卷

如何挂在一个数据卷?

docker run -itd --name <newContainerAlias> -v </host/path>:</conatiner/path> <imageName:tag> /bin/bash
# eg docker run -itd --name vUbuntu -v /docker/vUbuntu:/data ubuntu:15.10 /bin/bash

当然,Docker提供了一个更推荐的方式(本质都一样);先声明定义数据卷,在挂在使用数据卷
这样的好处是,该数据卷可被docker监控

# 创建数据卷
dokcer volume create myUbuntuData

# 挂载刚才的创建的数据卷
ocker run -itd --name vUbuntu -v myUbuntuData:/data ubuntu:15.10 /bin/bash

Bind mounts和Volumes行为上的差异

Volumes: 如果你将一个空Volume挂载到一个非空容器目录上,那么这个容器目录中的文件会被复制到Volume中,即容器目录原有文件不会被Volume覆盖。

Bind mounts: 如果你使用Bind mounts将一个宿主机目录挂载到容器目录上,此容器目录中原有的文件会被隐藏,从而只能读取到宿主机目录下的文件。

写到内存 tmpfs mounts

# 使用--tmpfs
docker run -dit --tmpfs /app ubuntu:15.10 /bin/bash

更多volume功能(NFS存储)的推荐一篇https://www.cnblogs.com/elvi/p/8463673.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值