这是我参与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这快的使用,大家加油!!!
十步杀一人,千里不留行 -李白