容器数据卷

什么是容器数据卷

docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
例如MySQL:容器删了,数据丢失!需求:MySQL数据可以存储在本地!

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!目录挂在,将我们容器内的目录,挂载到Linux上!

容器数据卷

总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的

使用数据卷

方式一:直接使用命令挂载 -v

$ docker run -it --name="容器名" -v 主机内目录:容器内目录 -p 主机端口:容器内端口 镜像名

# 将容器中的/home目录挂载到宿主机的~/File/centos_test目录下,内部和外部的文件都会互相自动同步
$ docker run -it -v ~/File/centos_test:/home centos /bin/bash

查看一下容器的信息

$ docker inspect 容器id

容器数据卷

测试文件同步步骤和效果
容器数据卷

再次进行测试
1.停止容器
2.宿主机上修改文件
3.启动容器
4.容器内的数据依旧是同步的
容器数据卷

好处:我们之后修改只需要在本地修改即可,容器内会自动同步。

实战测试:安装MySQL

问题:MySQL的持久化问题!

# 获取镜像
$ docker pull mysql

# 运行容器,需要做数据挂载!安装启动mysql需要配置密码的,这是要注意的点!
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

# 启动镜像
docker run -p 3306:3306 --name=mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql

# 启动成功后,进入容器内部拷贝配置文件,到宿主主机。
docker cp mysql:/etc/mysql ~/File/docker_mysql

# 删除mysql容器,重新创建容器
docker stop mysql
docker rm mysql

# 启动
# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境配置
# --name 容器名
# --privileged=true 授权执行
# -i: 以交互模式运行容器
# MYSQL_ROOT_PASSWORD:数据库密码(自己设置)
$ docker run -i -d -p 3310:3306 -v ~/File/docker_mysql/mysql-file:/var/lib/mysql-file -v ~/File/docker_mysql/conf:/etc/mysql -v ~/File/docker_mysql/data:/var/lib/mysql -v ~/File/docker_mysql/logs:/var/log/mysql -v /etc/localtime:/etc/localtime -e MYSQL_ROOT_PASSWORD=123456 -privileged=true --name=mysql01 mysql

docker exec -it 容器名或者ID /bin/bash
mysql -hlocalhost -uroot -p123456
select host,user,plugin,authentication_string from mysql.user;
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '新密码';
flush privileges;

命令解释

-p 端口映射

--privileged=true  挂载文件权限设置

--restart unless-stopped  设置 开机后自动重启容器

-v ~/File/docker_mysql/mysql:/etc/mysql    挂载配置文件

-v ~/File/docker_mysql/logs:/logs \      挂载日志

-v ~/File/docker_mysql/data:/var/lib/mysql \  挂载数据文件 持久化到主机,

-v /etc/localtime:/etc/localtime    容器时间与宿主机同步

-e MYSQL_ROOT_PASSWORD=123456    设置密码

-d  mysql:8   后台启动,mysql

启动成之后外部使用navicate测试,navicate连接到服务器的3310,服务器的3310和容器的3306映射,这个时候我们就可以连接上了!

容器数据卷
在本地创建一个数据库

容器数据卷

容器数据卷

这是测试一下,将MySQL的容器删除,发现挂载到本地的数据卷在本地还保存着。

容器数据卷

mysql 数据备份

虽然我们可以通过数据卷的操作,将数据挂载到宿主机中,但是我们在实际的项目开发中会有这样的问题,当有新的服务器或者部署新的版本的 mysql 时,需要同步当前的数据库中的所有数据时,就显得力不从心,这时就需要进行 mysql 的数据备份。
# 导出全部数据
docker exec 容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /data/all--databases.sql

# 导出指定数据库数据
docker exec 容器id sh -c 'exec mysqldump --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /data/all--databases.sql

# 导出指定数据库数据不包含数据
docker exec 容器id sh -c 'exec mysqldump --no-data --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /data/all--databases.sql
# 执行 sql 文件到 mysql 中
docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/xxx.sql

具名挂载和匿名挂载

  • 匿名挂载
# -v 容器内路径
$ docker run -d -p --name nginx -v /etc/nginx nginx
# 查看所有卷的情况
$ docker volume ls
DRIVER              VOLUME NAME
local               a7ea06ddbf53d1e879f304470b4775abdf9e455d2fba0a589588a6f50ba22137
# 这里发现,这种就是匿名挂载,我们在-v的时候,只写了容器内的路径,没有写容器外的路径!
  • 具名挂载
# 通过 -v 卷名:容器内路径
$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

$ docker volume ls

$ docker volume inspect 卷名

容器数据卷

所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data

但是发现一个问题,mac中是没有这个目录的,可以通过 screen Library/Containers/com.docker.docker/Data/vms/0/tty(路径后半部分可能会变)进入到 LinuxKit 虚拟机内部,通过其他 linux 命令看到里边就是一个定制的 linux 系统,运行了dockerd, containerd 等后台进程。注意可使用 Ctrl+A+D 快捷键退出 screen 窗口。
关于screen的更多具体命令可以看我关于screen的 Blog。

容器数据卷

进入之后可以看到实际的文件是保存在LinuxKit 虚拟机内部,g.docker 在 mac os 或者 windows 上,都是基于特定的虚拟化技术运行linux 虚拟机,并不共享宿主机内核。

容器数据卷

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用具名挂载

# 如何确定是具名挂载还是匿名挂载还是指定路径挂载
-v 容器内路径    # 匿名挂载
-v 卷名:容器内路径    # 具名挂载
-v /宿主机路径:容器内路径    # 指定路径挂载
  • 拓展

在后面加上ro或者是rw,改变读写权限

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就限定了!
$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nignx:ro nginx

$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nignx:rw nginx

# 通过-v 容器内路径:ro rw 改变读写权限
# ro    readonly    只读    只能通过宿主机操作,容器内无法改变
# rw    readwrite    可读可写

初识 Dockerfile

Dockerfile就是用来构建docker镜像的构建文件!命令脚本。
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层。

创建一个dockerfile
文件中的内容,指令(大写)参数

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "-----end-----"
CMD /bin/bash

# 这里的每个命令就是镜像的一层
$ docker build -f ~/File/docker_test_volume/dockerfile1 -t hudu/centos:1.0 .

容器数据卷

启动自己的镜像测试

容器数据卷

这个卷一定和外部有一个同步的目录!
1.通过命令查看容器的具体信息
2.看到挂载的卷在外部的具体的目录

容器数据卷

容器数据卷

容器数据卷

容器数据卷
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 容器内路径

数据卷容器

两个MySQL同步数据

容器数据卷

启动3个容器,通过我们刚才自己的写镜像启动
Ctrl+P+Q,不关闭容器退出

$ docker run -it --name docker01 hudu/centos:1.0 /bin/bash

$ docker run -it --name docker02 --volumes-from docker01 hudu/centos:1.0

$ docker run -it --name docker03 --volumes-from docker01 hudu/centos:1.0

容器数据卷

容器数据卷

容器数据卷

测试:删除docker01,查看一下,docker02和docker03都还有这个文件。

通过 docker inspect 容器id可以发现,其实他们都是映射到了宿主机的相同的目录下。
容器数据卷

多个MySQL实现数据共享

$ run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql

$ run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql02 --volumes-from mysql01 mysql

实现两个容器数据共享同步

结论,容器之间可以配置信息传递,数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦持久化到了本地,本地的数据是不会删除的。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
247
粉丝
18
喜欢
217
收藏
62
排名:731
访问:9753
私信
所有博文
社区赞助商