容器技術已經廣泛應用在接口開發等各個方面,那麼容器中產生的應用數據如用戶上傳的文件,系統日誌等,應該如何做好持久化存儲,以便共享及後續數據分析。本文會解答這個問題。
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來管理