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:停止并删除容器,但命名数据卷中的文件仍然保留。

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

相关推荐
binqian1 小时前
【Linux】mnt命名空间-操作
linux·运维·服务器
❀͜͡傀儡师1 小时前
CentOS 7 下升级 OpenSSL
linux·运维·centos
一叶飘零_sweeeet1 小时前
Docker 部署 Java 项目实践
java·docker
rr最叨2 小时前
Linux基础知识作业
linux·运维·服务器
cen难取名2 小时前
如何使用git上传项目至github。记一次上传github经历
运维·服务器·github
Karoku0662 小时前
【缓存与加速技术实践】Redis 高可用
运维·服务器·数据库·redis·mysql·缓存
Karoku0662 小时前
【缓存与加速技术实践】Redis 主从复制
linux·运维·服务器·数据库·redis·缓存
vivo互联网技术2 小时前
浅谈TiKV集群运维问题排查与修复——磁盘空间占用问题
运维·tikv
1037号森林里一段干木头2 小时前
ubuntu双屏只显示一个屏幕另一个黑屏
linux·运维·ubuntu
夜观天象昼编程2 小时前
服务器的免密登录和文件传输
运维·服务器