Docker数据卷的使用

1,158 阅读5分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

前面学习了docker的命令和镜像原理,docker算是简单的入门了,今天可以搞点稍微复杂的东西了,学习下容器数据卷

什么是容器数据卷?如果数据都存在容器中,那么容器删掉了数据也就丢失了,在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中,后面我们会通过具体的操作看下什么是数据卷

使用数据卷

通过命令直接挂载

docker run -it -v 主机目录:容器目录

我这边将容器中的/home目录挂载到宿主机的/Users/cb/test目录下(如果你本机没有centos镜像会先去下载)

$ docker run -it -v  /Users/cb/test:/home centos /bin/bash
[root@78c0a6fa144b /]#

执行完上面的命令后,我们通过docker inspect 命令查看下

docker inspect 容器id

在如下的输出的信息中可以看到容器挂载的关系,也就是我们挂载成功了

  • Source:主机内地址
  • Destination:docker容器内的地址
"Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/cb/test",
                "Destination": "/home",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]

绑定成功或者说挂载成功后,也就是有了双向绑定关系,数据就可以进行同步,我们来看下效果

开始的时候两边文件夹都是空的

我们在容器内部加一个文件看下

可以看到容器内的文件成功同步到了宿主机上

然后我们把容器停了,在宿主机上修改文件然后再启动容器看下数据也是可以正常同步

我这边列下命令,你可以自己操作下

1、exit 退出容器
2、修改宿主机文件
3、docker ps -a 查看最近启动的容器 、docker run 容器id  启动容器
4、查看容器中的文件内容

这个例子就是最直观的数据卷,数据卷还有一个用途,对于一些配置我们也可以使用映射将经常修改的配置映射到本地,本地修改后自动同步到容器

安装mysql

如果在docker中安装mysql那么数据一定不能放在容器中,容器一旦删除容器中的数据也会被删除。我们可以通过数据卷将对数据进行同步

通过如下命令将容器内的mysql的配置、数据同步到宿主机中

docker run -d -p 3310:3306 -v /Users/chenbang/home/mysql/conf:/etc/mysql/conf.d -v /Users/chenbang/home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
  • -d 后台运行
  • -p 端口映射
  • -v 数据卷挂载
  • -e 环境配置(启动mysql的时候一定要配置密码)

启动成功之后在本地用三方的客户端连接看下,是可以正常连接的

我们看下宿主机中目标路径下有对应的conf、data

在data中有对应的数据,看着数据是同步过来了...

我们在可视化工具中新建一个库,对应到data应该是一个文件

我们再看下宿主机目标路径data文件夹下的内容,果然多了我们刚刚新增的ajtest库

然后我们再把容器删了看下

操作之后可以发现数据依然健在...数据不会丢失

这就实现了容器内数据持久化!

匿名挂载

通过如下命令启动容器

docker run -d -P --name nginx01 -v /etc/nginx nginx 

我们在通过查看下所有数据卷的情况

docker volume ls

由上图可以看到,VOLUME NAME 有的是随机生成的字符串,对于这种就是匿名挂载,因为-v的时候只写了容器内的路径看,而没有写容器外的路径

具名挂载

通过如下命令启动容器

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

可以看到指定名称的数据卷,所以具名挂载可以通过 "-v 卷名:容器内路径"

我们看下这个卷的路径

➜  ~ docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2021-08-17T12:18:04Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/XXX

我们可以进这个目录看下

如果宿主机是mac会发现找不到/var/lib/docker...,原因是mac下 docker 实际是在vm里又加了一层,因此需要进入 vm 才能进行操作。

在网上找到的解决方案如下:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

尝试之后发现直接闪退并提示如下:

[screen is terminating]

故需解决这个闪退问题,解决方案如下:

docker run -it --privileged --pid=host justincormack/nsenter1

Unable to find image 'justincormack/nsenter1:latest' locally
latest: Pulling from justincormack/nsenter1
5bc638ae6f98: Pull complete 
Digest: sha256:e876f694a4cb6ff9e6861197ea3680fe2e3c5ab773a1e37ca1f13171f7f5798e
Status: Downloaded newer image for justincormack/nsenter1:latest
/ # cd /var/lib/docker/

可以看到docker工作目录下的内容

进入volumes中看下,可以看到所有数据卷

看下juming-nginx

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的,不建议大家使用匿名挂载

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

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

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

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

拓展:

通过-v容器内路径:ro/rw 可改变读写权限

ro readonly #只读

rw readwrite #可读可写

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

一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了!

关于docker数据卷的使用今天就先讲到这里吧,后面会继续接受Dockerfile,尽可能完整的学习下docker这快的使用,大家加油!!!

十步杀一人,千里不留行 -李白