存在的问题:
- 存储于联合文件系统中的数据,宿主机不易访问。
- 容器间数据共享不方便。
- 删除容器其数据会丢失。
解决方案:
卷(Volume)是容器上的一个或多个目录(即:多个卷),此类目录可绕过联合文件系统,与宿主机上的某目录绑定,Docker中要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。
绑定挂载卷
Bind mount volume(绑定挂载卷),用户自定义指定Docker中的某目录挂载到宿主机的某个指定目录。
version: "2"
services:
mysqldb:
build: ./mysql
container_name: mysql.db
...
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf/my.cnf:/etc/my.cnf
- ./mysql/init:/docker-entrypoint-initdb.d/
...
匿名挂载卷
Docker-managed volume(Docker管理的卷),由Docker自己维护,用户需要在/etc/docker/daemon.json中指定启用“Docker自动启动容器”时,由Docker默认自动创建一个目录(关联宿主机),并与容器中指定目录关联的方式。
Docker容器默认会以root权限运行,所以挂载目录的owner都会是root,对于容器中使用非root用户运行的情况下(MySQL、Redis等),绝对路径的方式实现数据持久化可能会引发权限问题,而通过使用匿名数据卷可以帮助解决这一问题。
version: "2"
services:
master:
build: ./redis/master
....
volumes:
- data1:/data
- ./redis/master/conf/redis.conf:/usr/local/etc/redis/redis.conf
slave1:
build: ./redis/slave1
....
volumes:
- data2:/data
- ./redis/slave1/conf/redis.conf:/usr/local/etc/redis/redis.conf
slave2:
build: ./redis/slave2
....
volumes:
- data3:/data
- ./redis/slave2/conf/redis.conf:/usr/local/etc/redis/redis.conf
volumes:
data1:
data2:
data3:
绝对路径方式,目录直接挂载到本地,比较直观,但需要管理本地的路径。匿名数据卷(卷标)的方式,比较简洁,但不知道数据存在本地什么位置,需要通过以下指令查看docker的卷标。
# 查看所有卷标
sudo docker volume ls
# 根据名称查看卷标
sudo docker volume ls | grep < 卷标 >
# 查看具体的volume对应的真实地址
sudo docker volume inspect < 卷标 >