Docker数据持久化
容器删除掉后,里边的数据也会跟着删除。数据的保存和重复可用这是最基本的要求,也就是常说的数据持久化。在写Dockerfile的时候可以用VOLUME
命令,指定数据持久化
VOLUME
命令设置持久化
当知道了容器中的数据不能持久化后,可以在编写Dockerfile
时用VOLUME
命令设置持久化的目录。
dockerfile
FROM ubuntu:21.04
VOLUME ["/app"]
RUN apt-get update && \
apt-get install vim -y
然后构建镜像 docker image build -t volume-test:1
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
volume-test 1 0526a62af1d2 16 seconds ago 180MB
....
并使用该镜像启动一个容器,参数为以命令行模式进入该容器
docker container run -it -p 3999:3999 0526a62af1d2 sh
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3999:3999 0526a62af1d2 sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# echo hello > app/hello.txt
# cd app
# ls
hello.txt
# cat hello.txt
hello
# exit
[root@iZwz9257qzx65bg8c3p88gZ docker-test]#
上面的操作分别是
- 进入容器,可以看到根目录下有
app
文件夹(通过VOLUME ["/app"]
指定的与宿主机共享数据的目录) - 然后进入
app
目录写入了一个hello
到app
下的hello.txt
文件,然后退出容器的命令行
然后我们需要验证这个文件是不是也同步到了我们的宿主机器上,这样才能保证完成容器数据的持久化`
docker volume
相关命令
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
首先 ls
查询所有的volume
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume ls
DRIVER VOLUME NAME
local 0bdf00aab64d926f21a6f90342e391d84a4c6ec14b67fe249f8c96ac4e59d91b
local 0ea958861d42b680f60053c59c5384a44069d53e7229f47118ffd64399b46926
local 01b1566780ad5af79b7228f10741b14cc38246e784f3fa5669fe7888a94bfb09
local 3cea763fa6e484560cc489b2aa9f794d370f0f34809a0a4fdd2e513a9c474a74
local 5d599f822fd7cf3f217423af17d483f14deecde3f0adaab300b5c777b3e77636
local 5f61686f8e896c94fb4e1ad2f518e9fb4e4160be75c5358be430919f7a1f5130
local 6b3f0fc9738e3402273e21b605629e6d5dfbf34c37747df4818fa5cd2b1e6059
local 7ae7a3c826c0bdf9a3f893266fedb5c6356d7067cb54bef2ca8506194483b635
local 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
local 8b24b542f0d75f7073c47e555d155c7719cd5d65c09b5b03b2a3f87dab4ba513
local 98e980c61c1b6fac75f899303f959f9ff8f788fdb6094edba8349d2dd950ce34
local 824de8cf2066827829e7ff90efc66073607956d8ad6c33e9d3811f8ba2cbc3e0
local 9759e4fb808c4674d384785b6bc746122d0284cafb2c94623d900c7f3508931e
local 40334acb4196bae68de3232bacb4dad775cc63b9cb96f4d9940c99acc3a491ce
local c69dc1de5d77b32eae6ccb7654921bbd63a07c4cf39b7b86ed818e79b211d480
local d5c0e014d7499a3a08642700f8ca8208f2d32a2d06fded94a621a82ccbf3cfe5
local e38488f4bd0dc6f910bee270bd1e1bd5ac9816d6f2e581f9406e7feab444cc45
然后找到我们刚刚创建的那个(这里我是一个一个找的…下面可以知道如何给volume
命名~)
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume inspect 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
[
{
"CreatedAt": "2021-11-28T16:06:46+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b/_data",
"Name": "8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b",
"Options": null,
"Scope": "local"
}
]
Mountpoint
对应的路径就是宿主机持久化数据的路径
[root@iZwz9257qzx65bg8c3p88gZ _data]# cd /var/lib/docker/volumes/8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b/_data
[root@iZwz9257qzx65bg8c3p88gZ _data]# ls
hello.txt
[root@iZwz9257qzx65bg8c3p88gZ _data]# cat hello.txt
hello
经过验证发现数据的确从容器同步到了宿主机,完成了容器数据的持久化~
设置启动容器volume
的名字
和上面不同的地方在于我们使用镜像启动容器的时候使用-v
命令
docker container run -d -v VolumeName:DockerfileVOLUMEPath image
我们这里的命令就变成了
docker container run -it -p 3999:3999 -v my-data:/app 0526a62af1d2 sh
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker container run -it -p 3999:3999 -v my-data:/app 0526a62af1d2 sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
# echo "hello my data" > hello.txt
# ls
hello.txt
# cat hello.txt
hello my data
# exit
重复文件的操作
然后退出,来到宿主机,查看宿主机docker
的volume
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume ls
DRIVER VOLUME NAME
local 0bdf00aab64d926f21a6f90342e391d84a4c6ec14b67fe249f8c96ac4e59d91b
local 0ea958861d42b680f60053c59c5384a44069d53e7229f47118ffd64399b46926
local 01b1566780ad5af79b7228f10741b14cc38246e784f3fa5669fe7888a94bfb09
local 3cea763fa6e484560cc489b2aa9f794d370f0f34809a0a4fdd2e513a9c474a74
local 5d599f822fd7cf3f217423af17d483f14deecde3f0adaab300b5c777b3e77636
local 5f61686f8e896c94fb4e1ad2f518e9fb4e4160be75c5358be430919f7a1f5130
local 6b3f0fc9738e3402273e21b605629e6d5dfbf34c37747df4818fa5cd2b1e6059
local 7ae7a3c826c0bdf9a3f893266fedb5c6356d7067cb54bef2ca8506194483b635
local 8ad42e37588d4bb6386f4c18e8c887ffd3a20d7ec4a4742947d01b6f7514331b
local 8b24b542f0d75f7073c47e555d155c7719cd5d65c09b5b03b2a3f87dab4ba513
local 98e980c61c1b6fac75f899303f959f9ff8f788fdb6094edba8349d2dd950ce34
local 824de8cf2066827829e7ff90efc66073607956d8ad6c33e9d3811f8ba2cbc3e0
local 9759e4fb808c4674d384785b6bc746122d0284cafb2c94623d900c7f3508931e
local 40334acb4196bae68de3232bacb4dad775cc63b9cb96f4d9940c99acc3a491ce
local c69dc1de5d77b32eae6ccb7654921bbd63a07c4cf39b7b86ed818e79b211d480
local d5c0e014d7499a3a08642700f8ca8208f2d32a2d06fded94a621a82ccbf3cfe5
local e9b25fe9c662b3d06d2914878b3d1ec498532fa8bf936de61ec1b6076d0fa360
local e38488f4bd0dc6f910bee270bd1e1bd5ac9816d6f2e581f9406e7feab444cc45
local my-data
这个时候,你就可以发现其中一条volume
是我们自定义的名称,查看详细的信息也的确是我们刚刚生成的
[root@iZwz9257qzx65bg8c3p88gZ _data]# docker volume inspect my-data
[
{
"CreatedAt": "2021-11-28T16:24:42+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-data/_data",
"Name": "my-data",
"Options": null,
"Scope": "local"
}
]
验证数据是否同步到了宿主机✅
[root@iZwz9257qzx65bg8c3p88gZ _data]# cd /var/lib/docker/volumes/my-data/_data
[root@iZwz9257qzx65bg8c3p88gZ _data]# ls
hello.txt
[root@iZwz9257qzx65bg8c3p88gZ _data]# cat hello.txt
hello my data
新容器使用宿主机的数据
已经会把容器(container
)中的数据和文件,保存在操作系统上了。现在的需求是,再创建一个容器,新容器如何用我们之前用volume
保存下来的的持久化数据?
现在我们本地已经有了之前的容器同步持久化下来的数据了,那么如果我们重新起了一个容器,如果去使用这一块数据呢~其实很简单和指定volume
名称的命令是一样的
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v my-data:/app --name datafromlocal volume-test sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
hello.txt
# cat hello.txt
hello my data
# exit
Bind Mount
实现数据持久化
数据持久化除了Data Volume
外,还有一种叫做Bind Mount
,从中文翻译来讲,就是挂载绑定
。简单讲就是把容器中持久化的数据,绑定到本机的一个自定义位置
Data Volume
,在WIndows/Mac环境中很难使用,因为路径是虚拟机的路径,不容易找到(mac都不太好找到的,下图的问题还未有解决方法,mac下找不到~哈哈)
相较于Data Volume
来说 Bind Mount
设置更简单,可以和开发环境更好的融合
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v ~/docker-test:/app --name datafromlocal volume-test sh
# ls
app bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
# cd app
# ls
dockerfile
# cat dockerfile
FROM ubuntu:21.04
VOLUME ["/app"]
RUN apt-get update && \
apt-get install vim -y
# ls
dockerfile
# exit
这种用法其实就是自定义了一个宿主机的目录同容器内的某个目录做绑定挂在,而不是像volume帮你管理在某个规定好的位置
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# ls
dockerfile
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# docker container run -it -p 3002:3002 -v ~/docker-test:/app --name datafromlocal volume-test sh
# cd app
# ls
dockerfile
# vim newFile.txt
# exit
[root@iZwz9257qzx65bg8c3p88gZ docker-test]# ls
dockerfile newFile.txt
完成了宿主机和容器的数据共享持久化!
- 容器内创建了一个
newFile.txt
- 退出容器回到宿主机通过
ls
命令,发现已经从容器中同步过来,完成了容器数据的持久化