docker 数据管理,数据持久化详解 一

docker镜像是分层设计的,镜像出只读,通过镜像启动的容器添加一层可读写的文件系统,用户写入的数据表都保存在这层中。

容器的数据分层目录

LowerDir:image 镜像层,即镜像本身,制度

UpperDir:容器上层,可读写,容器变化的数据存在在此处

MergeDir:容器的文件系统,使用Union FS(联合文件系统)将 LowerDir和UpperDir合并完成后给容器使用,最终呈现给用户的统一视图

WorkDir:容器在宿主机的工作目录,挂在后内容会被清空,请在使用过程中其内容用户不可见

数据持久化方式

1.卷 volume 最常使用

2.绑定挂载 bindmount 有安全风险

3.tmpfs挂载 挂载在内存里,且容器停止时 挂载文件会删除

卷分类

数据卷(Data Volume) 直接将宿主机目录挂载只容器的指定目录 常用

数据卷容器(Data Volume Container)间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据,不常用

数据卷详解

1.数据卷使用场景

数据库

日志输出

静态web页面

应用配置文件

多容器间目录或文件共享

2.数据卷特点

①数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用

②对数据卷更改数据在所有容器里面会立即更新

③数据卷的数据可以持久保存,删除使用该容器卷的容器也不影响

④在容器里面的写入数据不会形象到镜像本身,即数据卷的变化不会影响镜像的更新

⑤依赖于宿主机目录,宿主机出问题上面容器会受影响,当宿主机较多时,不方便统一管理

⑥匿名和命名数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,会拷贝到新初始化的数据卷中

3.数据卷分类

启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种

①指定宿主机目录或文件:指定宿主机的具体路径和容器路径的挂载关系,此方式不会创建数据卷

②匿名卷:不指定数据名称,至指定容器内目录路径充当挂载点,dicker自动指定宿主机的路径进行挂载,此方式会创建匿名数据卷,dockerfile中volume指定的卷即为此种

③命名卷:指定数据卷的名称和容器路径的挂载关系,此方式会创建命名数据卷

案例 1:MySQL 数据库

目标

  • 将 MySQL 数据库的数据持久化到主机上的命名数据卷中,确保数据在容器重启或删除后仍然保留。

步骤

  1. 创建命名数据卷:

docker volume create mysql_data

  1. 启动 MySQL 容器并挂载命名数据卷:

docker run -d --name mysql-container \

-e MYSQL_ROOT_PASSWORD=my-secret-pw \

-v mysql_data:/var/lib/mysql \

mysql:latest

  1. 验证数据卷:
  • 进入容器检查数据是否正确挂载:

docker exec -it mysql-container sh

ls /var/lib/mysql

  1. 停止和删除容器:

docker stop mysql-container

docker rm mysql-container

  1. 重新启动容器并挂载相同的命名数据卷:

docker run -d --name mysql-container \

-e MYSQL_ROOT_PASSWORD=my-secret-pw \

-v mysql_data:/var/lib/mysql \

mysql:latest

  1. 验证数据是否保留:
  • 进入容器检查数据是否仍然存在:

docker exec -it mysql-container sh

ls /var/lib/mysql

解释

docker volume create mysql_data:创建一个名为 mysql_data 的命名数据卷。

--v mysql_data:/var/lib/mysql:将命名数据卷 mysql_data 挂载到容器内的 /var/lib/mysql 目录,这是 MySQL 存储数据的默认位置。

docker stop 和 docker rm:停止并删除容器,但命名数据卷中的数据仍然保留。

重新启动容器:再次启动容器时,使用相同的命名数据卷,数据仍然存在。

案例 2:Nginx 静态文件

目标

将 Nginx 服务器的静态文件持久化到主机上的命名数据卷中,确保文件在容器重启或删除后仍然保留。

步骤

  1. 创建命名数据卷:

docker volume create nginx_static

  1. 启动 Nginx 容器并挂载命名数据卷:

docker run -d --name nginx-container \

-p 80:80 \

-v nginx_static:/usr/share/nginx/html \

nginx:latest

  1. 向数据卷中添加静态文件:
  • 创建一个 HTML 文件并复制到数据卷中:

echo "<h1>Hello, Docker!</h1>" > index.html

docker cp index.html nginx_container:/usr/share/nginx/html/

  1. 验证静态文件:
  1. 停止和删除容器:

docker stop nginx-container

docker rm nginx-container

  1. 重新启动容器并挂载相同的命名数据卷:

docker run -d --name nginx-container \

-p 80:80 \

-v nginx_static:/usr/share/nginx/html \

nginx:latest

  1. 验证静态文件是否保留:

访问 http://localhost,应该仍然能看到 "Hello, Docker!" 页面。

解释

docker volume create nginx_static:创建一个名为 nginx_static 的命名数据卷。

