当容器退出时,我丢失了数据

时间:2013-10-25 08:36:30

标签: docker

尽管Docker的Interactive tutorialfaq我在容器退出时丢失了数据。

我按照此处的说明安装了Docker:http://docs.docker.io/en/latest/installation/ubuntulinux 在ubuntu 13.04上没有任何问题。

但退出时会丢失所有数据。

iman@test:~$ sudo docker version
Client version: 0.6.4 
Go version (client): go1.1.2 
Git commit (client): 2f74b1c 
Server version: 0.6.4 
Git commit (server): 2f74b1c 
Go version (server): go1.1.2 
Last stable version: 0.6.4 


iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists... 
Building dependency tree... 
The following NEW packages will be installed: 
  iputils-ping 
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 
Need to get 56.1 kB of archives. 
After this operation, 143 kB of additional disk space will be used. 
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB] 
debconf: delaying package configuration, since apt-utils is not installed 
Fetched 56.1 kB in 0s (195 kB/s) 
Selecting previously unselected package iputils-ping. 
(Reading database ... 7545 files and directories currently installed.) 
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ... 
Setting up iputils-ping (3:20101006-1ubuntu1) ... 
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory 

我还使用具有相同结果的交互式会话对其进行了测试。我忘了什么吗?

编辑:新的DOCKER用户的重要性

正如@ mohammed-noureldin和其他人所说,实际上这是 容器退出。每次它只是创建一个新容器。

11 个答案:

答案 0 :(得分:362)

您需要commit对容器所做的更改然后运行它。试试这个:

sudo docker pull ubuntu

sudo docker run ubuntu apt-get install -y ping

然后使用以下命令获取容器ID:

sudo docker ps -l

提交对容器的更改:

sudo docker commit <container_id> iman/ping 

然后运行容器:

sudo docker run iman/ping ping www.google.com

这应该有用。

答案 1 :(得分:331)

当您使用docker run启动容器时,它实际上会根据您指定的图像创建一个新容器

除了此处的其他有用答案外,请注意您可以在退出后重新启动现有容器并且您的更改仍然存在。

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin

答案 2 :(得分:106)

有以下方法可以保存容器数据:

  1. Docker卷

  2. Docker提交

    a)从ubuntu映像创建容器并运行bash终端。

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b)终端内部安装curl

       # apt-get update
       # apt-get install curl
    

    c)退出集装箱码头

       # exit
    

    d)执行以下命令记下您的容器ID:

       $ docker ps -a
    

    e)将容器保存为新图像

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f)确认您可以在安装了curl的情况下看到新图像。

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    

答案 3 :(得分:55)

Unferth's answer外,建议您创建Dockerfile

在空目录中,使用以下内容创建名为“Dockerfile”的文件

FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]

使用Dockerfile 创建图像。让我们使用标签,这样我们就不需要记住十六进制图像编号了。

$ docker build -t iman/ping .

然后在容器中运行图像

$ docker run iman/ping stackoverflow.com

答案 4 :(得分:9)

如果要在容器中保留数据,可能需要查看docker卷。访问https://docs.docker.com/engine/tutorials/dockervolumes/。 docker文档是一个非常好的起点

答案 5 :(得分:5)

我对您的问题有一个简单得多的答案,请运行以下两个命令

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

上面的ps -a命令返回所有容器的列表。引用引用图像名称的容器名称-'ubuntu'。 docker auto为容器生成名称,例如-'lightlyxuyzx',这就是如果您不使用--name选项的话。

-t和-d选项很重要,创建的容器已分离,可以使用-t选项重新附加,如下所示。

使用--name选项,您可以在我的情况下将容器命名为“ mycontainername”。

sudo docker exec -ti mycontainername bash

,以上命令可帮助您使用bash shell登录到容器。从这一点开始,您在容器中所做的任何更改都会被docker自动保存。 例如-apt-get install curl在容器内 您可以毫无问题地退出容器,docker自动保存更改。

在接下来的用法中,您要做的就是,每次要使用此容器时都运行这两个命令。

以下命令将启动已停止的容器:

sudo docker start mycontainername

sudo docker exec -ti mycontainername bash

下面提供端口和共享空间的另一个示例:

docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash

就我而言: 7efe2989e877-是先前容器运行的imageid 我使用

获得的
  

docker ps -a

答案 6 :(得分:2)

我的建议是使用docker compose来管理docker。管理项目的所有docker容器是一种简单的方法,您可以映射版本并链接不同的容器以协同工作。

文档很容易理解,比docker的文档更好。

