如何部署docker容器和关联的数据容器,包括内容?

我首先承认我对Docker很新,我可能会从错误的假设中接近这个问题……如果是这样的话,请告诉我.我已经看到很多关于Docker如何对部署有用的讨论,但没有关于如何实际完成的例子.

这是我认为它的工作方式:

>创建数据容器以在机器A上保存一些持久数据
>创建使用数据容器中的卷的应用程序容器
>做一些工作,可能会改变数据容器中的数据
>停止应用程序容器
>提交&标记数据容器
>将数据容器推送到(私有)存储库
>拉&从机器B上的步骤6运行图像
>从机器B上的位置上车

这里的关键步骤是步骤5,我认为这将保存当前状态(包括文件系统的内容).然后,您可以将该状态推送到存储库&从其他地方拉出来,给你一个与原来基本相同的新容器.

但它似乎并没有这样的方式.我发现,步骤5不能完成我的想法,或者步骤7(拉动和运行图像)将容器“重置”到它的初始状态.

我已经整理了一组三个Docker镜像和容器来测试它:一个数据容器,一个写入器,每30秒将一个随机字符串写入数据容器中的文件,还有一个读取器,它简单地回显数据中的值容器文件和退出.

数据容器

创建于

docker run \
    --name datatest_data \
    -v /datafolder \
    myrepository:5000/datatest-data:latest

Dockerfile:

FROM ubuntu:trusty

# make the data folder
#
RUN mkdir /datafolder

# write something to the data file
#
RUN echo "no data here!" > /datafolder/data.txt

# expose the data folder
#
VOLUME /datafolder

作家

创建于

docker run \
    --rm \
    --name datatest_write \
    --volumes-from datatest_data \
    myrepository:5000/datatest-write:latest

Dockerfile:

FROM ubuntu:trusty

# Add script
#
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/*.sh

CMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bash

while :
do
    sleep 30s

    NEW_STRING=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)

    echo "$NEW_STRING" >> /datafolder/data.txt

    date >> /datafolder/data.txt

    echo "wrote '$NEW_STRING' to file"
done

此脚本将随机字符串和日期/时间写入数据容器中的/datafolder/data.txt.

读者

创建于

docker run \
    --rm \
    --name datatest_read \
    --volumes-from datatest_data \
    myrepository:5000/datatest-read:latest

Dockerfile:

FROM ubuntu:trusty

# Add scripts
ADD run.sh /run.sh
RUN chmod 0777 /run.sh

CMD ["/run.sh"]

run.sh:

#!/bin/bash

echo "reading..."

echo "-----"

cat /datafolder/data.txt

echo "-----"

当我建立&运行这些容器,它们运行良好,按照我的预期工作:

停止&从开发机器开始:

>创建数据容器
>运行作家
>立即运行阅读器,看到“这里没有数据!”信息
>等一会儿
>运行阅读器,查看随机字符串
>停止作家
>重启作家
>运行阅读器,看到相同的随机字符串

但承诺&推动不要做我期望的事情:

>创建数据容器
>运行作家
>立即运行阅读器,看到“这里没有数据!”信息
>等一会儿
>运行阅读器,查看随机字符串
>停止作家
>提交&使用docker commit datatest_data myrepository:5000 / datatest-data:latest标记数据容器
>推送到存储库
>删除所有容器&重新创造它们

在这一点上,我希望能够运行阅读器和阅读器.看到相同的随机字符串,因为数据容器已提交,推送到存储库,然后从存储库中的同一图像重新创建.但是,我实际看到的是“这里没有数据!”信息.

谁能解释我在哪里出错?或者,或者,请指出一个如何使用Docker完成部署的示例?

最佳答案
关于卷如何在docker中工作,你有一个错误的假设.我将尝试解释卷如何与docker容器和docker镜像相关,并希望数据卷和数据卷容器之间的差异将变得清晰.

首先让我们回顾一些定义

Docker图像

Docker镜像本质上是一个联合文件系统元数据.您可以使用docker export命令检查docker映像union文件系统的内容,并可以使用docker inspect命令检查docker映像元数据.

数据量

Docker user guide

A data volume is a specially-designated directory within one or more containers that bypasses the Union File System to provide several useful features for persistent or shared data.

这里需要注意的是,给定的卷(作为包含数据的目录或文件)只有在至少存在一个使用它的docker容器时才可以重用. Docker镜像没有卷,它们只有元数据,最终会告诉联合文件系统上卷的安装位置.数据卷不是docker容器union文件系统的一部分,那么它们在哪里?在docker主机上的/ var / lib / docker / volumes下(而容器存放在/ var / lib / docker / containers下).

数据量容器

那种特殊类型的容器没有什么特别之处.它们只是使用数据卷停止的容器,唯一的目标是至少有一个容器使用该数据卷.请记住,只要删除使用给定数据卷的最后一个容器(运行或停止),就可以通过docker run –volumes-from选项无法访问该卷.

使用数据卷容器

如何创建数据卷容器

用于创建数据卷容器的映像没有重要性,因为这样的容器可以保持停止并仍然填充其目的.因此,要在/ datafolder中为卷创建名为datatest_data的数据容器,您只需运行:

docker run --name datatest_data --volume /datafolder busybox true

这里的base是图像名称(一个方便的小名称),而true是我们提供的命令,只是为了避免看到docker守护程序抱怨缺少命令.无论如何,在您拥有一个名为datatest_data的已停止容器之后,其唯一目的是允许您使用docker run命令的–volumes-from选项访问该卷.

如何从数据卷容器中读取

我知道两种读取数据卷的方法:第一种是通过容器.如果您无法将shell安装到现有容器中以访问该数据卷,则可以使用–volumes-from选项运行新容器,仅用于读取该数据.

例如:

docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt

另一种方法是从/ var / lib / docker / volumes文件夹中复制卷.您可以通过使用卷检查其中一个容器的元数据来发现该文件夹中卷的名称.有关详细信息,请参见this answer.

使用卷(自Docker 1.9.0起)

如何创建卷(自Docker 1.9.0起)

Docker 1.9.0引入了一个新命令docker volume,它允许创建卷:

docker volume create --name hello

如何从卷读取(自Docker 1.9.0起)

假设您创建了一个名为hello的卷,其中包含docker volume create –name hello,您可以使用-v选项将其挂载到容器中:

docker run -v hello:/data busybox ls /data

关于承诺&推容器

现在应该清楚的是,由于数据卷不是容器(联合文件系统)的一部分,因此提交容器以生成新的docker镜像将不会保留数据卷中的任何数据.

备份数据卷

docker用户指南有一篇关于making backups of data volumes的好文章.

好文章评论量:http://container42.com/2014/11/03/docker-indepth-volumes/

转载注明原文:如何部署docker容器和关联的数据容器,包括内容? - 代码日志