缘起
这是介绍docker容器的第三篇文章。本系列文章链接如下:
- 容器(1):容器相关知识简介——容器化、docker、docker-compose、Kubernetes / K8s等
- 容器(2):docker最佳实践指南——docker-compose和Portainer
- 容器(4):docker最佳实践指南——容器更新、升级和迁移
前两篇文章分别介绍了容器的基本概念和使用方法,以及使用容器的最佳实践方式。
之前的两篇文章中没有着重介绍数据卷(volume)的相关问题,但数据卷的管理其实是容器使用和管理中非常重要的一部分。通常来说,容器中的数据是临时的,当容器停止或删除时,容器中的数据也会被删除。这一机制使得容器非常轻量级,用户不用担心容器中的数据会占用过多的存储空间。
但在实际使用容器来部署某些服务时,我们可能需要将容器中的某些数据持久化,即使容器停止或删除,这些数据也不会丢失。例如之前的文章《使用Chevereto-free搭建私人图床》中,我们介绍了如何搭建私有图床,这时我们就需要将Chevereto中的图片数据持久化到宿主机上,以便在容器停止或删除后,仍然可以访问这些图片。或者将来我们将docker迁移到其他机器上时,也可以将这些数据迁移过去。
数据卷是Docker中用于持久化数据的机制,可以将容器中的数据保存到宿主机上,或者在多个容器之间共享数据。
前提
- 已安装Docker和docker-compose
- 了解Docker的基本概念和基本用法
- 使用docker-compose管理容器(如果你没有使用docker-compose管理容器,也不想使用docker-compose管理容器,那么本篇文章仅供参考)
数据卷(volume)简介
数据卷(volume)是Docker中用于持久化数据的机制,可以将容器中的数据保存到宿主机上,或者在多个容器之间共享数据。数据卷可以在容器之间共享,也可以在宿主机和容器之间共享。 数据卷的使用可以避免容器停止或删除时,容器中的数据被删除的问题。数据卷的使用可以提高容器的性能,因为数据卷是直接挂载到宿主机上的,而不是通过网络访问宿主机上的数据。
当使用docker-compose来管理容器时,我们可以在docker-compose.yml
文件中使用volumes
字段来定义数据卷及其使用方式。
一般来说,docker中的数据卷有以下几种类型:
-
命名卷(named volume):命名卷是Docker中最常用的数据卷类型,可以在多个容器之间共享数据。命名卷的名称是唯一的,可以通过名称来访问数据卷。命名卷的数据存储在宿主机上的
/var/lib/docker/volumes
目录下。 在docker-compose中使用命名卷时,可以在docker-compose.yml
文件中使用volumes
字段来定义命名卷,例如:1 2 3 4 5 6 7 8
version: '3' services: app: image: nginx volumes: - my_volume:/usr/share/nginx/html volumes: my_volume:
注意,命名卷在services中定义之后,还必须在
volumes
字段中定义。 -
绑定挂载(bind mount):绑定挂载是将宿主机上的目录挂载到容器中,可以在宿主机和容器之间共享数据。绑定挂载的数据存储在宿主机上的指定目录下。 在docker-compose中使用绑定挂载时,可以在
docker-compose.yml
文件中使用volumes
字段来定义绑定挂载,例如:1 2 3 4 5 6
version: '3' services: app: image: nginx volumes: - ./data:/usr/share/nginx/html
上述配置将宿主机上的
./data
目录挂载到容器中的/usr/share/nginx/html
目录下。绑定挂载还有一类特殊的用法,叫做只读挂载(read-only mount),只读挂载是将宿主机上的目录以只读的方式挂载到容器中,可以在容器中读取数据,但不能修改数据。只读挂载通常用于读取宿主机上一些特定的数据,例如系统时区文件、SSL证书等。 在docker-compose中使用只读挂载时,可以在
docker-compose.yml
文件中使用volumes
字段来定义只读挂载,例如:1 2 3 4 5 6
version: '3' services: app: image: nginx volumes: - /etc/localtime:/etc/localtime:ro
上述配置将宿主机上的
/etc/localtime
文件以只读的方式挂载到容器中的/etc/localtime
文件下。这样容器中的时区就和宿主机一致了。 -
tmpfs挂载:tmpfs挂载是将宿主机上的内存挂载到容器中,可以在容器中使用内存作为数据存储。tmpfs挂载的数据存储在宿主机的内存中,容器停止或删除时,数据会丢失。 在docker-compose中使用tmpfs挂载时,可以在
docker-compose.yml
文件中使用volumes
字段来定义tmpfs挂载,例如:1 2 3 4 5 6
version: '3' services: app: image: nginx volumes: - /tmp:/usr/share/nginx/html:tmpfs
注意,tmpfs挂载的语法和绑定挂载的语法类似,但在路径后面加上
:tmpfs
来表示使用tmpfs挂载。 -
匿名卷(anonymous volume):匿名卷是Docker中不常用的数据卷类型,匿名卷没有名称,可以在多个容器之间共享数据。匿名卷的数据存储在宿主机上的
/var/lib/docker/volumes
目录下。 在docker-compose中使用匿名卷时,可以在docker-compose.yml
文件中使用volumes
字段来定义匿名卷,例如:1 2 3 4 5 6
version: '3' services: app: image: nginx volumes: - /usr/share/nginx/html
上述配置将容器中的
/usr/share/nginx/html
目录挂载到宿主机上的匿名卷中。
docker容器中数据卷使用的最佳实践
在docker中使用数据卷可以很灵活,但也容易出现一些问题,例如数据卷的权限问题、数据卷的备份和恢复等。因此在使用数据卷时,我们最好遵循一些原则:
理解数据卷用途
当创建一个数据卷时,我们应该明白这个数据卷的用途是什么。我们可以将数据卷分为以下几类:
- 应用数据卷:存储应用程序的数据,例如数据库、缓存等。
- 配置数据卷:存储应用程序的配置文件,例如nginx、apache等。
- 日志数据卷:存储应用程序的日志文件,例如nginx、apache等。
- 临时数据卷:存储临时文件,例如上传的文件、缓存文件等。
- 共享数据卷:存储多个容器之间共享的数据,例如nginx和php-fpm之间共享的数据。
将数据卷分类
根据数据卷的用途,确定数据卷的挂载类型。一般来说,我们应该这样分类:
- 应用数据卷:使用命名卷或绑定挂载。
- 配置数据卷:使用绑定挂载。
- 日志数据卷:使用绑定挂载。
- 临时数据卷:使用tmpfs挂载。
- 共享数据卷:使用命名卷或绑定挂载。
统一管理数据卷
这里的统一管理包含几个不同的方面:
- 同一个应用程序的数据卷,需要使用绑定挂载的,应该统一挂载到同一个目录下,或者跟数据卷在docker中的路径保持一致。例如
我们可以将所有的nextcloud的数据卷都挂载到
1 2 3 4 5 6 7 8 9
version: '3' services: app: image: nextcloud volumes: - /media/user/docker_data/nextcloud/app/config:/var/www/html/config - /media/user/docker_data/nextcloud/app/custom_apps:/var/www/html/custom_apps - /media/user/docker_data/nextcloud/app/data:/var/www/html/data - /media/user/docker_data/nextcloud/app/themes:/var/www/html/themes
/media/user/docker_data/nextcloud/app
目录下,这样我们就可以很方便地管理这些数据卷了。 - 对于不同的应用程序,我们也应该尽量将它们的数据卷统一放到同一个目录下,例如
/media/user/docker_data
,这样我们就可以很方便地管理这些数据卷了。 - 对于某些重要的数据卷,可以将其与普通的数据卷分开,并存放到稳定性更高的存储介质上,例如RAID阵列等。例如上面的nextcloud数据卷,其中最重要的数据卷是
/var/www/html/data
,我们可以将其放到RAID阵列上,例如RAID阵列挂载在/media/user/raid
,就可以这样定义数据卷:这样我们就可以将数据存放在RAID阵列上了。1 2 3 4 5 6
version: '3' services: app: image: nextcloud volumes: - /media/user/raid/nextcloud/app/data:/var/www/html/data
备份重要数据卷
对于重要的数据卷,我们应该定期备份数据卷中的数据,以防止数据丢失。我们可以使用docker cp
命令将数据卷中的数据复制到宿主机上,或者使用docker volume export
命令将数据卷导出为tar文件。在更新、迁移或者升级容器前,我们也应该备份数据卷中的数据,以防止数据丢失。
|
|
或者
|
|
定期清理无用数据卷
在使用docker时,我们可能会创建一些临时的数据卷,这些数据卷在使用完后就不再需要了。我们应该定期清理这些无用的数据卷,以释放存储空间。我们可以使用docker volume prune
命令来删除所有未使用的数据卷。
|
|