Docker持久化数据分两大类
- 本地文件系统的 Volume
- Plugin 的 Mount
1. 本地文件系统的 Volume
可以在执行 Docker create 或 Docker run 时,通过 -v 参数将主机的目录作为容器的数据卷。
Volume 的类型:
- 受管理的 data volume,由 docker 后台自动创建
- 绑定挂载的 volume,由用户指定具体挂载位置
1.1. Data Volume
首先我们启动一个 mysql 的 container
启动之前先看下 Dockerfile,会发现当这个 container 创建启动后,会通过 /var/lib/mysql 这个 volume 将数据持久化存储到本机
FROM debian:stretch-slim
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
… …
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT [“docker-entrypoint.sh”]
EXPOSE 3306
CMD [“mysqld”]
然后启动 container
$ docker run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.6
618125ed3c5ab9401d6fd251b212af5ceb8e572e5dcd9073abe403a5e35d484d
我们查看下 volume 以及详细信息
$ docker volume ls
DRIVER VOLUME NAME
local 0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10
$ docker volume inspect 0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10
[
{
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10/_data",
"Name": "0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10",
"Options": {},
"Scope": "local"
}
]
可以发现 volume 0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10 是挂载到本地的 /var/lib/docker/volumes/0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10 目录。
当我们停止该 mysql 容器后,会发现该 volume 还在
$ docker stop mysql
mysql
$ docker volume ls
DRIVER VOLUME NAME
local 0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10
由于默认的volume 名字是container id,太长了不太友好,我们可以给它起个别名
我们把一开始创建的 mysql container 和 volume 删除
$ docker rm mysql
mysql
$ docker volume rm 0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10
0aef14be96dd31340bdf0685810e6e6574b3845625960e1af58cc9cf11159d10
重新创建一个 mysql container
$ docker run -d --name mysql -v mysql:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.6
2000bca9afd56a25cdbbc3a93616072687fc98160ba8364f560b093ed51c5645
$ docker volume ls
DRIVER VOLUME NAME
local mysql
我们进入 container
$ docker exec -it mysql /bin/bash
在 mysql 容器中登录 mysql 并查看有哪些数据库
$ mysql -u root
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
可以看出总共有三个库,我们创建一个名为 docker 数据库
mysql> create database docker;
Query OK, 1 row affected (0.00 sec)
然后退出并销毁这个 container
$ docker rm -f mysql
mysql
这时候 mysql container 已经不存在了,但是 volume 还在
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker volume ls
DRIVER VOLUME NAME
local mysql
我们再次创建一个新的 mysq container
$ docker run -d --name mysql2 -v mysql:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.6
41de5c3d0115c31cb4d7d974c17ed5740d4361af6197337236ccdfc78d2e3531
创建好后,我们进入该 container 并登录 mysql 查看所有数据库
$ docker exec -it 4 /bin/bash
$ mysql -u root
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| docker |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)
会发现名为 docker 的数据库还在,这就说明 data volume 起作用了
1.2 Bind Mouting
只需要在运行的时候指定本地的目录和 container 中的目录一一对应关系
2. 磁盘挂载
支持第三方的存储方案,e.g., NAS, AWS
3. Bind Mouting
参考资料: