Docker教程


何时需要使用Docker Volume?

在前面的例子中,如果我们在MongoDB中创建了数据,那么每次重新启动容器的时候,先前数据都会丢失。在需要保持数据的时候,就需要使用Docker Volume。

Docker Volume介绍

Docker Volume的工作原理就是把host的一个目录挂载到容器中的虚拟目录中,这样即使容器重新启动或者被删除了,数据还在,进而实现了容器内数据的持久化。

比如,在运行docker run的时候:

bash
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data mysql

从本质上将,使用数据卷就是在容器内使用mount挂载主机的某个目录。数据全部保存在host的目录下,自然就不会受容器生命周期的影响了。

这里可以同时挂载多个不同的路径。

可能出现的问题及解决方法

如果出现如下错误提示:

bash
cannot open directory .: Permission denied

其原因在于,挂载容器卷的行为在有些Linux版本中被系统认为是不安全的行为,因此,系统的root权限受到限制。

解决方法很简单,添加一个–privileged=true参数就可以给root真正的管理员权限:

bash
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data --privileged=true mysql

读写权限

rw

默认情况下,容器内的目录是可以读写的,也就是说,默认的命令其实是:

bash
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data:rw --privileged=true mysql

只读

bash
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data:ro --privileged=true mysql

如果通过上面方式的话,在容器内只能读,不能写。

三种Volume类型

方式一:同时指定host目录和容器中目录

bash
docker run -v /home/lcoding/mysql-data:/var/lib/mysql/data mysql

方式二:只指定容器中目录(Anonymous Volumes)

在这种方式中,docker会自动管理host中对应的目录,它会在/var/lib/docker/volumes中创建一个临时目录(Anonymous Volumes),并挂载到容器中的虚拟目录。

bash
docker run -v /var/lib/mysql/data mysql

方式三:指定host中目录名及容器中目录(Named Volumes)

这是第二种方式的改进,这样就可以通过名字来引用volume。同时,这也是在production环境中推荐的方式

bash
docker run -v mysql-folder:/var/lib/mysql/data mysql

容器卷的继承

可以使用volumes-from 父容器名参数来实现容器卷的继承。

比如:

bash
docker run -it --volumes-from redis1 --name redis2 redis /bin/bash

通过这种方式,就实现了多个容器间及主机的数据共享

在docker-compose.yml中使用volume

其使用方式和docker命令行类似:

yaml
services:
  mongodb:
    image: mongo
    ports:
      - 27017:27017
    volumes:
      - mongo-data:/data/db
volumes:
  mongo-data      

通过上面这种方式,可以把host的同一个目录映射到不同容器中的不同虚拟目录,从而实现在不同容器中共享数据的目的

常见几种数据库的数据存储路径:

  • MongoDB: /data/db
  • MySQL: /var/lib/mysql
  • postgres: /var/lib/postgresql/data

Docker存储volume的路径:

  • Windows: C:\ProgramData\docker\volumes
  • Linux/Mac: /var/lib/docker/volumes (注意:在Mac中看不到这个目录,原因在于Docker for Mac会创建一个Linux VM,并把Docker对应的文件存储到这个VM中),这时可以输入以下命令进入Linux VM:~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

一个完整的例子

yaml
version: '3'
services:
  lcoding-demo:
    image: xxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/lcoding-demo:1.0
    ports:
      - 3000:3000
  mongodb:
    image: mongo
    ports:
      - 27017:27017
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=12345
    volumes:
      - mongo-data:/data/db  
  mongo-express:
    image: mongo-express
    ports:
      - 8081:8081
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
      - ME_CONFIG_MONGODB_ADMINPASSWORD=12345
      - ME_CONFIG_MONGODB_SERVER=mongodb
volumes:
  mongo-data:
    driver: local      

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !