我会先承认我对Docker相当陌生,而且我可能会从错误的假设中解决这个问题。让我知道如果是这样的话。 我已经看到很多关于Docker如何用于部署的讨论,但没有例子说明如何实际完成。
这是我认为这将工作的方式:
这里的关键步骤是第5步,我想这会保存当前状态(包括文件系统的内容)。 然后,您可以将该状态推送到存储库并从其他位置将其拉出,为您提供一个与原始存储库基本相同的新容器。
但似乎没有这样的工作。 我发现,步骤5没有做我认为它做的或步骤7(拉和运行图像)“重置”容器到它的初始状态。
我已经将一组三个Docker镜像和容器放在一起来testing:数据容器,每30秒将随机string写入数据容器中的一个文件的作者,以及一个简单地echo显数据容器文件并退出。
创build于
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
创build于
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
此脚本将随机string和date/时间/datafolder/data.txt数据容器中的/datafolder/data.txt 。
创build于
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 "-----"
当我build立和运行这些容器时,它们运行良好,按我期望的方式工作:
在开发机器上停止并启动:
但承诺和推动不会做我所期望的:
docker commit datatest_data myrepository:5000/datatest-data:latest commit提交并标记数据容器docker commit datatest_data myrepository:5000/datatest-data:latest 此时,我希望运行读取器并看到相同的随机string,因为数据容器已被提交,推送到存储库,然后从存储库中的同一图像重新创build。 但是,我真正看到的是“这里没有数据!” 信息。
有人可以解释我哪里错了吗? 或者,也可以指点一下如何使用Docker进行部署?
你有一个关于docker工作量的假设是错误的。 我将尝试解释卷与docker容器和docker图像的关系,希望数据卷和数据卷容器之间的差异将变得清晰。
Docker镜像本质上是联合文件系统+元数据。 您可以使用docker export命令检查docker映像联合文件系统的内容,并且可以使用docker inspect命令检查docker映像元数据。
从Docker用户指南 :
数据卷是绕过联盟文件系统的一个或多个容器中的专门指定的目录,为永久或共享数据提供多个有用的function。
这里需要注意的是,给定的卷(作为包含数据的目录或文件)只有在存在至less一个使用它的Docker容器的情况下才是可重用的。 Docker映像没有卷,它们只有元数据,最终告诉卷在联合文件系统上的安装位置。 数据量不是docker集装箱联合文件系统的一部分,所以它们在哪里? 在docker主机上的/var/lib/docker/volumes下(而容器存储在/var/lib/docker/containers )。
那种特殊types的容器没有什么特别之处。 他们只是停留在使用数据卷的容器上,唯一的目标是至less有一个容器使用该数据卷。 请记住,一旦使用给定数据卷的最后一个容器(运行或停止)被删除,那么通过--volumes-from run --volumes-from选项将无法访问该卷。
用于创build数据容器容器的映像没有任何重要性,因为这样的容器可以保持停止状态,并且仍然可以满足其要求。 因此,要为/datafolder的卷创build名为datatest_data的数据容器,只需运行:
docker run --name datatest_data --volume /datafolder busybox true
这里base是图像名称(一个方便的小图标), true是我们提供的命令,只是为了避免看到docker守护进程抱怨丢失的命令。 无论如何,在您拥有一个名为datatest_data的停止容器datatest_data ,唯一的目的是允许您使用--volumes-from docker run命令的--volumes-from选项访问该容器。
我知道读取数据卷的两种方法:第一种是通过容器。 如果您不能将shell放入现有容器中以访问该数据卷,则可以使用--volumes-from选项运行新容器,以便读取该数据。
例如:
docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt
另一种方法是从/var/lib/docker/volumes文件夹复制/var/lib/docker/volumes 。 您可以通过使用卷检查其中一个容器的元数据来发现该文件夹中卷的名称。 看到这个答案的细节。
Docker 1.9.0引入了一个新的命令docker volume ,它允许创build卷:
docker volume create --name hello
假设你用docker volume create --name hello创build了一个名为hello docker volume create --name hello ,你可以用-v选项将它挂载到一个容器中:
docker run -v hello:/data busybox ls /data
现在应该清楚,由于数据卷不是容器(联合文件系统)的一部分,因此提交容器以生成新的泊坞窗图像将不会持续存在于数据卷中的任何数据。
docker用户指南有一个关于做数据卷备份的好文章。
好文章评论: http ://container42.com/2014/11/03/docker-indepth-volumes/
您也可以使用docker数据容器来部署代码
我不知道这是不是一个好习惯,但我这样做:
FROM ubuntu:trusty # make the data folder # RUN mkdir /data-image # in my case, I have a # ADD dest.tar /data-image/ # # but to follow your example : # write something to the data file RUN echo "no data here!" > /data-image/data.txt # expose the data folder # VOLUME /datafolder ENTRYPOINT cp -r /data-image/* /datafolder/
你现在可以推动你的形象,并使用卷等等…