存在的问题:

  1. 存储于联合文件系统中的数据,宿主机不易访问。
  2. 容器间数据共享不方便。
  3. 删除容器其数据会丢失。

解决方案:
卷(Volume)是容器上的一个或多个目录(即:多个卷),此类目录可绕过联合文件系统,与宿主机上的某目录绑定,Docker中要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。

绑定挂载卷

Bind mount volume(绑定挂载卷),用户自定义指定Docker中的某目录挂载到宿主机的某个指定目录。

  1. version: "2"
  2. services:
  3. mysqldb:
  4. build: ./mysql
  5. container_name: mysql.db
  6. ...
  7. volumes:
  8. - ./mysql/data:/var/lib/mysql
  9. - ./mysql/conf/my.cnf:/etc/my.cnf
  10. - ./mysql/init:/docker-entrypoint-initdb.d/
  11. ...

匿名挂载卷

Docker-managed volume(Docker管理的卷),由Docker自己维护,用户需要在/etc/docker/daemon.json中指定启用“Docker自动启动容器”时,由Docker默认自动创建一个目录(关联宿主机),并与容器中指定目录关联的方式。
Docker容器默认会以root权限运行,所以挂载目录的owner都会是root,对于容器中使用非root用户运行的情况下(MySQL、Redis等),绝对路径的方式实现数据持久化可能会引发权限问题,而通过使用匿名数据卷可以帮助解决这一问题。

  1. version: "2"
  2. services:
  3. master:
  4. build: ./redis/master
  5. ....
  6. volumes:
  7. - data1:/data
  8. - ./redis/master/conf/redis.conf:/usr/local/etc/redis/redis.conf
  9. slave1:
  10. build: ./redis/slave1
  11. ....
  12. volumes:
  13. - data2:/data
  14. - ./redis/slave1/conf/redis.conf:/usr/local/etc/redis/redis.conf
  15. slave2:
  16. build: ./redis/slave2
  17. ....
  18. volumes:
  19. - data3:/data
  20. - ./redis/slave2/conf/redis.conf:/usr/local/etc/redis/redis.conf
  21. volumes:
  22. data1:
  23. data2:
  24. data3:

绝对路径方式,目录直接挂载到本地,比较直观,但需要管理本地的路径。匿名数据卷(卷标)的方式,比较简洁,但不知道数据存在本地什么位置,需要通过以下指令查看docker的卷标。

  1. # 查看所有卷标
  2. sudo docker volume ls
  3. # 根据名称查看卷标
  4. sudo docker volume ls | grep < 卷标 >
  5. # 查看具体的volume对应的真实地址
  6. sudo docker volume inspect < 卷标 >