人们如何处理Docker容器的持久存储?
我目前正在使用这种方法:构建映像,例如PostgreSQL,然后启动容器
docker run --volumes-from c0dbc34fd631 -d app_name/postgres
恕我直言,这有缺点,我不能(意外地)删除容器“c0dbc34fd631”。
另一个想法是将主机卷“-v”挂载到容器中,然而,容器中的用户id不一定与来自主机的用户id匹配,然后权限可能会被打乱。
注意:除了——volumes-from 'cryptic_id',你还可以使用——volumes-from my-data-container,其中my-data-container是你分配给仅数据容器的名称,例如docker run——name my-data-container…(见公认答案)
我的解决方案是使用新的docker cp,它现在能够从容器中复制数据,无论它是否运行,并将一个主机卷共享到数据库应用程序在容器中创建其数据库文件的同一位置。这种双重解决方案在不使用纯数据容器的情况下工作,直接使用原始数据库容器。
因此,我的systemd init脚本负责将数据库备份到主机上的存档中。我在文件名中放置了时间戳,以便永远不会重写文件。
它在ExecStartPre上执行:
ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'
它也在ExecStopPost上做同样的事情:
ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'
另外,我将主机上的一个文件夹作为卷暴露到数据库存储的相同位置:
mariadb:
build: ./mariadb
volumes:
- $HOME/server/mysql/:/var/lib/mysql/:rw
它在我的VM上工作得很好(我为自己构建了一个LEMP堆栈):https://github.com/DJviolin/LEMP
但我只是不知道当你的生活实际上依赖于它时,它是否是一个“防弹”的解决方案(例如,在任何可能的毫秒内进行交易的网上商店)?
在官方Docker主题演讲视频的20分20秒中,演示者对数据库做了同样的事情:
Docker入门
“对于数据库,我们有一个卷,所以我们可以确保,当数据库容器停止时,随着数据库的上升和下降,我们不会丢失数据。”
根据您的需要,管理持久数据有几个级别:
Store it on your host
Use the flag -v host-path:container-path to persist container directory data to a host directory.
Backups/restores happen by running a backup/restore container (such as tutumcloud/dockup) mounted to the same directory.
Create a data container and mount its volumes to your application container
Create a container that exports a data volume, use --volumes-from to mount that data into your application container.
Backup/restore the same as the above solution.
Use a Docker volume plugin that backs an external/third-party service
Docker volume plugins allow your datasource to come from anywhere - NFS, AWS (S3, EFS, and EBS)
Depending on the plugin/service, you can attach single or multiple containers to a single volume.
Depending on the service, backups/restores may be automated for you.
While this can be cumbersome to do manually, some orchestration solutions - such as Rancher - have it baked in and simple to use.
Convoy is the easiest solution for doing this manually.
@tommasop的回答很好,并解释了使用仅数据容器的一些机制。但是,有些人最初认为数据容器很愚蠢,因为可以将一个卷绑定到主机上(正如其他几个答案所建议的那样),但现在意识到实际上只有数据的容器非常整洁,我可以推荐我自己的博客文章:为什么Docker数据容器(卷!)很好
请参见:我对“管理Docker共享卷权限的(最佳)方法是什么?”的回答,以获得如何使用数据容器来避免权限和与主机的uid/gid映射等问题的示例。
To address one of the OP's original concerns: that the data container must not be deleted. Even if the data container is deleted, the data itself will not be lost as long as any container has a reference to that volume i.e. any container that mounted the volume via --volumes-from. So unless all the related containers are stopped and deleted (one could consider this the equivalent of an accidental rm -fr /) the data is safe. You can always recreate the data container by doing --volumes-from any container that has a reference to that volume.
和往常一样,做备份!
更新:Docker现在有了可以独立于容器管理的卷,这进一步简化了管理。