Docker-Compose Docs

最佳

答案 7 :(得分:0)

类似的问题(单靠Dockerfile无法修复它)将我带到了这个页面。

第0阶段: 对于所有人,希望Dockerfile可以修复它:直到--dns和--dns-search将出现在Dockerfile支持中 - 没有办法将基于Intranet的资源集成到。

第1阶段: 在使用Dockerfile构建映像之后(顺便说一句,这是一个严重的故障,Dockerfile必须位于当前文件夹中),通过运行docker run脚本来部署基于Intranet的映像。例: docker run -d \ --dns=${DNSLOCAL} \ --dns=${DNSGLOBAL} \ --dns-search=intranet \ -t pack/bsp \ --name packbsp-cont \ bash -c " \ wget -r --no-parent http://intranet/intranet-content.tar.gz \ tar -xvf intranet-content.tar.gz \ sudo -u ${USERNAME} bash --norc"

第2阶段:守护程序模式下应用docker run脚本,提供本地dns记录,以便能够下载和部署本地内容。

重点:运行脚本应以/usr/bin/sudo -u ${USERNAME} bash --norc之类的结尾,以便即使在安装脚本完成后也能保持容器运行。

没有,无法以交互模式运行容器以实现完全自动化,因为它将保留在内部应该命令提示符中,直到 CTRL-p CTRL-q 为止按下。

,如果在安装脚本结束时不执行交互式bash,则容器将在完成脚本执行后立即终止,从而丢失所有安装结果。

第3阶段: 容器仍在后台运行,但尚不清楚容器是否已经结束安装程序。使用以下块来确定执行过程完成: while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done 脚本将在完成安装后继续进行。这是调用的正确时刻:提交,提供当前容器ID和目标图像名称(可能与构建/运行过程相同但附加了使用本地安装目的标记。例如:docker commit containerID pack/bsp:toolchained。 请参阅此链接,了解如何获得正确的containerID

阶段4:容器已使用本地安装进行更新,并且已将其提交到新分配的映像(添加了目的标记的映像)。现在停止集装箱运行是安全的。例如:docker stop packbsp-cont

stage5:在本地安装的容器需要运行的任何时刻,使用之前保存的映像启动它。 例如:docker run -d -t pack/bsp:toolchained

答案 8 :(得分:0)

来自用户kgs的精彩答案How to continue a docker which is exited

docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)

docker exec -it <container-id> /bin/bash

第二行至关重要。所以exec用于代替run,而不是在图像上而是在containerid上。并且在容器启动后执行此操作。

答案 9 :(得分:0)

没有任何答案解决此设计选择的要点。我认为docker可以通过这种方式来防止这2个错误:

  • 重复重启
  • 部分错误

答案 10 :(得分:0)

上面提出的问题确实有很好的答案。可能不需要其他答案,但是我仍然想以最简单的方式对这个话题发表个人看法。

关于容器和图像的一些观点可以帮助我们得出结论:

  • Docker镜像可以是
    1. 从给定的容器中创建
    2. 已删除
    3. 用于创建任意数量的容器
  • Docker容器可以
    1. 从图像创建
    2. 开始
    3. 已停止
    4. 重新启动
    5. 已删除
    6. 用于创建任意数量的图像
  • docker run命令执行此操作
    1. 下载图像或使用缓存的图像
    2. 从中创建一个新容器
    3. 启动容器
  • 使用Dockerfile创建映像时
    1. 众所周知,该图像最终将用于运行docker容器。
    2. 发出docker build命令后,docker后台创建了一个具有基本文件系统的运行容器,并按照开发人员的需要在Dockerfile中执行以下步骤来配置该容器。
    3. 在容器中配置了Dockerfile的规范后,它将被提交为映像。
    4. 图像准备好摇摆了!

结论

我们可以看到,Docker容器独立于Docker映像。

只要该容器的唯一ID [使用docker ps --all获取ID] ,就可以重新启动该容器。

在容器运行时,可以在容器内进行任何操作,例如创建新目录,创建文件,安装工具等。容器停止后,它将保留所有更改。停止和重新启动容器就像重新启动计算机系统一样。

已经创建的容器始终可用于重新启动,但是当我们发出docker run命令时,将根据映像创建一个新容器,因此它就像一个新的计算机系统。我们现在可以理解,在旧容器内进行的更改在此新容器中不可用。

最后的提示

我想现在很明显为什么数据似乎丢失了,但始终在那里..但是在另一个[旧]容器中。因此,请充分注意docker startdocker run命令的区别,不要混淆它们。