-v nginx_static:/usr/share/nginx/html:将命名数据卷 nginx_static挂载到容器内的 /usr/share/nginx/html` 目录,这是 Nginx 存储静态文件的默认位置。

docker cp:将本地文件复制到容器内的指定目录。

docker stop和 docker rm:停止并删除容器,但命名数据卷中的静态文件仍然保留。

重新启动容器:再次启动容器时,使用相同的命名数据卷,静态文件仍然存在。

案例 3:Redis 数据库

目标

将 Redis 数据库的数据持久化到主机上的命名数据卷中,确保数据在容器重启或删除后仍然保留。

步骤

  1. 创建命名数据卷:

docker volume create redis_data

  1. 启动 Redis 容器并挂载命名数据卷:

docker run -d --name redis-container \

-v redis_data:/data \

redis:latest

  1. 验证数据卷:
  • 进入容器检查数据是否正确挂载:

docker exec -it redis-container sh

ls /data

  1. 写入数据:
  • 使用 `redis-cli` 写入一些数据:

docker exec -it redis-container redis-cli

set key1 value1

exit

  1. 停止和删除容器:

docker stop redis-container

docker rm redis-container

  1. 重新启动容器并挂载相同的命名数据卷:

docker run -d --name redis-container \

-v redis_data:/data \

redis:latest

  1. 验证数据是否保留:
  • 使用 redis-cli 检查数据是否仍然存在:

docker exec -it redis-container redis-cli

get key1

exit

解释

docker volume create redis_data:创建一个名为 redis_data 的命名数据卷。

-v redis_data:/data:将命名数据卷 redis_data 挂载到容器内的 /data 目录,这是 Redis 存储数据的默认位置。

docker exec -it redis-container redis-cli:进入容器并使用 `redis-cli` 进行数据操作。

docker stop 和 docker rm:停止并删除容器,但命名数据卷中的数据仍然保留。

重新启动容器:再次启动容器时,使用相同的命名数据卷,数据仍然存在。

案例 4:多容器共享数据

目标

在多个容器之间共享数据,使用命名数据卷确保数据的一致性和持久性。

步骤

  1. 创建命名数据卷:

docker volume create shared_data

  1. 启动第一个容器并挂载命名数据卷:

docker run -d --name container1 \

-v shared_data:/shared \

nginx:latest

  1. 向数据卷中添加文件:
  • 创建一个文件并复制到数据卷中:

echo "This is a shared file" > shared_file.txt

docker cp shared_file.txt container1:/shared/

  1. 启动第二个容器并挂载相同的命名数据卷:

docker run -d --name container2 \

-v shared_data:/shared \

busybox:latest

  1. 验证文件是否共享:
  • 进入第二个容器检查文件是否存在:

docker exec -it container2 sh

cat /shared/shared_file.txt

  1. 停止和删除容器:

docker stop container1 container2

docker rm container1 container2

  1. 重新启动容器并挂载相同的命名数据卷:

docker run -d --name container1 \

-v shared_data:/shared \

nginx:latest

docker run -d --name container2 \

-v shared_data:/shared \

busybox:latest

  1. 验证文件是否保留:
  • 进入任意一个容器检查文件是否仍然存在:

docker exec -it container1 sh

cat /shared/shared_file.txt

解释

docker volume create shared_data:创建一个名为 shared_data的命名数据卷。

-v shared_data:/shared:将命名数据卷 shared_data 挂载到容器内的 /shared目录。

docker cp:将本地文件复制到容器内的指定目录。

docker exec -it:进入容器并检查文件是否存在。

docker stop 和 docker rm:停止并删除容器,但命名数据卷中的文件仍然保留。

重新启动容器:再次启动容器时,使用相同的命名数据卷,文件仍然存在。

相关推荐
Qayrup19 小时前
docker 搭建私有仓库,推送并拉取
运维·docker·容器
闪耀星星19 小时前
debian elctron-builder
运维·debian
会飞的土拨鼠呀19 小时前
Debian 12 笔记本合盖不休眠设置指南
运维·debian
郭庆汝19 小时前
docker拉取英伟达官方cuda11.8镜像
docker·cuda11.8
天下不喵21 小时前
Ubuntu24.04安装Docker过程记录
docker
黑黍21 小时前
如何在k8s中配置并使用nvidia显卡
云原生·容器·kubernetes
梁正雄1 天前
6、prometheus资源规划
运维·服务器·服务发现·prometheus·监控
晨曦之旅1 天前
零成本体验云计算!阿贝云免费服务器深度测评
运维·服务器·云计算
工具人55551 天前
Linux 抓取 RAM Dump 完整指南
linux·运维·安全
冷血~多好1 天前
使用docker部署elk,实现日志追踪
elk·docker·容器