为什么要做数据持久化?
当容器运行期间产生的数据是不会在写镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写层来保存数据。如果想做到数据持久化,Docker提供数据卷(Data volume)或者数据容器卷来解决问题,另外还可以通过commit提交一个新的镜像来保存产生的数据。
Docker数据持久化方案:-
基于本机文件系统的Volume。可以执行
Docker create
或Docker run
时,通过-v
参数将主机的目录作为容器的数据卷。这部分功能便是基于本地文件系统的volume管理。 - 基于plugin的Volume,支持第三方的存储方案,比如NAS,AWS。
基于本机文件系统的Volume:
- Data Volume:挂载数据卷
- Bind Mouting: 挂载本地目录
数据持久化之Data Volume:
1.下载mysql镜像
[root@localhost ~]# docker search mysql //搜索mysql镜像
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9468 [OK]
[root@localhost ~]# docker pull mysql //下载mysql镜像
...
bcc6c6145912: Pull complete
951c3d959c9d: Extracting [===============================================> ] 3.998MB/4.178MB
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest a7a67c95e831 10 days ago 541MB
2.启动mysql1容器并查看容器内与容器外的volume对象
-i:以交互模式运行容器,通常与 -t 同时使用
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用
-d:后台运行
--name 容器名: 为容器指定一个名称
-e:操作mysql的内部命令
--MYSQL_ALLOW_EMPTY_PASSWORD=true:代表密码设置为空
[root@localhost ~]# docker run -itd --name mysql1 -e MYSQL_ROOT_PASSWORD=123 mysql:latest
109d0290ccbfe0d6d335b0e9842c770f21123b3ba42587bb8b389765c2be063c
//指定容器名称为mysql1,-e设置mysql1容器数据库密码为123
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 8931d175e3b22ea7d963d76b1ea2ee9347b546ddfb86ab17940fac44466acd03
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
109d0290ccbf mysql:latest "docker-entrypoint.s…" 19 minutes ago Up 19 minutes 3306/tcp, 33060/tcp mysql1
可以看到如果不指定-v参数就直接启动mysql1容器,那么默认产生的volume对象就是一串ID。
3.删除mysql1容器,查看volume对象是否被删除
[root@localhost ~]# docker stop mysql1
mysql1
[root@localhost ~]# docker rm mysql1
mysql1
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 8931d175e3b22ea7d963d76b1ea2ee9347b546ddfb86ab17940fac44466acd03
可以看到在删除mysql1容器后,这个volume对象并没有随着容器的删除而丢失。
4.删除之前mysql1容器默认生成的volume对象
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 8931d175e3b22ea7d963d76b1ea2ee9347b546ddfb86ab17940fac44466acd03
[root@localhost ~]# docker volume rm 8931d175e3b22ea7d963d76b1ea2ee9347b546ddfb86ab17940fac44466acd03
8931d175e3b22ea7d963d76b1ea2ee9347b546ddfb86ab17940fac44466acd03
5.启动mysql2容器并指定volume对象名称(挂载目录)
-v:挂载宿主机的一个目录/数据卷(宿主机目录如果不存在,则会自动创建)
用法:-v 宿主机目录/数据卷:容器内目录(容器目录必须为绝对路径)
docker volume管理命令:
docker volume create 数据卷:--> 创建volume
docker inspect 数据卷:--> 查看数据卷信息
docker run -itd -v 数据卷:容器内目录:--> 使用某个数据卷
docker volume ls:--> 列出所有数据卷
docker volume rm 数据卷:--> 删除某个数据卷
[root@localhost ~]# docker run -itd --name mysql2 -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql
1d90619790ecb9ff9bd63524048fef777a39b8cb14652eade5b1551e30bd4964
//数据卷mysql若不存在,则会自己创建
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local mysql
[root@localhost ~]# docker volume inspect mysql
[
{
"CreatedAt": "2020-05-09T03:01:17+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql/_data",
"Name": "mysql",
"Options": null,
"Scope": "local"
}
]
因为我们挂载时没有指定mysql目录绝对路径,用volume inspect
可以查看volume挂载的信息,若挂载宿主机目录时不使用绝对路径,则默认挂载在/var/lib/docker/volumes/目录下,也可以指定路径(如:-v /mnt/mysql:/var/lib/mysql)
验证Data Volume持久化:
1.进入mysql2容器创建test库并删除容器mysql2
[root@localhost ~]# docker exec -it mysql2 /bin/bash
root@1d90619790ec:/# mysql -uroot -p123
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.68 sec)
mysql> create database test; //创建test库
Query OK, 1 row affected (0.24 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d90619790ec mysql "docker-entrypoint.s…" 3 hours ago Up 3 hours 3306/tcp, 33060/tcp mysql2
[root@localhost ~]# docker rm -f mysql2 //强制删除mysql2容器
mysql2
2.新启动mysql3容器,并使用-v参数挂载之前的mysql数据卷
[root@localhost ~]# docker run -itd --name mysql3 -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql
96a5f81cd671f57cb52df89ae5ae130207aec454f4f55d4746b00a8655ed5113
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96a5f81cd671 mysql "docker-entrypoint.s…" 27 seconds ago Up 16 seconds 3306/tcp, 33060/tcp mysql3
[root@localhost ~]# docker exec -it mysql3 /bin/bash
3.进入mysql3容器,查看mysql数据卷中的数据是否还在
[root@localhost ~]# docker exec -it mysql3 /bin/bash
root@96a5f81cd671:/# mysql -uroot -p123
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test | ---》test库依然存在
+--------------------+
5 rows in set (0.01 sec)
Data Volume 数据共享:
数据卷可以被挂载到多个容器中,这时候数据卷中的数据被共享。
如果要共享数据卷,需要使用--volumes-from
参数。
1.进入mysql3容器,查看mysql数据卷数据
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
96a5f81cd671 mysql "docker-entrypoint.s…" 2 days ago Up 7 seconds 3306/tcp, 33060/tcp mysql3
[root@localhost ~]# docker exec -it mysql3 /bin/bash
root@96a5f81cd671:/# mysql -uroot -p123
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test | -----》之前创建的test库
+--------------------+
5 rows in set (0.01 sec)
2.新启动mysql4容器,共享mysql数据卷
注意:
在启动mysql4容器之前,需要先停止mysql3数据库容器,经测试不能同时开启做数据共享(使用同一个数据卷)的两个mysql容器。
[root@localhost ~]# docker stop mysql3 //停止mysql3容器
mysql3
[root@localhost ~]# docker run -itd --name mysql4 --volumes-from mysql3 -e MYSQL_ROOT_PASSWORD=123 mysql
7632976b82d40de79ed0c165d0f7d0757fd4e1088fb638ed405c0a67c9656cf1
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7632976b82d4 mysql "docker-entrypoint.s…" 38 seconds ago Up 37 seconds 3306/tcp, 33060/tcp mysql4
3.进入mysql4容器,查看数据库中共享数据卷mysql后的数据
[root@localhost ~]# docker exec -it mysql4 /bin/bash
root@7632976b82d4:/# mysql -uroot -p123
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test | ---》可以看到mysql数据卷中的数据的确存在
+--------------------+
5 rows in set (0.01 sec)
↓↓↓↓↓↓
最近刚申请了个微信公众号,上面也会分享一些运维知识,大家点点发财手关注一波,感谢大家。 【原创公众号】:非著名运维 【福利】:公众号回复 “资料” 送运维自学资料大礼包哦!