Docker容器数据持久化存储机制
一、Docker容器数据持久化存储介绍
1、物理机或虚拟机数据持久化存储
由于物理机或虚拟机本身就拥有大容量的磁盘,所以可以直接把数据存储在物理机或虚拟机本地文件系统中,也可以通过使用额外的存储系统(NFS、GlusterFS、Ceph等)来完成数据持久化存储。
2、Docker容器数据持久化存储
Docker 容器数据持久化存储是确保容器内数据在容器重启或删除后不会丢失的重要机制。
由于Docker容器属于“用后即焚”型计算资源,因此Docker容器做数据持久化存储需挂载宿主机数据卷
二、Docker容器数据持久化存储方式
Docker提供三种方式将数据从宿主机挂载到容器中:
- docker run -v
运行容器时,直接挂载本地目录至容器中
- volumes(数据卷)
数据卷是 Docker 官方推荐的持久化存储方式,由 Docker 管理,存储在宿主机的 /var/lib/docker/volumes 目录下。
优点:
数据卷的生命周期独立于容器,即使容器被删除,数据卷中的数据仍然保留。
支持在多个容器之间共享数据。
- bind mounts(绑定挂载)
绑定挂载允许将宿主机上的目录或文件直接挂载到容器内部。
优点:
操作简单,适用于简单的数据持久化需求。
数据存储在宿主机的任意位置,便于管理和访问。
局限:
依赖宿主机文件系统,可能存在性能和安全性问题。
- Docker容器数据持久化存储案例
实验目的:
将大量数据放在容器中不合适,所以可以将数据放在宿主机上(容器只开启服务,数据依旧放在宿主机上,这样不会因为停止容器造成丢失数据,更安全);
其二:频繁的进入容器有些繁琐,我们可以将宿主机做映射(通俗说就是挂载),比如说经常修改的配置文件可以直接在宿主机上修改,直接映射到容器中。
- 挂载本地目录
创建本地目录:
[root@docker-01 ~]# mkdir /opt/web1root
向本地目录中添加index.html文件:
[root@docker-01 ~]# echo 'web1-page' > /opt/web1root/index.html
运行web1容器,把/opt/web1root目录挂载到/usr/share/nginx/html目录中:
[root@docker-01 ~]# docker run -d --name web1 -v /opt/web1root/:/usr/share/nginx/html/ nginx
使用curl命令访问容器:
[root@docker-01 ~]# docker inspect e78ee5c7f0a6
[root@docker-01 ~]# curl http://172.17.0.2
web1-page
windows访问会报错,因为没有暴露端口!!!
- 未创建本地目录(系统将自动创建)
运行web2容器,挂载未创建的本地目录,启动容器时将自动创建本地目录:
[root@docker-01 ~]# docker run -d --name web2 -v /opt/web2root/:/usr/share/nginx/html/ nginx
往自动创建的目录中添加一个index.html文件:
[root@docker-01 ~]# echo "web2-page" > /opt/web2root/index.html
在容器中执行查看文件命令:
[root@docker-01 ~]# docker exec web2 cat /usr/share/nginx/html/index.html
web2-page
使用curl命令访问容器:
[root@docker-01 ~]# docker inspect d380cba9ed3c
[root@docker-01 ~]# curl http://172.17.0.3
web2-page
- Volumes(数据卷)
常用命令:
docker volume inspect data_vo1
创建数据卷:
创建一个名称为nginx-vol的数据卷:
[root@docker-01 ~]# docker volume create nginx-vol
确认数据卷创建后的位置:
[root@docker-01 ~]# ls /var/lib/docker/volumes/
查看已经创建数据卷:
[root@docker-01 ~]# docker volume ls
查看数据卷详细信息:
[root@docker-01 ~]# docker volume inspect nginx-vol
使用数据卷
运行web3容器,使用--mount选项,实现数据卷挂载:
[root@docker-01 ~]# docker run -d --name web3 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
# docker run -d --name web3 -v nginx-vol:/usr/share/nginx/html/ nginx
查看容器运行后数据卷中文件或子目录:
[root@docker-01 ~]# ls /var/lib/docker/volumes/nginx-vol/_data/
50x.html index.html
使用curl命令访问容器:
[root@docker-01 ~]# docker inspect 352829e6fecf
[root@docker-01 ~]# curl http://172.17.0.4
修改index.html文件内容:
[root@docker-01 ~]# echo "web3-page" > /var/lib/docker/volumes/nginx-vol/_data/index.html
再次使用curl命令访问容器:
[root@docker-01 ~]# curl http://172.17.0.4
web3-page
- Bind mounts
创建用于容器挂载的目录web4root:
[root@docker-01 ~]# mkdir /opt/web4root
运行web4容器并使用bind mount方法实现本地任意目录挂载:
[root@docker-01 ~]# docker run -d --name web4 --mount type=bind,src=/opt/web4root,dst=/usr/share/nginx/html nginx
查看已挂载目录,里面没有任何数据:
[root@docker-01 ~]# ls /opt/web4root/
添加内容至/opt/web4root/index.html中:
[root@docker-01 ~]# echo "web4-page" > /opt/web4root/index.html
使用curl命令访问容器:
[root@docker-01 ~]# docker inspect b2b2ad7be0c3
[root@docker-01 ~]# curl http://172.17.0.5
web4-page
实例一:数据卷挂载mysql
- 下载mysql镜像
[root@docker-01 ~]# docker pull mysql
- 启动mysql容器,映射端口、设置密码、挂载自动数据卷
[root@docker-01 ~]# docker run -itd --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123.com -v mysqldata:/var/lib/mysql mysql
- 查看数据卷数据:
[root@docker-01 ~]# ls /var/lib/docker/volumes/mysqldata/_data
- 连接数据卷,创建测试表
启动容器时下载的mysql镜像是最新版本,所以navicat也要用最新版连接测试,否则会报错,或者下载5.7版本的镜像可以用之前安装的旧版本的navicat
[root@docker-01 ~]# ls /var/lib/docker/volumes/mysqldata/_data/
- 删除mysql容器(模拟故障)
[root@docker-01 ~]# docker stop mysql1
[root@docker-01 ~]# docker rm mysql1
- 查看数据卷中是否还有数据
右击——刷新——表信息出现错误
- 新建容器,复用旧数据卷
删除所有容器:[root@docker-01 ~]# docker rm -f $(docker ps -aq)
[root@docker-01 ~]# docker run -itd --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123.com -v mysqldata:/var/lib/mysql mysql
- 连接数据库,查看旧数据表是否存在
- 再新建容器,以修改后的配置文件启动(方便后期修改配置文件)
[root@docker-01 ~]# docker rm -f $(docker ps -aq)
[root@docker-01 ~]# docker run -itd --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123.com -v mysqldata:/var/lib/mysql -v mysqlconf:/etc/ mysql
5.7镜像的命令:
[root@docker-01 ~]# docker run -itd --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123.com -v mysqldata:/var/lib/mysql -v mysqlconf:/etc/mysql mysql:5.7
查看方法:
[root@docker-01 ~]# ls /var/lib/docker/volumes/mysqlconf/_data/
[root@docker-01 ~]# ls /var/lib/docker/volumes/
将配置文件挂载到 mysqlconf 卷,将数据文件挂载到 mysqldata 卷。这样,即使容器被删除,只要卷没有被删除,数据和配置都不会丢失。
[root@docker-01 ~]# ls /var/lib/docker/volumes/mysqlconf/_data/
my.cnf