跑个容器应用,结果重启后配置全没了?日志也找不着了?这其实是很多新手踩过的坑——没搞明白容器平台的存储方案。容器本身是轻量、可销毁的,但数据不能跟着一起删,得想办法存住。
为什么容器默认存不了数据?
容器就像一次性杯子,用完就扔。它里面的文件系统是临时的,一旦容器停止或重建,里面的数据就没了。比如你往容器里的 /app/logs 写了日志,下次启动新容器,这个目录就是全新的,老日志自然就丢了。
用卷(Volume)存数据最常见
Docker 和 Kubernetes 都支持 Volume,简单说就是把宿主机的一块“硬盘区域”挂载进容器。这样即使容器换了,数据还在卷里。
比如在 Docker 里创建一个名为 appdata 的卷:
docker volume create appdata
然后运行容器时挂载进去:
docker run -d -v appdata:/var/lib/mysql --name db mysql:8.0
这样一来,MySQL 的数据就存在 appdata 卷里,换容器也不怕丢。
绑定挂载:直接连宿主机目录
如果你更习惯手动管理,可以用绑定挂载(Bind Mount),把宿主机的具体目录映射进容器。
比如你想把本地的 /home/user/config 映射到容器的 /etc/app/conf:
docker run -d -v /home/user/config:/etc/app/conf myapp
这种方式适合开发调试,改配置直接在宿主机上操作,容器立刻生效。
Kubernetes 里怎么处理存储?
在 K8s 环境中,常用 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)来管理存储。你可以理解为 PV 是“准备好的硬盘”,PVC 是“申请使用硬盘的请求”。
先定义一个 PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
然后在 Pod 里引用它:
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
spec:
containers:
- name: mysql
image: mysql:8.0
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
这样 Pod 重启或迁移,数据依然通过 PVC 保留在后端存储中。
云平台存储更省心
如果你用的是阿里云、腾讯云这类平台,它们通常提供现成的网络存储服务,比如云硬盘、NAS。Kubernetes 可以直接对接这些服务,自动创建 PV,不用你手动配置。
比如在阿里云上声明一个 NAS 类型的 PVC,系统会自动分配存储空间,多个容器还能共享访问,适合存放用户上传的图片、日志文件等。
小贴士:别把数据直接塞容器里
很多人图省事,直接在容器里改配置、存文件,结果一升级全白搭。正确的做法是:配置走环境变量或 ConfigMap,数据存卷或外部数据库。这样容器才能真正做到“可替换、可复制”。
举个例子,你部署了个博客系统,文章内容如果存在容器本地,哪天服务器出问题,博客就没了。但如果数据存到挂载卷或云数据库,换个容器照样正常打开。