直接说结论:用 Docker Desktop 跑 redis,不是“图省事装个软件”那么简单,而是把 redis 的开发、测试、部署环境统一成一个随时可复现的镜像。我帮团队排查过不少 redis 容器使用问题,大多数坑都不是 redis 本身出的,而是对 Docker Desktop 的目录映射、端口绑定、容器生命周期理解不到位。这篇就按我实操的路径,把从拉镜像到深度配置、再到排查问题的完整过程写清楚,适合刚接触容器、想在本地快速搭一套 redis 环境的开发者,也适合已经用了一段时间但老被细节卡住的选手。
1. 为什么选择 Docker Desktop 跑 Redis——方案选型与前置准备
1.1 先用一句话说清 Dcoker Desktop 是什么
Docker Desktop 是 Docker 官方出品的桌面端容器运行环境,Mac 和 Windows 上都能装。它的核心价值不是“能装软件”,而是提供一个与生产环境高度一致的运行沙箱:你在本地跑起来的 redis,和在服务器上用 docker run 跑起来的 redis,内核逻辑、配置路径、网络方式几乎完全一致。
选它跑 redis 有几个实际好处。第一,环境隔离。redis 以容器方式运行,不会往宿主机里塞一堆动态库、配置碎片和残留服务。第二,版本切换成本低。想测 redis 7 和 redis 6 的差异,本质上就是切换镜像标签,而不需要来回卸载安装。第三,团队协作好复现。你写一个 docker-compose.yml,同事拉起来就是同一套环境,没人再喊“我这边怎么跑不起来啊”。
1.2 安装 Docker Desktop 前的硬件与网络准备
装之前有硬性条件建议先自查一遍,不然装到一半容易白折腾。Windows 端必须开启 WSL2,Docker Desktop 新版默认依赖 WSL2 做资源隔离和文件系统支持。Mac 端要求系统版本不能太旧,Intel 芯片和 Apple 芯片使用的安装包也不同,装错包会直接报“无法打开”。
硬件资源上,至少保证可用内存 8G 以上,磁盘剩余空间 30G 以上。为什么强调这个数字?因为 Docker 引擎本身、镜像缓存、容器写入层都会占空间,而且本地跑 redis 往往还伴随其他中间件容器,空间不够时最容易出现的症状是:镜像拉取到一半报错、容器启动后自动退出,且日志里没有任何有效错误提示。
网络方面,国内网络环境下拉取镜像经常出现超时或速度极慢,这一点要有心理准备。解决办法就是配置镜像加速源,这个属于常规操作,但不同版本的 Docker Desktop 配置入口有差异,建议在设置里的 Docker Engine 配置项中追加 registry-mirrors 字段,配置完需要重启引擎才生效。
注意:镜像加速配置一定要改完就立刻确认是否生效,不要等拉取报错再回头排查。验证方式也很简单,改了之后跑一条
docker pull hello-world,如果拉取速度快且没有报 TLS 相关错误,那基本就没问题了。
1.3 为什么不用 Homebrew 或官方安装包直接装 Redis
肯定有人会问,本地直接用包管理器装 redis 不是更快吗?我承认安装那一下确实很快,但这种方式有几个长期成本。第一,服务随系统启动的机制要自己配置,否则每次开机都要手动拉起来。第二,配置文件散落在系统目录里,改坏了想恢复只能靠备份。第三,多个项目对 redis 版本有不同要求时,系统级只有一个全局版本,冲突起来非常麻烦。
而容器方案的优势在于:redis 实例与外部系统的边界非常清晰。删除重建一个容器,对宿主机毫无影响。配置文件挂载在项目目录内部,改动了也能通过 git 追踪。多版本并行的时候,只要容器名和端口不冲突,想跑几个跑几个。
我实际经手过的几个项目迁移,从 Homebrew 方案迁到 Docker 方案之后,原先“程序能跑但不知道连的是哪个 redis”这种尴尬局面基本绝迹,因为容器名、网络别名、端口映射都是显式声明的。
2. 从拉取镜像到跑起第一个 Redis 容器——标准操作与参数拆解
2.1 拉取镜像:标签选择有讲究
打开终端,确认 Docker Desktop 处于运行状态,直接执行:
docker pull redis冒号后面没写标签,默认拉取的是 latest 标签,也就是最近发布的最新稳定版本。如果你想锁定大版本,比如用 7.2.x 系列,可以写成:
docker pull redis:7.2如果只是想临时验证功能,alpine 变体的镜像体积更小,启动更快:
docker pull redis:7.2-alpine拉取完成后,通过docker images查看本地镜像列表,确认 REPOSITORY 是 redis,TAG 正确,SIZE 正常(标准版一般在 100MB 左右,alpine 版一般在 35MB 左右),这一步检查建议不要跳过,因为碰上镜像损坏或平台架构不匹配时,后面启动容器会出现各种诡异报错。
2.2 第一次启动容器:命令逐段解释
先跑一个最基础版本,把容器拉起来再说:
docker run -d --name my-redis -p 6379:6379 redis这个命令看起来不长,但每个部分都值得说透。
docker run是创建并启动一个新容器的命令。-d表示后台运行,不加的话当前终端会被容器日志占用。--name my-redis给容器起了一个明确的名字,后续查询日志、停止、删除容器时都用这个名字,比记一串容器 ID 方便太多,强烈建议每次都起名。-p 6379:6379是端口映射,左侧 6379 是宿主机端口,右侧 6379 是容器内部 redis 监听的端口。前面是“外面”的入口,后面是“里面”的服务端口,这个顺序我见过好几个人写反,写反的直接后果就是客户端连接被拒。最后的redis是镜像名。
执行完命令后,输入docker ps查看运行状态。STATUS 如果是 Up X seconds,说明已经正常起来了。此时本机任意 redis 客户端都能通过127.0.0.1:6379连上这个容器里的 redis。
2.3 进入容器内部验证 Redis 可用性
容器是黑盒,光看端口映射成功还不够。我习惯用两条命令验证容器内部状态。
docker exec -it my-redis redis-cli ping如果返回 PONG,说明 redis 服务本身正常响应。然后查看基本信息:
docker exec -it my-redis redis-cli info server这里能看到 redis_version、uptime_in_seconds、config_file 等关键字段。重点关注 config_file,如果显示为空,说明 redis 是以默认配置启动的,没有加载任何自定义配置文件。这其实是很重要的信号。因为后续做持久化、密码配置、内存策略调整时,你必须在启动命令里挂载并指定配置文件,否则改的东西不生效。
提示:容器启动后不要用
docker exec -it my-redis redis-cli shutdown这种命令直接关闭 redis。原因在于 redis 容器的主进程就是 redis-server,当你通过 exec 执行 shutdown 时,等于让容器主进程退出,容器状态随之变成 exited。这不算错误操作,但容易让人误以为容器崩溃了。理解这个机制,后续排查容器退出问题会更从容。
3. 数据持久化与自定义配置——让 Redis 从“临时玩具”变成“开发环境基础设施”
3.1 为什么只跑默认容器还不够
直接跑第一条命令确实快,但只要你执行docker rm -f my-redis把容器删掉,再重新创建一个完全一样的容器,你存进去的数据就全没了。很多第一次用容器跑 redis 的开发者都会在这一步踩坑:容器明明还在,数据怎么就没了?
核心原因要从容器文件系统的生命周期说起。容器是一个隔离的运行环境,但它的可写层与镜像层分离。你在 redis 里写入 key 后,数据被持久化到容器可写层,可写层跟容器本身生命周期绑定。一旦容器被删除,可写层也被清除。这时候就引出一个核心概念:volume,即数据卷。数据卷是独立于容器生命周期之外的一块存储空间,容器删除后数据卷还在,重新创建容器时重新挂载同一个数据卷,数据就能完整恢复。
开发环境里用更简单的方式:直接把宿主机的某个目录挂载到容器内部的数据目录,比如把宿主机/Users/你的用户名/data/redis映射到容器里的/data。这样 redis 的持久化文件就直接写在宿主机目录里,怎么删容器都不怕。
3.2 挂载目录与配置文件的标准启动命令
先把宿主机需要使用的两个目录准备好,一个是数据目录,一个是配置文件目录。
mkdir -p ~/docker-data/my-redis/data mkdir -p ~/docker-data/my-redis/conf接着准备 redis.conf 配置文件。先做一层最小可用的配置,后续再按需扩展。
cd ~/docker-data/my-redis/conf touch redis.conf然后启动容器时同时挂载数据和配置目录:
docker run -d \ --name my-redis \ -p 6379:6379 \ -v ~/docker-data/my-redis/data:/data \ -v ~/docker-data/my-redis/conf/redis.conf:/etc/redis/redis.conf \ -d redis redis-server /etc/redis/redis.conf \ --appendonly yes命令较长,但拆开看就清晰了。第一块是容器参数,指定容器名、端口映射、数据卷挂载、配置文件夹挂载。第二块是镜像名redis。第三块是启动 redis 服务,并显式指定加载/etc/redis/redis.conf这个配置。第四块是启动时追加的运行时参数,--appendonly yes开启 AOF 持久化,让 redis 把每条写操作追加到文件里。
这里有个很关键的细节:如果你在容器启动命令里写了-v 宿主机配置路径:/etc/redis/redis.conf,但宿主机上这个配置文件是空的,redis 启动后不会报错,只会以“空配置”方式运行。换句话讲,挂载空文件和没挂载配置文件的效果几乎一样。想要让配置真正生效,必须提前把配置写进宿主机文件里。
另外,配置文件的权限也要注意,至少保证当前用户有读取权限。否则容器内 redis 进程读取文件时会提示 Permission denied,这类问题在 Mac 和 Windows 上出现概率不高,但在 Linux 环境下很常见。
3.3 redis.conf 里最值得先配好的三个参数
自定义配置文件是容器跑 redis 的核心升级方式,其中有几个参数我建议在第一次启动之前就写进去,避免后面反复改配置重启。
第一个是持久化策略。如果你决定用 AOF,至少把下面两行写进配置文件:
appendonly yes appendfsync everyseceverysec表示每秒把缓冲区的写命令同步到磁盘,这是性能和安全性之间比较平衡的选择。如果业务对数据丢失容忍度极低,改为always会安全一些,但性能和磁盘 IO 压力会明显上升。
第二个是内存上限与淘汰策略。不设置 maxmemory 的风险在于,容器内的 redis 会持续使用内存直到宿主机内存告警,最终可能导致 Docker Desktop 整体卡死,所有容器一起遭殃。设置一个上限能保护宿主机,也能让 redis 在内存紧张时有明确的淘汰行为。常见的组合是:
maxmemory 512mb maxmemory-policy allkeys-lruallkeys-lru表示内存满了以后按照最近最少使用策略淘汰 key,适合大多数缓存场景。
第三个是访问密码。虽然本地开发环境可能不太在意,但如果你把容器端口映射到宿主机后,同一局域网内任何设备都能访问 6379 端口,不设置密码等于把数据敞开给别人读。设置方式是在配置文件里加入:
requirepass your-strong-password设置之后,本机客户端连接也需要带密码,防止那种“本地验证通了、换个网络环境就被人扫到”的尴尬局面。
注意:不要把密码直接写在 docker run 命令里,更不要把密码提交到 git 仓库。配置文件的密码一旦泄露,等于 redis 大门敞开。本地开发用简单密码没关系,但要养成“密码只放在配置文件中”的习惯。
3.4 容器启动失败时的自检顺序
挂载配置目录之后,最常见的失败场景就是启动后容器瞬间退出。排查顺序建议固定下来,省时间。
第一步,docker ps -a查看容器状态。第二步,docker logs my-redis查看日志。第三步,重点看日志里是否有 Error opening config file 或 Permission denied 之类的字样。
如果日志显示配置加载失败,先检查宿主机配置文件路径是否正确。路径没问题,检查文件权限。权限没问题,检查文件内容是否存在语法错误,比如缩进、中文引号、不支持的参数。
这种自检顺序看起来基础,但能解决八成以上由配置挂载引起的启动问题。不要一上来就删容器重建,那样既难定位问题,也容易掩盖真实原因。
4. 客户端连接、可视化管理与安全检查——把容器 Redis 当成正式服务来管理
4.1 宿主机连接 Redis 的三种方式
容器跑起来之后,连接方式取决于你处在什么环境。
第一,最直接的方式,使用本机 redis-cli。如果没有单独安装 redis 客户端工具,可以直接用容器里的自带的客户端,这条命令在宿主机上就能执行:
docker exec -it my-redis redis-cli -a your-password ping注意-a后面的密码要和你配置文件里的保持一致。如果不想每一次都明文带密码,可以用REDISCLI_AUTH这个环境变量,redis-cli会自动读取,效果是一样的。
第二,从宿主机其他程序连。连接地址写127.0.0.1:6379就行。因为端口映射已经建立了宿主机到容器的通路,而且这个通路是双向可见的,所以客户端无需做任何额外配置。
第三,从其他容器里连。此时不能用 127.0.0.1,哪怕是同一个 Docker 宿主机上跑的容器之间,也不建议通过宿主机端口互相访问。正确做法是让容器加入同一个自定义网络,然后用容器名作为主机名连接。先建网络:
docker network create my-dev-net再启动 redis 容器时加上--network my-dev-net,其他应用容器也加入这个网络,应用内部的连接地址写my-redis:6379即可。这种方式的好处是绕过了端口映射的转发开销,容器之间通信走的是 Docker 内部网络,速度更快,也不容易被外部访问到。
4.2 用可视化工具查看数据状态
命令行虽然是基本功,但可视化工具能让你更快了解 redis 里到底存了什么。本地开发阶段我推荐用 RedisInsight 这类图形化工具,连接配置和普通客户端相同:host 填 127.0.0.1,port 填 6379,密码填配置文件里设置的值。
可视化工具的价值主要体现在两个场景:一是浏览 key 列表,快速确认某个缓存是否已经写入;二是查看内存分析,看看哪些 key 占了多大空间,以及内存淘汰实际是否触发。
不过说实话,可视化工具更适合“查看”和“临时操作”,真正做配置管理和性能排查,我还是习惯命令行。比如查看当前 key 数量,命令行一条搞定:
docker exec -it my-redis redis-cli dbsize4.3 容器级安全检查:端口暴露与防火墙
把容器端口映射到宿主机之后,实际上等于把服务暴露给了所有能到达宿主机 IP 的网络节点。本地开发时这个风险不大,可一旦宿主机连接了办公网络或校园网络,事情就变得敏感起来。
我建议至少做两步检查。第一步,确认宿主机的防火墙策略,明确 6379 端口只允许来自本机的连接。第二步,确认 redis 配置文件里的bind设置。如果 bind 写的是0.0.0.0,redis 会在所有网络接口上监听,外部设备只要知道宿主机的 IP 就能尝试连接。本地开发更稳妥的配置是:
bind 127.0.0.1这里有个细节要说明:bind 配置限制的是 redis 进程本身监听哪个接口,和 Docker 端口映射并不冲突。bind 127.0.0.1 时,宿主机 6379 端口映射仍然生效,但远端连接会被 redis 自身拒绝,因为从容器视角看,连接来源经过端口映射后是宿主机回环地址。这种组合是我个人比较推荐的:宿主机端口随便映射,redis 只信任宿主机来源。
5. 常见问题与排查技巧实录——把容易踩的坑一次性说清楚
5.1 排查问题前先确认 Docker Desktop 本身状态
不少 redis 容器问题看起来是 redis 配置问题,实际却是 Docker Desktop 没有正常运行。尤其是 Mac 上 Docker Desktop 偶尔会出现后台状态显示正常、但实际引擎不在服务的假象。
遇到容器启动异常、端口映射不生效等问题,先打开 Docker Desktop 主界面确认状态栏是否为绿色运行状态。如果状态异常,重启 Docker Desktop 后再重新执行 docker ps 验证。
还有一种容易被忽略的场景:Docker Desktop 升级后,WSL2 后端要重新初始化,旧容器可能处于退出状态,但你没注意到。这种时候直接docker start my-redis恢复容器运行,不需要重新创建。
5.2 端口占用与映射冲突
启动 redis 容器时如果提示端口 bind 失败,通常意味着宿主机的 6379 端口已经被占用了。这个占用可能来自另一个 redis 容器、一个普通系统服务,也可能是刚才调试时留下的僵尸进程。
在宿主机上执行:
lsof -i :6379可以快速查到占用进程的 PID。确认不是自己需要保留的服务后,用kill -9 PID结束进程,或者直接改 redis 容器映射端口,比如从 6379:6379 改成 6380:6379。后一种做法在生产环境更常见,避免和系统默认服务冲突。
需要注意的是,修改端口映射不能直接改一个运行中容器的参数。容器创建时的端口映射是固定不变的,想改就必须删掉容器重新创建。因此,第一次启动前就想清楚端口策略,能省不少后续麻烦。
5.3 容器内时区与日志时间错位
容器默认时区是 UTC,和国内时区差 8 小时。redis 日志里的时间戳会比宿主机时间落后 8 小时,排查问题时不注意会把因果顺序搞颠倒。
解决办法是启动容器时挂载宿主机时区文件:
-v /etc/localtime:/etc/localtime:roMac 上同样能挂载,效果一致。挂载后容器内日志时间就会和宿主机保持一致。这种问题不会导致功能异常,但在跨团队协作时很容易引发误判,建议第一次创建容器就顺手挂上。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 处理方式 |
|---|---|---|
| 容器启动瞬间退出 | 配置文件语法错误或权限不足 | 查看 docker logs,检查配置文件内容与权限 |
| 客户端连接超时 | 端口映射未生效或防火墙拦截 | 确认 docker ps 端口列,检查宿主机防火墙 |
| redis-cli ping 返回 NOAUTH | 未带密码或密码错误 | 使用 -a 参数带上正确密码 |
| 数据重启后丢失 | 未挂载数据卷或未开启持久化 | 重新创建容器,挂载数据目录并开启 appendonly |
| 内存持续上涨导致宿主机卡顿 | 未设置 maxmemory | 在 redis.conf 中增加 maxmemory 与淘汰策略 |
| 容器内写操作提示 OOM 相关错误 | 容器内存限制过小 | Docker Desktop 中调大容器内存限额 |
5.5 Mac 和 Windows 在挂载目录时的路径差异
路径挂载是跨平台容器开发中最容易出现理解偏差的部分。Mac 的挂载命令可以直接写绝对路径,例如:
-v /Users/你的用户名/docker-data/my-redis/data:/dataWindows 上路径写法要谨慎。如果是 WSL2 后端,尽量使用 WSL 内部的 Linux 文件系统目录,不要直接挂载 Windows 盘符路径。直接挂载 C 盘和 D 盘的路径时,Docker Desktop 与 Windows 文件系统之间需要一层额外转换,文件 IO 性能会明显下降。换句话说,WSL2 场景下,把数据目录放在 Linux 文件系统里,写入性能远好于放在 Windows 文件系统上。
还有一种常见的路径错误:Windows 挂载路径使用反斜杠,但 Linux 风格的挂载点使用正斜杠。两者混写容易导致路径解析失败。建议统一用正斜杠,并且在命令行里用双引号包裹整个挂载参数,避免空格问题。
6. 进阶:用 docker-compose 固化 Redis 环境——从“临时容器”迈向“项目级基础设施”
6.1 docker-compose 的核心价值:把命令变成配置
单条 docker run 命令跑 redis 没问题,但一旦涉及多个容器、多个网络、多个环境变量,命令会变得非常长且难以维护。docker-compose 的意义在于把上述所有参数“固化成一份 YAML 配置”,团队成员拉取项目后一条命令就能复现整套环境。
以 redis 为例,在项目根目录创建docker-compose.yml:
services: redis: image: redis:7.2-alpine container_name: my-redis ports: - "6379:6379" volumes: - ./redis/data:/data - ./redis/conf/redis.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf restart: unless-stopped networks: - dev-net networks: dev-net: driver: bridge这个配置把之前 docker run 里的所有参数都涵盖进来了,而且restart: unless-stopped让容器在 Docker 引擎重启后自动恢复,省去手动 start 的步骤。
启动方式:
docker compose up -d停止但保留数据:
docker compose down这里需要区分两个常用命令:docker compose down会停止并删除容器,但不会删除数据卷,所以数据还是安全的;docker compose down -v则会连数据卷一并删除,属于“彻底拆除”模式,不是明确要清空数据时千万别加 -v。
6.2 多环境配置:开发、测试、生产切换
项目发展到后期,通常需要 dev 和 test 两套 redis 实例。一种做法是复制两份 yml 文件,另一种做法是在同一个 yml 里通过profiles或environment变量区分。我个人更推荐使用不同 compose 文件管理不同环境,例如docker-compose.dev.yml和docker-compose.test.yml。
两个文件里镜像版本可以不同、端口映射可以不同、maxmemory 限制也可以不同。好处是环境隔离明确,互不污染,而且不同团队分支可以各自维护对应文件,不会产生“一个文件两套配置”的混乱局面。
6.3 容器资源限额配置
开发环境虽然不需要像生产环境那样精细调优,但给容器设置资源限额还是有必要的。
在 compose 文件里增加 mem_limit 和 cpus 配置项,比如:
services: redis: image: redis:7.2-alpine mem_limit: 512m cpus: 1.0设置之后,即便 redis 的内存使用异常暴涨,也不会把宿主机拖垮。因为容器内部的内存分配超过限额后,Linux 内核会参与干预,redis 进程会被强制进入 OOM 相关处理路径。
不过 Redis 官方对容器限制内存的策略有一点提醒:不要用 Docker 层面的内存限制完全替代 redis 自身的 maxmemory 参数。原因在于 Redis 的内存淘汰机制需要知道自己能使用多大内存,如果你只限制容器但不设置 redis maxmemory,redis 在分配内存到接近容器限制时可能还没触发淘汰策略,直接导致进程被 OOM 杀掉。两个限制需要同时存在,一个管“服务自身行为”,一个管“容器边界”。
7. 一个完整的最小生产级配置样例
把上面的知识点汇集成一个可复用的最小生产级配置。适合在本地开发环境直接使用,也可以作为团队内部脚手架的一部分。
宿主机目录:
- 数据目录:
~/docker-data/my-redis/data - 配置目录:
~/docker-data/my-redis/conf
redis.conf内容建议如下:
bind 127.0.0.1 port 6379 daemonize no appendonly yes appendfsync everysec maxmemory 512mb maxmemory-policy allkeys-lru save 900 1 save 300 10这里解释几个关键点。daemonize no是容器场景下的硬性要求。因为容器主进程必须是前台进程,如果 redis 自己后台化,容器会认为进程已经结束,随之进入退出状态。save开头的几行是 RDB 快照配置,表示多少秒内有多少次写操作时触发一次快照。save 900 1是 900 秒内至少有 1 次写操作就触发,save 300 10是 300 秒内至少有 10 次写操作就触发。RDB 快照用做快速恢复,AOF 文件用做更精确的持久化,两者可以同时开启,启动时 redis 会优先用 AOF 文件恢复数据。
启动命令(compose 场景下不需要手动执行 run,但单容器场景下这样写):
docker stop my-redis 2>/dev/null; docker rm my-redis 2>/dev/null docker run -d \ --name my-redis \ --network my-dev-net \ -p 6379:6379 \ -v ~/docker-data/my-redis/data:/data \ -v ~/docker-data/my-redis/conf/redis.conf:/etc/redis/redis.conf \ -v /etc/localtime:/etc/localtime:ro \ redis:7.2-alpine \ redis-server /etc/redis/redis.conf如果不需要自定义网络,把--network my-dev-net去掉即可,不会影响 redis 本身的运行。如果需要的服务与 redis 通信,再把它们统一加入 same network。
启动完成后,做一轮完整验证:
docker ps docker logs my-redis docker exec -it my-redis redis-cli ping docker exec -it my-redis redis-cli set hello world docker exec -it my-redis redis-cli get hello全部按预期输出,说明环境已经稳定可用。这套流程跑通之后,再往里加其他中间件容器,比如 postgres、kafka、nacos,思路是一模一样的。
8. 个人习惯与最后建议
我把 Docker Desktop 跑 redis 这套流程在本地用了一年多,踩过的坑里面,最值得提醒的还是那几点:不要生产连接懒密码,不要忘记后台持久化,更不要随意删容器却不关心数据卷去向。小组里有同事问为什么项目跑着跑着缓存没了,一排查就是容器被开发工具清理掉,数据没有挂载目录。这种问题不是 redis 故障,而是容器使用方式的问题。
我自己的习惯是每个项目目录下都放一个 docker-compose.yml,把 redis 作为 dependencies 之一固定下来。新机器上 clone 代码后,三五分钟就能恢复整套本地开发环境。这种体验比手工安装、手工配置、手工迁移数据要好得多,也是容器化最真实的价值。
如果这篇文章对你有一点帮助,建议照着上面的步骤,自己动手把容器建一遍,然后故意删掉重建一次,亲眼看看挂载了数据卷和没挂载数据卷的区别。只有亲手经历过一次“数据丢失又恢复”的过程,对容器和数据卷的理解才算是真正入门了。