docker数据卷的管理
文章目录说明主机默认生成存储目录说明查看容器默认生成的存储ID主机上查看默认路径创建测试主机指定存储目录特别说明【重要】说明创建测试创建数据卷并挂载到容器创建一个数据卷查看数据卷的默认路径创建容器时指定数据卷指定主机目录的特别使用场景mysql数据备份特别说明说明关于容器数据卷,这做一下简单说明容器层是数据是临时的,当我们删除了容器的话,对应的容器层数据是会被一起删除掉。所以这样的默认机制是不安全
文章目录
说明
-
关于容器数据卷,这做一下简单说明
容器层是数据是临时的,当我们删除了容器的话,对应的容器层数据是会被一起删除掉。
所以这样的默认机制是不安全的,比如某个容器运行了一段时间,里面已经挺多数据了,但不小心将容器删除了,那么里面的数据也会被跟着删除。 所以我们需要将容器的数据同步到主机上,这样的容器数据才是安全的。【下面 会说步骤的】 -
数据同步到主机上就是在创建的时候加一个参数:
-v file
然后容器存储在file里面的文件就会被保留在主机上了==【注,仅仅是-v 后面的file文件中的数据会被同步到主机上,其他数据随着容器被删除而消失】==,保留到主机上的目录有2种方式,一种是默认生成的目录,一种是自定义目录,见下面。
主机默认生成存储目录
说明
- 当我们创建容器的时候 -v 指定一个容器中的目录后,同时在本地会响应的生成一个随机ID的文件用来临时存储这个文件。
- 注,容器存储id不是固定的,即使使用同样的参数创建容器,每次创建容器都会生成不同的存储ID。
- 创建参数说明:
-v file
【这个file是容器中的存储文件夹,是文件夹!】
查看容器默认生成的存储ID
- 命令:
docker inspect NAMES |egrep -B 1 volume
【docker ps查看names】
如:下面中Name后面跟的就是默认生成的存储id了
[root@ccx volumes]# docker inspect d1 | egrep -B 1 volume
{
"Type": "volume",
"Name": "da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d",
"Source": "/var/lib/docker/volumes/da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d/_data",
[root@ccx volumes]#
主机上查看默认路径
- 需要先知道上面查询到的某容器生成的存储id
- 主机默认存储路径:
/var/lib/docker/volumes/ID/_data/
【ID就是上面查询到的ID】 - 其实这个
/var/lib/docker/volumes/
路径中的id内容是可以通过命令查看的
命令是:docker volume list
这里面显示的内容和上面路径中的内容一样
[root@ccx ~]# cd /var/lib/docker/volumes/
[root@ccx volumes]# ls
1a357f1b653a6425db41e623941831617ef8cc8d6346141bf54456da6c9e7e0a
3e3709b327a2221a40db1da5632c4323e493fa4cfed9d1619a0aab4434340520
7d514798b27d6d29e626592e51d5c31c68f1b3332a4e6a4fac3dd8f6e5af8a10
854e6f5d053ebe6b759baf488a9a2656d2528954b58b4b295e292ad20853227c
bfd01afaff30e2040931a49fa46b7b118448e92f52bae935162dcff9fe973a7c
da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d
metadata.db
[root@ccx volumes]# docker volume list
DRIVER VOLUME NAME
local 1a357f1b653a6425db41e623941831617ef8cc8d6346141bf54456da6c9e7e0a
local 3e3709b327a2221a40db1da5632c4323e493fa4cfed9d1619a0aab4434340520
local 7d514798b27d6d29e626592e51d5c31c68f1b3332a4e6a4fac3dd8f6e5af8a10
local 854e6f5d053ebe6b759baf488a9a2656d2528954b58b4b295e292ad20853227c
local bfd01afaff30e2040931a49fa46b7b118448e92f52bae935162dcff9fe973a7c
local da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d
[root@ccx volumes]#
创建测试
- 如:我现在新建一个容器的时候,指定一个容器中存储目录
/ccx
,在里面随便写几个文件测试
[root@ccx ~]# docker run -dit --restart=always --name=d1 -v /ccx hub.c.163.com/library/centos
cf0548fc5a3e0808c70f0c41b2e9360f8bb8a034749f622320901ce639a5fc65
[root@ccx ~]# docker attach d1
[root@cf0548fc5a3e /]# touch /ccx/111.txt
[root@cf0548fc5a3e /]# touch /ccx/222.txt
[root@cf0548fc5a3e /]# ls /ccx
111.txt 222.txt
[root@cf0548fc5a3e /]#
- 然后我们到主机看下默认的存储文件
可以看到在容器中创建的文件这儿已经能看到了
[root@ccx _data]# pwd
/var/lib/docker/volumes/da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d/_data
[root@ccx _data]# ls
111.txt 222.txt
[root@ccx _data]#
- 当我们删除了容器,这个id里面的文件依然是存在的
[root@ccx _data]# pwd
/var/lib/docker/volumes/da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d/_data
[root@ccx _data]# ls
111.txt 222.txt
[root@ccx _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf0548fc5a3e hub.c.163.com/library/centos "/bin/bash" 10 minutes ago Up 11 seconds d1
[root@ccx _data]# docker rm d1 -f
d1
[root@ccx _data]# pwd
/var/lib/docker/volumes/da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d/_data
[root@ccx _data]# ls
111.txt 222.txt
[root@ccx _data]#
主机指定存储目录
特别说明【重要】
- 服务器的selinux一定要修改配置文件,改为disabled模式并重启服务器。
如果不修改的话,会出现下面两种问题。 如果不想关闭selinux,可以使用下面创建数据卷的方式,那个对selinux没有限制。
[root@ccx ~]# cat /etc/selinux/config |grep SELINUX=
# SELINUX= can take one of these three values:
SELINUX=disabled
[root@ccx ~]#
-
如果selinux没有设置为disabled模式,可能会出现下面2种问题:
-
1、创建容器以后,在容器中写入文件权限错误
[root@ccx ~]# docker run -it --name=d1 --rm -v /date:/ccx:rw hub.c.163.com/library/centos
[root@fdd812c31dc8 /]# touch /ccx/1
touch: cannot touch '/ccx/1': Permission denied
[root@fdd812c31dc8 /]#
- 2、如果事先在主机目录上创建一个文件夹并写入文件,那么创建容器后会出现查看目录报 权限错误
[root@ccx ~]# mkdir /date
[root@ccx ~]# touch /date/hero.txt
[root@ccx ~]# touch /date/superhero.txt
[root@ccx ~]# docker run -it --restart=always --name=c1 -v /date:/ccx hub.c.163.com/library/centos
[root@f7c89ba1174f /]# cd /ccx
[root@f7c89ba1174f ccx]# ls
ls: cannot open directory .: Permission denied
[root@f7c89ba1174f ccx]# ls
ls: cannot open directory .: Permission denied
[root@f7c89ba1174f ccx]# exit
exit
说明
- 就是创建容器的时候指定一个主机目录用来存储容器中的文件目录
- 创建参数说明:
-v 主机文件:容器文件:rw
【权限默认是rw,可以不写,但如果想指定为ro,就需要加上去了】【这个文件是容文件夹,是文件夹!】 - 这种指定就相当于mount挂载【下面展示的信息是我已经创建好容器的内容】
可以查看的,d1是容器的NAMES
[root@ccx ~]# docker inspect d1 | egrep -A 4 Mounts
"Mounts": [
{
"Type": "bind",
"Source": "/date",
"Destination": "/ccx",
[root@ccx ~]#
创建测试
- 如:我现在新建一个容器的时候,指定一个容器中存储目录
/ccx
并让其存储在本地的/date
目录中】,在里面随便写几个文件测试- 我先在主机上创建一个/date并随便写入几个文件【这个文件可以不用手动创建,创建容器的时候会自动创建
- 然后我去容器中查看目录,能看到我在主机上创建的文件
- 然后我再容器中创建几个文件,可以在主机上的这个目录看到这些文件
[root@ccx ~]# mkdir /date
[root@ccx ~]# touch /date/hero.txt /date/superhero.txt
[root@ccx ~]# docker run -it --restart=always --name=d1 -v /date:/ccx:rw hub.c.163.com/library/centos
[root@305175003c1d /]# cd /ccx
[root@305175003c1d ccx]# ls
hero.txt superhero.txt
[root@305175003c1d ccx]# touch test.txt
[root@305175003c1d ccx]# exit
exit
[root@ccx ~]# cd /date
[root@ccx date]# ls
hero.txt superhero.txt test.txt
[root@ccx date]#
创建数据卷并挂载到容器
这种和指定存储目录比起来,可能会更专业点吧。
创建一个数据卷
- 命令:
docker volume create 自定义卷名称
- 查看卷:
docker volume list
- 如下:我创建了一个v1的数据卷
[root@ccx ~]# docker volume create v1
v1
[root@ccx ~]#
[root@ccx ~]# docker volume list | tail -n 2
local da83526212497c34ed7eddcb803d192f80dab0812bf20957b961a605faf6dd3d
local v1
[root@ccx ~]#
查看数据卷的默认路径
- 这个默认路径与默认卷处于同一目录,只是这个v1不会改变,原理其实和我们指定存储目录一样,只是路径变了而已。
- 如下v1卷的默认路径为:Mountpoint项
[root@ccx ~]# docker volume inspect v1
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/v1/_data",
"Name": "v1",
"Options": {},
"Scope": "local"
}
]
[root@ccx ~]#
创建容器时指定数据卷
- 这个和主机指定存储目录挂载的方式是一样的,只是主机路径变成之前创建的卷名了而已。
- 如:我讲主机的v1卷挂在到容器中的/ccx目录,并在里面创建一个文件,然后回到主机上查看这个卷的内容,发现同步的。
[root@ccx ~]# docker run -it --restart=always --name=d1 -v v1:/ccx hub.c.163.com/library/centos
[root@2c7ff6e87a94 /]# touch /ccx/hero.txt
[root@2c7ff6e87a94 /]# exit
exit
[root@ccx ~]# ls /var/lib/docker/volumes/v1/_data/
hero.txt
[root@ccx ~]#
指定主机目录的特别使用场景
-
上面中:主机指定存储目录和创建数据卷并挂载到容器方法均一样
-
容器之间数据同步 【也就这一个使用方式比较特殊罢了】
比如将多个容器的数据目录均使用同一个数据卷,那么容器间看到的数据都是一样的。
- 将数据写入到主机目录后,容器中的这个目录内容会同步变化,这个需要了解一下。
- 数据持久化
mysql数据备份特别说明
流程
-
因为mysql的默认存放路径为:
/var/lib/mysql
所以我们只需要在创建的时候将数据卷同步到上面路径上,即可实现mysql的数据自动同步了 -
如,我创建mysql容器的时候将本地的
/date
【建议手动mkdir创建好该文件】同步到容器中的/var/lib/mysql
目录,这样创建的时候数据就会自动同步到本地的/date目录中了
注:本地的目录中必须是空的,如果有内容先执行:rm -rf /date1/*
[root@ccx date]# rm -rf /date/*
[root@ccx date]# docker run -dit --restart=always --name=db -e MYSQL_ROOT_PASSWORD=passwd -v /date:/var/lib/mysql/:rw hub.c.163.com/library/mysql
8d27c14f23c60e7cee5a34ac135f3c1e09fbfca31e378d632b9fb383953f705a
[root@ccx date]# ls
auto.cnf ibdata1 ib_logfile1 mysql sys
ib_buffer_pool ib_logfile0 ibtmp1 performance_schema
[root@ccx date]#
- 后续登陆这个容器的方法和测试见下面
先在客户端上装 mysql,查看容器的ip,然后就可以登陆了
如果密码是p开头,那么是不能直接-p后面跟密码的,如我密码是passwd,如果我用-ppasswd登陆就会报错,必须-p然后手动输入密码才行。
我下面就是登陆进容器以后,创建了一个aa表再里面写如数据后退出并查看本地文件,确实aa表有出现了。
[root@ccx date]# docker inspect db | grep ipaddress -i
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
[root@ccx date]# cd
[root@ccx ~]# mysql -uroot -ppasswd -h 127.17.0.3
ERROR 2003 (HY000): Can't connect to MySQL server on '127.17.0.3' (111)
[root@ccx ~]# mysql -uroot -h 172.17.0.3
ERROR 1045 (28000): Access denied for user 'root'@'172.17.0.1' (using password: NO)
[root@ccx ~]# mysql -uroot -h 172.17.0.3 -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.18 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show datebash;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'datebash' at line 1
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
MySQL [(none)]> create database aa;
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> use aa;
Database changed
MySQL [aa]> create table aa(id int,name varchar(10));
Query OK, 0 rows affected (0.01 sec)
MySQL [aa]> insert into aa values (1,'ccx');
Query OK, 1 row affected (0.01 sec)
MySQL [aa]> show tables;
+--------------+
| Tables_in_aa |
+--------------+
| aa |
+--------------+
1 row in set (0.00 sec)
MySQL [aa]> select * from aa;
+------+------+
| id | name |
+------+------+
| 1 | ccx |
+------+------+
1 row in set (0.00 sec)
MySQL [aa]> exit
Bye
[root@ccx ~]# cd /date
[root@ccx date]# ls
aa ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
[root@ccx date]#
- 如果要进入mysql容器中查看路径,需要新增一个bash进程,流程如下
我顺便在这进入到容器中的/var/lib/mysql目录中,对比主机的/date目录,可以看到文件内容确实一模一样的。
[root@ccx aa]# docker exec -it db bash
root@8d27c14f23c6:/# cd /var/lib/mysql
root@8d27c14f23c6:/var/lib/mysql# ls
aa ca.pem ib_buffer_pool ibdata1 performance_schema server-cert.pem
auto.cnf client-cert.pem ib_logfile0 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile1 mysql public_key.pem sys
root@8d27c14f23c6:/var/lib/mysql# exit
exit
[root@ccx aa]# cd /date
[root@ccx date]# ls
aa ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
[root@ccx date]#
备份意义及使用
- 通过上面的备份完毕以后,这么做的好处就是,如果不小心误删了该容器,可以新建一个一摸一样的容器出来,这样里面的数据都还在
- 注:必须参数要一模一样,特别是密码,如果变动了以后,就登不上了,报错内容是:
ERROR 1045 (28000): Access denied for user 'root'@'172.17.0.1' (using password: YES)
- 这个数据库是不能共享到其他容器上面的,登陆报错和上面一样
- 注:必须参数要一模一样,特别是密码,如果变动了以后,就登不上了,报错内容是:
- 如,我删掉db这个容器,新建一个一摸一样的,可以看到之前新建的aa库还在。
[root@ccx ~]# docker rm -f db
db
[root@ccx ~]# docker run -dit --restart=always --name=db -e MYSQL_ROOT_PASSWORD=passwd -v /date:/var/lib/mysql/ hub.c.163.com/library/mysql
83817192b3ad981916fbd4a5233f6938ed39fadbe397e808ce6fe9cae2d3ef37
[root@ccx ~]# mysql -uroot -p -h 172.17.0.3
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show datebases;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'datebases' at line 1
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| aa |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
MySQL [(none)]>
更多推荐
所有评论(0)