容器技术已经广泛应用在接口开发等各个方面,那么容器中产生的应用数据如用户上传的文件,系统日志等,应该如何做好持久化存储,以便共享及后续数据分析。本文会解答这个问题。
docker容器中创建的文件默认是存储在容器可写层,这意味着有如下限制
- 容器消失后数据会消失,容器外需要访问数据比较困难
- 容器可写层是与宿主机器耦合一起的,不能轻易移动
- 写数据到容器可写层需要storage dirver来管理文件系统,storage dirver使用linux内核提供一致的文件管理系统,相比使用直接写入host文件系统的volume,性能会下降
存储方法
为了持久化数据,Docker有三种方法将数据存储到主机中, volumes, bind mounts, tmpfs mount
- Volumes 存在Docker管理的主机文件目录下(/var/lib/docker/volumes),非docker进程不能更改这个目录。
- Bind mounts 可以mount任意的主机目录到docker,非docker进程也可以更改
- tmpfs 数据存在主机内存中,不会写入主机文件系统。
应用场景:
Bind Mounts
本机开发时候使用,将代码目录直接bind mounts到docker中,可以直接查看运行效果。生产环境不建议使用,因为依赖于主机。
Volumes
- 容器之间共享数据
如web日志需要上传到ElasticSearch, - 应用数据持久化
如用户上传的文档,可以使用Volume的nfs扩展存储到NFS上,或者使用云扩展上传到云文件系统中如AWS S3。
docker volume命令
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
使用实例
version: '2'
services:
dd:
image: dd_local:latest
container_name: dd
command: ["web-service"]
environment:
- "ELASTICSEARCH_HOST=es-master-dd"
- "ELASTICSEARCH_PORT=9200"
volumes:
- logs-volume:/var/log/dd
- ../:/src
command: ["web-service"]
ports:
- "80:80"
networks:
- esnet
depends_on:
- kibana-dd
filebeat-dd:
image: filebeat_dd:latest
container_name: filebeat-dd
volumes:
- logs-volume:/var/log/dd
networks:
- esnet
volumes:
logs-volume:
driver: local
networks:
esnet:
dd是web应用的container,产生的日志log需要通过filebeat上传到elasticsearch中,通过logs-volume共享数据。
…/:/src 将代码直接bindmount到container中,方便调试。
经验
- 用户上传数据,日志等一定要确保数据持久化已经测试完备,不然会丢数据。
- 可以使用专门的volume container来管理