Docker(05) 数据卷-数据持久化

一、数据卷的介绍

Docker应用与运行的环境 打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当这个容器被删除,容器中的数据也随之被删除。于是便产生了需求:容器中的数据持久化。容器之间有一个数据共享技术,将docker 中产生的 数据 同步到本地。这就是 卷技术,将容器内的目录挂载到宿主机上。

卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

数据卷的特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接在容器中生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

二、简单使用

运行容器,指定挂载数据卷命令:

docker run -it -v 主机目录:容器内的目录 镜像名 /bin/bash

在 Docker 中运行一个 CentOS 容器,并将主机的 /data/centos/home/test 目录挂载到容器内的 /home 目录。这样就可以在容器中访问主机上的 /data/centos/home/test 目录及其内容。

1. 先查看/data目录下是否有centos文件夹

tree /data

2. 在容器内部创建test.java文件,再看宿主机上是否同步创建了。

docker run -it -v /data/centos/home/test:/home centos /bin/bash

 参数说明:

  • docker run: 运行一个容器。
  • -it: 分配一个交互式的终端,并保持标准输入 (stdin) 打开。
  • -v /data/centos/home/test:/home: 挂载主机的 /data/centos/home/test 目录到容器内的 /home 目录。
  • centos: 使用 CentOS 镜像作为容器的基础镜像。
  • /bin/bash: 在容器内执行 /bin/bash 命令,启动一个交互式的 Bash 终端。

 通过以上命令,可以进入 CentOS 容器的交互式终端,并且在容器内可以访问并操作主机上 /data/centos/home/test 目录中的文件和文件夹。

 3. 在宿主机上创建test222.java,再看容器内部是否同步了。

root@hongpon316:~# cd /data/centos/home/test/
root@hongpon316:/data/centos/home/test# ls
test.java
root@hongpon316:/data/centos/home/test# touch test222.java
root@hongpon316:/data/centos/home/test# ls
test222.java  test.java
root@hongpon316:/data/centos/home/test# 

再进入容器内部查看是否有test222.java

root@hongpon316:/# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
dca4c4ec2518   centos    "/bin/bash"   10 minutes ago   Up 10 minutes             jolly_carson
root@hongpon316:/# docker exec -it dca /bin/bash
[root@dca4c4ec2518 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@dca4c4ec2518 /]# cd /home/
[root@dca4c4ec2518 home]# ls   可以看到test222.java已经同步到容器内部了
test.java  test222.java
[root@dca4c4ec2518 home]# 

4. 查看容器对应元数据docker inspect 容器id,可以在Mounts节点查看建立的数据卷信息

查看容器元数据:

docker inspect 容器id

 

即使容器停止运行或者容器删除,仍然可以实现数据同步,本地的数据卷不会丢失,即宿主机上挂载的文件夹不会同时被删除。

三、MySQL容器建立数据卷同步数据

Linux下的mysql

默认的数据目录存储在:/var/lib/mysql

默认的日志目录存储在:/logs

默认的配置文件存储在:/etc/mysql/conf.d

为了确保在MySQL镜像或容器删除后的数据不会丢失,下面建立数据卷保存MySQL的数据和文件。

---------------------------------------------------------------------------------------------------------------------------------

docker中的mysql挂载命令:

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
  -v /data/mysql/data:/var/lib/mysql \
  -v /data/mysql/log:/var/log/mysql \
  -e MYSQL_ROOT_PASSWORD=12345678 \
  --restart=always \
  mysql

参数说明:

  • -d: 将容器设置为在后台运行(以守护进程模式)。
  • --name mysql: 指定容器的名称为 "mysql"
  • -p 3306:3306: 将容器的 3306 端口映射到宿主机的 3306 端口,允许通过宿主机访问 MySQL 服务。
  • -v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf: 将宿主机上的 /data/mysql/conf/my.cnf 文件挂载到容器内的 /etc/mysql/my.cnf 文件,用于配置 MySQL 的配置文件。
  • -v /data/mysql/data:/var/lib/mysql: 将宿主机上的 /data/mysql/data 目录挂载到容器内的 /var/lib/mysql 目录,用于持久化存储 MySQL 的数据文件。
  • -v /data/mysql/log:/var/log/mysql: 将宿主机上的 /data/mysql/log 目录挂载到容器内的 /var/log/mysql 目录,用于存储 MySQL 的日志文件。
  • -e MYSQL_ROOT_PASSWORD=12345678: 设置 MySQL 的 root 用户的密码为 "12345678"。
  • --restart=always: 设置容器总是在退出后自动重启
  • -d mysql: 使用默认的最新版本的 MySQL 镜像创建容器,并在后台运行。

 注意:如果直接使用以上的方式挂载,会出现错误。

