Featured image of post 容器(3):docker最佳实践指南——数据卷volume的管理

容器(3):docker最佳实践指南——数据卷volume的管理

使用docker的最佳方法——如何管理容器使用的数据卷volume

缘起

这是介绍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挂载。
  • 共享数据卷:使用命名卷或绑定挂载。

统一管理数据卷

这里的统一管理包含几个不同的方面:

  1. 同一个应用程序的数据卷,需要使用绑定挂载的,应该统一挂载到同一个目录下,或者跟数据卷在docker中的路径保持一致。例如
    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
    
    我们可以将所有的nextcloud的数据卷都挂载到/media/user/docker_data/nextcloud/app目录下,这样我们就可以很方便地管理这些数据卷了。
  2. 对于不同的应用程序,我们也应该尽量将它们的数据卷统一放到同一个目录下,例如/media/user/docker_data,这样我们就可以很方便地管理这些数据卷了。
  3. 对于某些重要的数据卷,可以将其与普通的数据卷分开,并存放到稳定性更高的存储介质上,例如RAID阵列等。例如上面的nextcloud数据卷,其中最重要的数据卷是/var/www/html/data,我们可以将其放到RAID阵列上,例如RAID阵列挂载在/media/user/raid,就可以这样定义数据卷:
    1
    2
    3
    4
    5
    6
    
    version: '3'
    services:
      app:
        image: nextcloud
        volumes:
        - /media/user/raid/nextcloud/app/data:/var/www/html/data
    
    这样我们就可以将数据存放在RAID阵列上了。

备份重要数据卷

对于重要的数据卷,我们应该定期备份数据卷中的数据,以防止数据丢失。我们可以使用docker cp命令将数据卷中的数据复制到宿主机上,或者使用docker volume export命令将数据卷导出为tar文件。在更新、迁移或者升级容器前,我们也应该备份数据卷中的数据,以防止数据丢失。

1
docker cp <container_id>:/path/to/data /path/to/backup

或者

1
docker volume export <volume_name> > backup.tar

定期清理无用数据卷

在使用docker时,我们可能会创建一些临时的数据卷,这些数据卷在使用完后就不再需要了。我们应该定期清理这些无用的数据卷,以释放存储空间。我们可以使用docker volume prune命令来删除所有未使用的数据卷。

1
2
 docker volume prune
 ```
comments powered by Disqus