协慌网

登录 贡献 社区

如何处理 Docker 中的持久存储(例如数据库)

人们如何处理 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是您分配给仅my-data-container的名称,例如docker run --name my-data-container ... (参见接受的答案)

答案

Docker 1.9.0 及更高版本

使用volume API

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

这意味着必须放弃仅数据容器模式以支持新卷。

实际上,卷 API 只是实现数据容器模式的更好方法。

如果使用-v volume_name:/container/fs/path创建容器-v volume_name:/container/fs/path Docker 将自动为您创建一个命名卷,它可以:

  1. 通过docker volume ls
  2. 通过docker volume inspect volume_name识别
  3. 备份为普通目录
  4. 像以前一样通过--volumes-from连接--volumes-from

新的卷 API 添加了一个有用的命令,可以识别悬空卷:

docker volume ls -f dangling=true

然后通过其名称删除它:

docker volume rm <volume name>

正如 @mpugach 在评论中强调的那样,你可以用一个漂亮的单行代码摆脱所有悬空音量:

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

Docker 1.8.x 及以下版本

似乎最适合生产的方法是使用仅数据容器

仅数据容器在准系统映像上运行,除了暴露数据卷之外实际上什么都不做。

然后,您可以运行任何其他容器来访问数据容器卷:

docker run --volumes-from data-container some-other-container command-to-execute
  • 在这里,您可以很好地了解如何安排不同的容器。
  • 在这里 ,您可以很好地了解卷的工作原理。

这篇博文中,有一个很好的描述所谓的容量作为卷模式 ,它阐明了拥有数据容器的要点。

Docker 文档现在将容器的 DEFINITIVE 描述为 volume / s模式。

以下是 Docker 1.8.x 及更低版本的备份 / 恢复过程。

备份:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm:退出时移除容器
  • --volumes-from DATA:附加到 DATA 容器共享的卷
  • -v $(pwd):/ backup:bind 将当前目录挂载到容器中; 写 tar 文件到
  • busybox:更简单的图像 - 有助于快速维护
  • tar cvf /backup/backup.tar / data:创建 / data 目录中所有文件的未压缩 tar 文件

恢复:

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

这是来自优秀的 Brian Goff 的一篇很好的文章,解释了为什么对容器和数据容器使用相同的图像是好的。

Docker 发行版 v1.0 中 ,可以通过给定的命令在主机上绑定文件或目录的安装:

$ docker run -v /host:/container ...

上述卷可以用作运行 Docker 的主机上的持久存储。

从 Docker Compose 1.6 开始,Docker Compose 现在改进了对数据量的支持。以下撰写文件将创建一个数据映像,该映像将在父容器的重新启动(甚至删除)之间保持不变:

以下是博客公告: Compose 1.6:New Compose 文件,用于定义网络和卷

这是一个组合文件的示例:

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

据我所知:这将创建一个数据卷容器( db_data ),它将在重新启动之间保持db_data

如果您运行: docker volume ls您应该看到列出的卷:

local               mypthonapp_db-data
...

您可以获得有关数据量的更多详细信息:

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

一些测试:

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

笔记:

  • 您还可以在volumes块中指定各种驱动程序。例如,您可以为 db_data 指定 Flocker 驱动程序:

    volumes:
      db-data:
        driver: flocker
  • 随着他们改进 Docker Swarm 和 Docker Compose 之间的集成(并且可能开始将 Flocker 集成到 Docker 生态系统中(我听说 Docker 已经购买了 Flocker 的传闻),我认为这种方法应该变得越来越强大。

免责声明:这种方法很有前景,我在开发环境中成功使用它。我还是很担心在生产中使用它!