文章目录
官网
https://docs.docker.com/storage/
概述
1.数据持久化章节,我们以mysql的数据存储为例去了解;
2.所谓docker数据持久化,主要是镜像容器数据内容的持久化;
3.比如我们的mysql容器,无意间被删除了,再次启动容器之后,可能涉及到历史数据的恢复问题;
因此我们怎么样把数据能够保存下来,再次启动的时候,能够恢复历史的数据,即是我们需要考虑的技术点;
初探Mysql镜像容器的数据存储
镜像准备:拉取mysql镜像 docker pull mysql
[root@localhost vagrant]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
d599a449871e: Already exists
f287049d3170: Already exists
08947732a1b0: Already exists
96f3056887f2: Already exists
871f7f65f017: Already exists
1dd50c4b99cb: Already exists
5bcbdf508448: Already exists
a59dcbc3daa2: Pull complete
13e6809ab808: Pull complete
2148d51b084d: Pull complete
93982f7293d7: Pull complete
e736330a6d9c: Pull complete
Digest: sha256:c93ba1bafd65888947f5cd8bd45deb7b996885ec2a16c574c530c389335e9169
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
[root@localhost vagrant]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest d435eee2caa5 2 weeks ago 456MB
[root@localhost vagrant]#
启动Mysql镜像
[root@localhost vagrant]# docker run -d --name mysql01 -e MYSQL_ROOT_PASSWORD=root mysql
e256da6e433dbaf90c05d1cdc91b7c8da0db8ee3f5486c394df6292fe5f3f1d4
[root@iZwz91h49n3mj8r232gqweZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2db4015bcc59 mysql "docker-entrypoint.s…" 46 seconds ago Up 34 seconds 3306/tcp, 33060/tcp aliyun-mysql-01
[root@iZwz91h49n3mj8r232gqweZ ~]#
登录Mysql镜像容器
[root@localhost vagrant]# docker exec -it mysql01 bash
root@e256da6e433d:/#
登录mysql
root@e256da6e433d:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
容器数据存储路径查看 VOLUME /var/lib/mysql
查看官方源码地址的Dockfile文件
https://github.com/docker-library/mysql/blob/master/5.7/Dockerfile
1.上面的这个VOLUME /var/lib/mysql,是指我们容器mysql中的数据会存储到容器中的/var/lib/mysql下
进入容器查看
[root@localhost vagrant]# docker exec -it mysql01 bash
root@e256da6e433d:/# cd /var/lib/mysql
root@e256da6e433d:/var/lib/mysql# ls -la
total 178188
drwxr-x---. 2 mysql mysql 187 Dec 9 23:38 #innodb_temp
drwxr-xr-x. 6 mysql mysql 4096 Dec 9 23:38 .
drwxr-xr-x. 1 root root 55 Nov 23 01:49 ..
-rw-r-----. 1 mysql mysql 56 Dec 9 23:37 auto.cnf
-rw-r-----. 1 mysql mysql 3084516 Dec 9 23:38 binlog.000001
-rw-r-----. 1 mysql mysql 155 Dec 9 23:38 binlog.000002
-rw-r-----. 1 mysql mysql 32 Dec 9 23:38 binlog.index
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 ca-key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 ca.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 client-cert.pem
-rw-------. 1 mysql mysql 1680 Dec 9 23:37 client-key.pem
-rw-r-----. 1 mysql mysql 5433 Dec 9 23:38 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:38 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:37 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibdata1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibtmp1
drwxr-x---. 2 mysql mysql 143 Dec 9 23:37 mysql
-rw-r-----. 1 mysql mysql 30408704 Dec 9 23:38 mysql.ibd
drwxr-x---. 2 mysql mysql 8192 Dec 9 23:37 performance_schema
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 private_key.pem
-rw-r--r--. 1 mysql mysql 452 Dec 9 23:37 public_key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 server-cert.pem
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 server-key.pem
drwxr-x---. 2 mysql mysql 28 Dec 9 23:37 sys
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 undo_001
-rw-r-----. 1 mysql mysql 10485760 Dec 9 23:38 undo_002
root@e256da6e433d:/var/lib/mysql#
宿主机数据路径查看
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
[root@localhost vagrant]#
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
[root@localhost vagrant]# docker volume inspect 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
[
{
"CreatedAt": "2019-12-09T23:38:11Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data",
"Name": "3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c",
"Options": null,
"Scope": "local"
}
]
1.因为只创建了一个容器mysql01,然后myslq01的Dockerfile中有设置volume这个属性,因为我们姑且认为docker
volume ls 查出的3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c 即是我们刚
创建的;
后面我们还会具体如何自定义命名volume_name;
2.通过上面的inspect查看,我们可以发现,mysql01的数据存储在宿主机的路径为:
/var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data
我们现在进去查看一下,是不是跟容器中是一致的;
[root@localhost vagrant]# cd /var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data
[root@localhost _data]# ls -la
total 178188
drwxr-x---. 2 polkitd input 187 Dec 9 23:38 #innodb_temp
drwxr-xr-x. 6 polkitd input 4096 Dec 9 23:38 .
drwxr-xr-x. 3 root root 19 Dec 9 23:37 ..
-rw-r-----. 1 polkitd input 56 Dec 9 23:37 auto.cnf
-rw-r-----. 1 polkitd input 3084516 Dec 9 23:38 binlog.000001
-rw-r-----. 1 polkitd input 155 Dec 9 23:38 binlog.000002
-rw-r-----. 1 polkitd input 32 Dec 9 23:38 binlog.index
-rw-------. 1 polkitd input 1676 Dec 9 23:37 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 ca.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 client-cert.pem
-rw-------. 1 polkitd input 1680 Dec 9 23:37 client-key.pem
-rw-r-----. 1 polkitd input 5433 Dec 9 23:38 ib_buffer_pool
-rw-r-----. 1 polkitd input 50331648 Dec 9 23:38 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 Dec 9 23:37 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 ibdata1
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 ibtmp1
drwxr-x---. 2 polkitd input 143 Dec 9 23:37 mysql
-rw-r-----. 1 polkitd input 30408704 Dec 9 23:38 mysql.ibd
drwxr-x---. 2 polkitd input 8192 Dec 9 23:37 performance_schema
-rw-------. 1 polkitd input 1676 Dec 9 23:37 private_key.pem
-rw-r--r--. 1 polkitd input 452 Dec 9 23:37 public_key.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 server-cert.pem
-rw-------. 1 polkitd input 1676 Dec 9 23:37 server-key.pem
drwxr-x---. 2 polkitd input 28 Dec 9 23:37 sys
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 undo_001
-rw-r-----. 1 polkitd input 10485760 Dec 9 23:38 undo_002
[root@localhost _data]#
1.很明显,上面的显示跟mysql01容器中列表是一致的;
容器数据与宿主机数据同步验证
为了进一步验证宿主机和容器中的列表数据是保持一致的,我们现在在容器中创建一个文件,看一下宿主机目录中是不是也创建成功了
登录容器中在/var/lib/mysql/目录下中创建test.txt文件
[root@localhost _data]# docker exec -it mysql01 bash
root@e256da6e433d:/# cd /var/lib/mysql/
root@e256da6e433d:/var/lib/mysql# ls -la
total 178188
drwxr-x---. 2 mysql mysql 187 Dec 9 23:38 #innodb_temp
drwxr-xr-x. 6 mysql mysql 4096 Dec 9 23:38 .
drwxr-xr-x. 1 root root 55 Nov 23 01:49 ..
-rw-r-----. 1 mysql mysql 56 Dec 9 23:37 auto.cnf
-rw-r-----. 1 mysql mysql 3084516 Dec 9 23:38 binlog.000001
-rw-r-----. 1 mysql mysql 155 Dec 9 23:38 binlog.000002
-rw-r-----. 1 mysql mysql 32 Dec 9 23:38 binlog.index
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 ca-key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 ca.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 client-cert.pem
-rw-------. 1 mysql mysql 1680 Dec 9 23:37 client-key.pem
-rw-r-----. 1 mysql mysql 5433 Dec 9 23:38 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:38 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:37 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibdata1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibtmp1
drwxr-x---. 2 mysql mysql 143 Dec 9 23:37 mysql
-rw-r-----. 1 mysql mysql 30408704 Dec 9 23:38 mysql.ibd
drwxr-x---. 2 mysql mysql 8192 Dec 9 23:37 performance_schema
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 private_key.pem
-rw-r--r--. 1 mysql mysql 452 Dec 9 23:37 public_key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 server-cert.pem
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 server-key.pem
drwxr-x---. 2 mysql mysql 28 Dec 9 23:37 sys
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 undo_001
-rw-r-----. 1 mysql mysql 10485760 Dec 9 23:38 undo_002
root@e256da6e433d:/var/lib/mysql# touch test.txt
root@e256da6e433d:/var/lib/mysql# ls -la
total 178188
drwxr-x---. 2 mysql mysql 187 Dec 9 23:38 #innodb_temp
drwxr-xr-x. 6 mysql mysql 4096 Dec 10 00:02 .
drwxr-xr-x. 1 root root 55 Nov 23 01:49 ..
-rw-r-----. 1 mysql mysql 56 Dec 9 23:37 auto.cnf
-rw-r-----. 1 mysql mysql 3084516 Dec 9 23:38 binlog.000001
-rw-r-----. 1 mysql mysql 155 Dec 9 23:38 binlog.000002
-rw-r-----. 1 mysql mysql 32 Dec 9 23:38 binlog.index
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 ca-key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 ca.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 client-cert.pem
-rw-------. 1 mysql mysql 1680 Dec 9 23:37 client-key.pem
-rw-r-----. 1 mysql mysql 5433 Dec 9 23:38 ib_buffer_pool
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:38 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 Dec 9 23:37 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibdata1
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 ibtmp1
drwxr-x---. 2 mysql mysql 143 Dec 9 23:37 mysql
-rw-r-----. 1 mysql mysql 30408704 Dec 9 23:38 mysql.ibd
drwxr-x---. 2 mysql mysql 8192 Dec 9 23:37 performance_schema
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 private_key.pem
-rw-r--r--. 1 mysql mysql 452 Dec 9 23:37 public_key.pem
-rw-r--r--. 1 mysql mysql 1112 Dec 9 23:37 server-cert.pem
-rw-------. 1 mysql mysql 1676 Dec 9 23:37 server-key.pem
drwxr-x---. 2 mysql mysql 28 Dec 9 23:37 sys
-rw-r--r--. 1 root root 0 Dec 10 00:02 test.txt
-rw-r-----. 1 mysql mysql 12582912 Dec 9 23:38 undo_001
-rw-r-----. 1 mysql mysql 10485760 Dec 9 23:38 undo_002
退出容器,查看宿主目录下是否多出test.txt文件
root@e256da6e433d:/var/lib/mysql# exit
exit
[root@localhost _data]# pwd
/var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data
[root@localhost _data]# ls -la
total 178188
drwxr-x---. 2 polkitd input 187 Dec 9 23:38 #innodb_temp
drwxr-xr-x. 6 polkitd input 4096 Dec 10 00:02 .
drwxr-xr-x. 3 root root 19 Dec 9 23:37 ..
-rw-r-----. 1 polkitd input 56 Dec 9 23:37 auto.cnf
-rw-r-----. 1 polkitd input 3084516 Dec 9 23:38 binlog.000001
-rw-r-----. 1 polkitd input 155 Dec 9 23:38 binlog.000002
-rw-r-----. 1 polkitd input 32 Dec 9 23:38 binlog.index
-rw-------. 1 polkitd input 1676 Dec 9 23:37 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 ca.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 client-cert.pem
-rw-------. 1 polkitd input 1680 Dec 9 23:37 client-key.pem
-rw-r-----. 1 polkitd input 5433 Dec 9 23:38 ib_buffer_pool
-rw-r-----. 1 polkitd input 50331648 Dec 9 23:38 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 Dec 9 23:37 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 ibdata1
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 ibtmp1
drwxr-x---. 2 polkitd input 143 Dec 9 23:37 mysql
-rw-r-----. 1 polkitd input 30408704 Dec 9 23:38 mysql.ibd
drwxr-x---. 2 polkitd input 8192 Dec 9 23:37 performance_schema
-rw-------. 1 polkitd input 1676 Dec 9 23:37 private_key.pem
-rw-r--r--. 1 polkitd input 452 Dec 9 23:37 public_key.pem
-rw-r--r--. 1 polkitd input 1112 Dec 9 23:37 server-cert.pem
-rw-------. 1 polkitd input 1676 Dec 9 23:37 server-key.pem
drwxr-x---. 2 polkitd input 28 Dec 9 23:37 sys
-rw-r--r--. 1 root root 0 Dec 10 00:02 test.txt
-rw-r-----. 1 polkitd input 12582912 Dec 9 23:38 undo_001
-rw-r-----. 1 polkitd input 10485760 Dec 9 23:38 undo_002
[root@localhost _data]#
1.很明显,已经娱乐test.txt文件
结论总结
1.容器中的目录,我们可以认为是临时目录
宿主机中的目录,才是永久的一个目录;
深入Mysql镜像容器的数据存储 bind mounts
[root@localhost vagrant]# docker run -d --name mysql02 -e MYSQL_ROOT_PASSWORD=root mysql
ff4c0c015850bcaf5ee2c5075acb80b17a093d3637b4f3b69024722b42f660b4
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
[root@localhost vagrant]#
[root@localhost vagrant]# docker volume inspect 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
[
{
"CreatedAt": "2019-12-09T23:38:11Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data",
"Name": "3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c",
"Options": null,
"Scope": "local"
}
]
[root@localhost vagrant]#
[root@localhost vagrant]# docker volume inspect 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
[
{
"CreatedAt": "2019-12-10T05:03:45Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00/_data",
"Name": "8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00",
"Options": null,
"Scope": "local"
}
]
[root@localhost vagrant]#
1.根据上面我们在启动的时候,没有指定任何的volume的任何信息,所以根据Dockerfile文件中,如果有VOLUME步骤,
那么他会随机创建一个volume_name
如:3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
这个名字对于我们来说,可能不太好识别,不方便记忆,因此,如果我们能够指定volume_name,对于后续的操作
是比较方便的;
2.对于不同的volume,宿主机的数据存储路径如下:
/var/lib/docker/volumes/3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c/_data
/var/lib/docker/volumes/8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00/_data
3.关于指定volume_name,见下面的章节操作;
指定volume_name:-v {volume_name}:{存储镜像的路径}
[root@localhost vagrant]# docker run -d --name mysql03 -v mysql03_volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql
cd66bcd252a72dc5367cb7465f67b659d6b8f8bb2cfc985c62a9a30d3ec2cadb
[root@localhost vagrant]#
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
local mysql03_volume
[root@localhost vagrant]#
[root@localhost vagrant]# docker volume inspect mysql03_volume
[
{
"CreatedAt": "2019-12-10T06:03:07Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql03_volume/_data",
"Name": "mysql03_volume",
"Options": null,
"Scope": "local"
}
]
[root@localhost vagrant]#
备注
1.再次查看发现mysql03容器中的volume已经显示为我们自定义的mysql03_volume,可读性变高
2.并且,在我们的宿主机上显示的存储路径也变为:
/var/lib/docker/volumes/mysql03_volume/_data
删除镜像之后volume的变化
[root@localhost vagrant]# docker rm -f mysql03
mysql03
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
local mysql03_volume
[root@localhost vagrant]# docker volume inspect mysql03_volume
[
{
"CreatedAt": "2019-12-10T06:03:07Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql03_volume/_data",
"Name": "mysql03_volume",
"Options": null,
"Scope": "local"
}
]
[root@localhost vagrant]#
备注
1.从上面,我们可以发现,在删除了mysql03容器之后,我们发现volume:mysql03_volume实际上还是存在的
2.volume是不会随着容器的消失而消失;
3.当然,我们可以通过手动的命令去删除某个volume,见下面
删除volume:docker volume rm -f {volume_name}
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
local mysql03_volume
[root@localhost vagrant]# docker volume rm -f 3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
3d954a87a61fc2328514c1c6f4fe04949f804ebb57a106018adc28f14493be1c
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
local mysql03_volume
[root@localhost vagrant]#
通过volume进行数据的恢复
1.既然,通过上面我们了解到,如果容器消失,volume不会自动消失,那么我们是不是可以根据volume存储的数据,
进行恢复数据呢?答案是肯定可以的;
数据恢复验证案例
指定volume:mysql001 启动容器mysql001
[root@localhost vagrant]# docker run -d --name mysql001 -v mysql001_volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql
795af641a1f7ae46d1a8b5e0c27c403e13cf442a29779d06c670cafbd94348b7
[root@localhost vagrant]#
**查看当前容器mysql001的volume挂在的路径信息a
[root@localhost vagrant]# docker volume ls
DRIVER VOLUME NAME
local 8787fbbc29680d2acebc4d2cbd6608aaf74add977328f90ee1734d7d0fdfee00
local mysql001_volume
local mysql03_volume
[root@localhost vagrant]# docker volume inspect mysql001_volume
[
{
"CreatedAt": "2019-12-10T06:32:37Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql001_volume/_data",
"Name": "mysql001_volume",
"Options": null,
"Scope": "local"
}
]
在当前容器mysql001之中,创建一个数据库demo_test
进入当前的容器mysql001,使用root用户登录myslq,创建demo_test数据库
[root@localhost vagrant]# docker exec -it mysql001 bash
root@795af641a1f7:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.08 sec)
mysql> create database demo_test;
Query OK, 1 row affected (0.05 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| demo_test |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> exit;
Bye
root@795af641a1f7:/# exit;
exit
接下来我们删除容器mysql001
[root@localhost vagrant]# docker rm -f mysql001
mysql001
[root@localhost vagrant]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
创建新的容器recover_mysql001,并使用之前的挂载目录volume:mysql001_volume
[root@localhost vagrant]# docker run -d --name recover_mysql001 -v mysql001_volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql
dc052020b23ca033c0b05770d613b19f057c9169006bf94732d79fd486a0a173
查看最新容器recover_mysql001中是否存在之前创建的数据库demo_test
[root@localhost vagrant]# docker exec -it recover_mysql001 bash
root@dc052020b23c:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| demo_test |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.04 sec)
mysql>
总结
1.很明显,我们使用了相同的volume挂载的目录之后,最新的容器也有了之前容器之中数据库的相关数据;
2.因此,通过制定volume挂载目录,我们可以做到数据的恢复;
指定宿主机的数据存储目录
设置宿主主机目录和容器目录, 启动tomcat02 容器
[root@localhost tmp]# docker run -d --name tomcat02 -v /tmp/demo:/usr/local/tomcat/webapps/demo -p 8080:8080 tomcat
e9eca215b5c8c8438dc341bdb4c87437f42c4d45854ca4ebc3438f62bc1da7ef
[root@localhost tmp]#
[root@localhost tmp]# docker exec -it tomcat02 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
1.-v {宿主主机数据存储目录}:{容器的数据存储目录}
宿主主机数据存储目录:/tmp/demo
容器的数据存储目录:/usr/local/tomcat/webapps/demo
验证tomcat02容器是否启动成功
[root@localhost tmp]# curl http://172.17.0.5:8080
出现下面这种即为已经启动成功;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtAtSH8o-1576317960096)(/Users/gaoxinfu/Library/Application Support/typora-user-images/image-20191210163244415.png)]
通过修改宿主主机数据,同步容器目录数据
1.在我们系统进行升级上线或者紧急修复服务器数据的过程中,我们可以需要紧急升级class文件或者j替换jar
去使得容器能够获取到最新的代码,我们可以通过修改宿主主机目录下的数据,使得自动同步容器中的数据
2.在上面的案例中,tomcat02容器的目录 /usr/local/tomcat/webapps/demo
挂载到了宿主主机目录/tmp/demo下,
这个时候,我们可以通过修改宿主主机中/tmp/demo的文件,
来使得usr/local/tomcat/webapps/demo 同步修改的文件
在宿主主机中新增一个demo.txt文件,文件内容为 “demo”
[root@localhost demo]# vi demo.txt
容器tomcat02中查看demo.txt文件是否已经同步存在
root@e9eca215b5c8:/usr/local/tomcat/webapps/demo# ls -la
total 4
drwxr-xr-x. 2 root root 22 Dec 10 07:20 .
drwxr-xr-x. 1 root root 18 Dec 10 07:11 ..
-rw-r--r--. 1 root root 5 Dec 10 07:19 demo.txt
1.发现在容器中的文件夹 /usr/local/tomcat/webapps/demo 中已经存在demo.txt文件
2.也就是在宿主机里更新之后,容器中对应的目录下也会自动更新;
在宿主机中请求容器demo.txt文件
[root@localhost demo]# curl http://172.17.0.5:8080/demo/demo.txt
demo
[root@localhost demo]#
总结
1.上面这种通过将容器中的数据存储目录映射宿主主机的数据存储目录的方式,我们称之为挂载bind mounts
Mysql高可用集群搭建
业务场景概述
1.在某个商城系统之中,我们使用的数据库为mysql,随着商城订单数据量和请求数量的不断增多,对于对于一台
数据库来讲,压力比较大,这个时候,我们可能就需要创建多个数据库,进行负载请求,同时,各个数据库之间
要实现数据的同步;
2.基于上面的业务场景的需求,我们采用了PXC技术去实现,所谓PXC全称percona-xtradb-cluster;
PXC是基于mysql封装的一个技术,本质上还是一个mysql应用;
当然,基于上面的需求,可能还有其他的一些解决方案,我们暂时不做讨论;
PXC搭建高可用mysql数据库集群数据同步
拉取镜像 percona-xtradb-cluster:
[root@iZwz91h49n3mj8r232gqweZ ~]# docker pull percona/percona-xtradb-cluster:5.7.21
5.7.21: Pulling from percona/percona-xtradb-cluster
10a267c67f42: Already exists
72c96f833dc7: Already exists
9cf61e12536f: Already exists
b488fc069de7: Already exists
b131403bd2f7: Pull complete
c65adfeef478: Pull complete
97bd9399a8f1: Pull complete
7cfcb94b1a52: Pull complete
b5c172b3901c: Pull complete
14ffc8582277: Pull complete
4a4c05674410: Pull complete
1d95eec298b1: Pull complete
6747fd68d00a: Pull complete
Digest: sha256:a8be30a462e7da02558fcf8140de034dc1c0cd6509af6c9196e9862275f9e07e
Status: Image is up to date for percona/percona-xtradb-cluster:5.7.21
docker.io/percona/percona-xtradb-cluster:5.7.21
[root@iZwz91h49n3mj8r232gqweZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
percona/percona-xtradb-cluster 5.7.21 aef0b3032083 2 months ago 827MB
[root@iZwz91h49n3mj8r232gqweZ ~]#
为了方便后续操作,将当前image打个Tag本地版本
[root@iZwz91h49n3mj8r232gqweZ ~]# docker tag percona/percona-xtradb-cluster:5.7.21 pxc
[root@iZwz91h49n3mj8r232gqweZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pxc latest aef0b3032083 2 months ago 827MB
percona/percona-xtradb-cluster 5.7.21 aef0b3032083 2 months ago 827MB
[root@iZwz91h49n3mj8r232gqweZ ~]#
创建网络 docker network create --subnet=172.25.0.0/24 pxc-net
[root@iZwz91h49n3mj8r232gqweZ ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
757b74ac61c7 bridge bridge local
c2cfc0ed2676 customer-network bridge local
d3d1516d3a7c harbor_harbor bridge local
6f425e496441 host host local
d082dd604405 none null local
[root@iZwz91h49n3mj8r232gqweZ ~]# docker network create --subnet=172.25.0.0/24 pxc-net
520b548c9a630905dc9c75b34f35a4fcced4fd1069e0319c88356e974380b756
[root@iZwz91h49n3mj8r232gqweZ ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
757b74ac61c7 bridge bridge local
c2cfc0ed2676 customer-network bridge local
d3d1516d3a7c harbor_harbor bridge local
6f425e496441 host host local
d082dd604405 none null local
520b548c9a63 pxc-net bridge local
[root@iZwz91h49n3mj8r232gqweZ ~]# docker network inspect pxc-net
[
{
"Name": "pxc-net",
"Id": "520b548c9a630905dc9c75b34f35a4fcced4fd1069e0319c88356e974380b756",
"Created": "2019-12-11T08:04:41.273859867+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.25.0.0/24"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
[root@iZwz91h49n3mj8r232gqweZ ~]#
创建volume 挂载目录
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume create pxc-v1
pxc-v1
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume create pxc-v2
pxc-v2
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume create pxc-v3
pxc-v3
[root@iZwz91h49n3mj8r232gqweZ ~]#
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume inspect pxc-v1
[
{
"CreatedAt": "2019-12-11T18:58:04+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/pxc-v1/_data",
"Name": "pxc-v1",
"Options": {},
"Scope": "local"
}
]
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume inspect pxc-v2
[
{
"CreatedAt": "2019-12-11T18:58:10+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/pxc-v2/_data",
"Name": "pxc-v2",
"Options": {},
"Scope": "local"
}
]
[root@iZwz91h49n3mj8r232gqweZ ~]# docker volume inspect pxc-v3
[
{
"CreatedAt": "2019-12-11T18:58:11+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/pxc-v3/_data",
"Name": "pxc-v3",
"Options": {},
"Scope": "local"
}
]
[root@iZwz91h49n3mj8r232gqweZ ~]#
启动pxc容器
pxc-node1容器
[root@iZwz91h49n3mj8r232gqweZ ~]# docker run -d -p 3301:3306 -v pxc-v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=gaoxinfu -e CLUSTER_NAME=pxc-cluster -e XTRABACKUP_PASSWORD=gaoxinfu --privileged --name pxc-node1 --net=pxc-net --ip=172.25.0.2 pxc
cd49429e58a75d611d478a9641c2dd121b35b04c35297109e4f68d7ad76412f1
[root@iZwz91h49n3mj8r232gqweZ ~]#
备注
1.-d 以守护线程运行
-p 端口,3301宿主机的端口,3306容器的端口
-v 数据目录挂载映射
-e MYSQL_ROOT_PASSWORD=gaoxinfu: root 用户的密码gaoxinfu
-e CLUSTER_NAME=pxc-cluster:集群的名字
-e XTRABACKUP_PASSWORD=gaoxinfu 备份数据库密码gaoxinfu
--privileged 设置为最高执行权限
--name 指定容器的名字
--net 指定容器使用的网络
--ip 指定容器的ip
登录查看
[root@iZwz91h49n3mj8r232gqweZ ~]# docker exec -it pxc-node1 bash
root@cd49429e58a7:/# mysql -uroot -pgaoxinfu
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.21-20-57-log Percona XtraDB Cluster (GPL), Release rel20, Revision 1702aea, WSREP version 29.26, wsrep_29.26
Copyright (c) 2009-2018 Percona LLC and/or its affiliates
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases
-> ;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
mysql>
pxc-node2容器
[root@iZwz91h49n3mj8r232gqweZ ~]# docker run -d -p 3302:3306 -v pxc-v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=gaoxinfu -e CLUSTER_NAME=pxc-cluster -e CLUSTER_JOIN=pxc-node1 -e XTRABACKUP_PASSWORD=gaoxinfu --privileged --name pxc-node2 --net=pxc-net --ip=172.25.0.3 pxc
e4eb04ed5f8578eb265653ecfb03a117057a2385bc40f840ae4ddcc6f917cd59
[root@iZwz91h49n3mj8r232gqweZ ~]#
1.-e CLUSTER_JOIN=pxc-node1 :CLUSTER_JOIN 一键式的与pxc-node1节点组成mysql的集群,
实现数据的同步
pxc-node3容器
[root@iZwz91h49n3mj8r232gqweZ ~]# docker run -d -p 3303:3306 -v pxc-v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=gaoxinfu -e CLUSTER_NAME=pxc-cluster -e CLUSTER_JOIN=pxc-node1 -e XTRABACKUP_PASSWORD=gaoxinfu --privileged --name pxc-node3 --net=pxc-net --ip=172.25.0.4 pxc
437abc4dabdb3f9409fe161ae984e298ad046e7b9efb23ca4d7548117de4c31e
[root@iZwz91h49n3mj8r232gqweZ ~]#
通过客户端测试数据是否能够正常连接
1.经过测试,数据库都能够正常连接了;
2.这里注意下,我用的是是阿里云的服务器,所以在端口控制方面,我们是通过阿里的服务器控台去设置开放了
3301 3302 3303端口;
在任意一个节点下操作数据库,查看是否自动同步其他节点
**我们手动在pxc-node1的mysql数据库下创建一个demo-test数据库之后,pxc-node2和pxc-node3下会自动同步demo-test库; **
同样的,我们在pxc-node1 pxc-node2 pxc-node3下做任何操作,其他的两个都会自动的同步操作
Haproxy搭建高可用mysql数据库集群请求负载
概述
1.我们上面PXC的使用,主要是实现的数据同步,但是对于三个节点node的负载均衡的请求,还是不能实现;
2.基于负载均衡的请求,我们使用haproxy去实现;
架构流程
创建Haproxy代理容器
/usr/local/etc/haproxy 创建haproxy.cfg文件
global
#工作目录,这边要和创建容器指定的目录对应
chroot /usr/local/etc/haproxy
#日志文件
log 127.0.0.1 local5 info
#守护进程运行
daemon
defaults
log global
mode http
#日志格式
option httplog
#日志中不记录负载均衡的心跳检测记录
option dontlognull
#连接超时(毫秒)
timeout connect 5000
#客户端超时(毫秒)
timeout client 50000
#服务器超时(毫秒)
timeout server 50000
#监控界面
listen admin_stats
#监控界面的访问的IP和端口
bind 0.0.0.0:8888
#访问协议
mode http
#URI相对地址
stats uri /dbs_monitor
#统计报告格式
stats realm Global\ statistics
#登陆帐户信息
stats auth admin:admin
#数据库负载均衡
listen proxy-mysql
#访问的IP和端口,haproxy开发的端口为3306
#假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例
bind 0.0.0.0:3306
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin
#权重算法:static-rr
#最少连接算法:leastconn
#请求源IP算法:source
balance roundrobin
#日志格式
option tcplog
#在MySQL中创建一个没有权限的haproxy用户,密码为空。
#Haproxy使用这个账户对MySQL数据库心跳检测
option mysql-check user haproxy
server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
#使用keepalive检测死链
option tcpka
[root@izwz91h49n3mj8r232gqwez haproxy]# docker run -it -d -p 8888:8888 -p 3306:3306 -v /tmp/haproxy:/usr/local/etc/haproxy --name haproxy01 --privileged --net=pxc-net haproxy
788825f7ee565f56fb3161717a4c1bf8f7aacf1a9d84b02e808a240c8b2c8021
[root@izwz91h49n3mj8r232gqwez haproxy]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
788825f7ee56 haproxy "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, 0.0.0.0:8888->8888/tcp haproxy01
effa9ca46624 pxc "/entrypoint.sh " About an hour ago Up About an hour 4567-4568/tcp, 0.0.0.0:3303->3306/tcp pxc-node3
389f7bc5a96e pxc "/entrypoint.sh " About an hour ago Up About an hour 4567-4568/tcp, 0.0.0.0:3302->3306/tcp pxc-node2
9c79dc31201a pxc "/entrypoint.sh " About an hour ago Up About an hour 4567-4568/tcp, 0.0.0.0:3301->3306/tcp pxc-node1
备注
1.其中8888:8888 这个是Haproxy配置文件中一个Haproxy监控页面的一个端口
2.3306:3306 这个主要是访问数据的一个同一个端口设置
3.-v /tmp/haproxy:/usr/local/etc/haproxy 前面这个路径是我们在宿主主机上同步创建的文件件
主要用途是:在本地方便去修改haproxy的配置文件;
/usr/local/etc/haproxy 这个是haproxy镜像文件中Dockerfile设置的一个挂载目录,
我们将其挂载映射到宿主主机的/tmp/haproxy
4.另外haproxy源码地址:
https://github.com/docker-library/haproxy/blob/master/2.1/
启动haproxy进程
[root@izwz91h49n3mj8r232gqwez haproxy]# docker exec -it haproxy01 bash
root@788825f7ee56:/# haproxy -f /usr/
bin/ games/ include/ lib/ local/ sbin/ share/ src/
root@788825f7ee56:/# haproxy -f /usr/l
lib/ local/
root@788825f7ee56:/# haproxy -f /usr/local/etc/haproxy/haproxy.cfg
root@788825f7ee56:/#
打开haproxy监控控台
[http:ip:8888/dbs_monitor]
默认账户和密码:admin/admin
这里的8888 是由于haproxy.cfg中的8888决定的
结果
配置负载的请求路径
1.这里登陆的账户密码就是pxc-node1-3三个数据库的账号和密码 root/root
2.配置负载的路径为ip:3306 然后负载到数据库的三个节点 pxc-node1,pxc-node2,pxc-node3,
这样就实现了请求的负载,三台mysql服务器能够收到相对均衡的请求数据量;