① 要确保宿主机上的 /data/mysql 目录存在,并具有适当的权限。如果目录不存在,可以使用以下命令进行创建。

mkdir -p /data/mysql/{conf,data,log}

 ② 因为-v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf会将my.cnf作为文件进行挂载,如果宿主记上没有名为my.cnf的文件一定会报flags: 0x5000错误,即:

 所以下面开始正确的挂载方式(先把刚刚未成功启动的容器删除,并且删除刚刚未成功挂载的目录):

①删除刚刚未启动成功的容器mysql

root@hongpon316:~# docker rm -f mysql 
mysql

②删除刚刚未成功挂载的目录

root@hongpon316:~# tree /data/mysql/
/data/mysql/
├── conf
│   └── my.cnf
├── data
└── log

4 directories, 0 files
root@hongpon316:~# rm -rf /data/mysql/{conf,data,log}
root@hongpon316:~# tree /data/mysql/
/data/mysql/

0 directories, 0 files

---------------------------------------------------------------------------------------------------------------------------------

 正确的挂载方式

 ①不添加挂载命令的方式启动mysql容器

目的:是为了将mysql容器成功启动,方便从容器内部复制配置文件到宿主机的/data/mysql/conf/目录下

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=12345678 \             
  --restart=always \   
  mysql

②在宿主机上创建要挂载的目录,如果有就不用创建了。

mkdir -p /data/mysql/{conf,logs,data}

 补充内容

进入容器内部

docker exec -it mysql /bin/bash

 whereis mysql:在容器中执行 whereis mysql 命令时,它将搜索系统路径来确定 mysql 可执行文件的位置。该命令将返回 mysql 可执行文件的路径,以及可能的源代码文件和帮助文档的路径。

root@e12898ada6d3:/# whereis mysql
mysql: /usr/bin/mysql /usr/lib/mysql /etc/mysql

find / -name my.cnf:f 将在容器内的整个文件系统中递归搜索名为 my.cnf 的文件,并显示找到的文件路径。如果希望限制搜索范围,可以将 / 替换为特定目录的路径,如 /etc 或 /usr/local/mysql

root@e12898ada6d3:/# find / -name my.cnf
find: '/proc/1/map_files': Permission denied
/etc/alternatives/my.cnf
/etc/mysql/my.cnf      #  这个就是我们需要复制到宿主机的配置文件
/var/lib/dpkg/alternatives/my.cnf

③将容器内部的配置信息复制到宿主机中

1.docker cp mysql:/etc/mysql/conf.d /data/mysql/conf/
2.docker cp mysql:/etc/mysql/my.cnf /data/mysql/conf/

④删除刚刚启动的容器

docker rm -f mysql 

⑤重新启动容器(以挂载的方式)

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
  -v /data/mysql/data:/var/lib/mysql \
  -v /data/mysql/log:/var/log/mysql \
  -e MYSQL_ROOT_PASSWORD=12345678 \
  --restart=always \
  mysql

启动成功: 

设置远程链接设置

①进入mysql容器

docker exec -it mysql /bin/bash

②登录mysql(回车后输入的密码是隐藏的)

mysql -u root -p

③设置远程链接的权限

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '12345678';
flush privileges;

四、具名挂载和匿名挂载

具名挂载和匿名挂载是 Docker 中用于将容器内部的路径与宿主机上的路径进行关联的两种不同方式。它们提供了一种方便的方式来在容器和宿主机之间共享和持久化数据。

匿名挂载

匿名挂载(Anonymous Volumes):匿名挂载就是在指定数据卷的时候,不指定容器路径对应的主机路径,这样对应映射的主机路径就是默认的路径/var/lib/docker/volumes/中自动生成一个随机命名的文件夹。例如:

docker run -d -P --name nginx01 -v /etc/nginx nginx

在容器内部创建一个匿名卷,并将其挂载到容器的 /etc/nginx 目录。
匿名卷的名称将由 Docker 自动生成,并且与容器的生命周期关联。

参数说明:

  • -d:以后台模式(detached mode)运行容器。
  • -P:将容器内部使用的网络端口映射到宿主机上的随机端口。
  • --name nginx01:为容器指定一个名称为 "nginx01"。
  • nginx nginx:指定要运行的镜像为 "nginx"。

 

  查看所有的数据卷volume的情况, VOLUME NAME这里的值是真实存在的目录。

docker volume ls

 具名挂载

具名挂载(Named Volumes):具名挂载是通过为卷分配一个名称来创建的。它允许在容器和宿主机之间共享数据,并且可以在多个容器之间共享。具名挂载的创建和管理由 Docker 引擎负责。可以使用 docker volume create 命令手动创建具名挂载,然后将其与容器关联。例如:

docker run -d -P --name nginx02 -v my_nginx:/etc/nginx nginx
```

在上述示例中,`my_bginx` 是一个具名挂载,它被关联到容器内的 `/etc/nginx` 路径。

 查看指定数据卷详细信息的命令:docker volume inspect 数据卷名称

可以看到 "my_nginx" 卷是一个本地驱动程序的卷,其挂载点位于 /var/lib/docker/volumes/my_nginx/_data。可以在宿主机上使用这个路径来访问和编辑卷的内容。

注意:具名卷(Named Volumes)在 Docker 中是持久化的,它们的数据在容器之间是可共享的,并且不会随着容器的删除而被删除。因此,即使删除了容器,卷中的数据仍然保留在宿主机上。

Docker所有的数据卷默认在/var/lib/docker/volumes/ 目录下。

匿名挂载,具名挂载,指定路径挂载的区别和联系

总的来说

匿名挂载适用于临时性的数据共享。

具名挂载适用于持久化数据和多个容器之间的数据共享。

指定路径挂载适用于与宿主机共享文件或目录的情况。

匿名挂载 具名挂载指定路径挂载
命令示例docker run -v 容器内的路径 imagedocker run -v 卷名:容器内的路径 imagedocker run -v 宿主机的挂载路径:容器内的路径 image
卷的生命周期独立于容器,即使容器删除也保留独立于容器,即使容器删除也保留独立于容器,即使容器删除也保留
卷的共享性仅在容器内部使用可在多个容器之间共享数据可与宿主机共享文件或目录
卷的命名和管理自动生成随机名称可手动创建或由 Docker 自动生成指定宿主机路径进行挂载
数据持久化数据将在容器停止和删除后仍然存在保留在具名卷中保留在宿主机路径中
数据备份与恢复不适用适用宿主机上的文件即为备份
使用场景临时性的数据共享持久化数据和多个容器间数据共享与宿主机共享文件或目录

指定数据卷映射的相关参数

ro —— readonly 只读。设置了只读则只能操作宿主机的路径,不能操作容器中的对应路径。挂载的目录或文件在容器中只能以只读方式访问。

rw ----- readwrite 可读可写。挂载的目录或文件在容器中可读可写。

docker run -d -P --name nginx_02 -v my_nginx:/etc/nginx:rw nginx
docker run -d -P --name nginx_01 -v my_nginx01:/etc/nginx:rw nginx

 -v 挂载和 -mount挂载方式的区别

① - v挂载方式:用于指定容器和主机之间的简单数据卷挂载。

docker run -d -v /host/data:/container/data image

②- mount挂载方式:一种更灵活的选项,用于详细配置挂载选项。它可以处理更复杂的挂载需求,例如指定挂载的类型、设置挂载的读写权限等。使用 --mount 选项时,您需要提供一个 JSON 格式的描述符来定义挂载配置。

docker run -d --mount type=bind,source=/host/data,target=/container/data image
```

在这个示例中,`type=bind` 指定挂载类型为绑定挂载,`source=/host/data` 指定主机上的路径,`target=/container/data` 指定容器内的路径。

五、常用命令

创建数据卷

docker volume create my_volume

删除数据卷

docker volume rm my_volume

查看数据卷

docker volume ls

查看指定的数据卷的信息

docker volume inspect <volume_name>

查看特定容器的数据卷信息

docker inspect <container_name_or_id> --format='{{ .Mounts }}'

删除容器时同时删除关联的数据卷

docker rm -v my_container

清理未使用的 Docker 卷

docker volume prune

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值