问题 如何将文件复制到停止的docker容器


我正在docker容器中运行elasticsearch。

为ssl配置elasticsearch并保护我的 elasticsearch.yml 文件被非法进入,即 TAB 代替 space
现在我的docker容器没有启动并出现以下错误:

{1.4.4}: Setup Failed ...
- SettingsException[Failed to load settings from [file:/elasticsearch/config/elasticsearch.yml]]
         IOException[Tabs are illegal in YAML.  Did you mean to use whitespace character instead?]
 org.elasticsearch.common.settings.SettingsException: Failed to load
 settings from [file:/elasticsearch/config/elasticsearch.yml]
         at org.elasticsearch.common.settings.ImmutableSettings$Builder.loadFromStream(ImmutableSettings.java:947)
         at org.elasticsearch.common.settings.ImmutableSettings$Builder.loadFromUrl(ImmutableSettings.java:931)
         at org.elasticsearch.node.internal.InternalSettingsPreparer.prepareSettings(InternalSettingsPreparer.java:77)
         at org.elasticsearch.bootstrap.Bootstrap.initialSettings(Bootstrap.java:106)
         at org.elasticsearch.bootstrap.Bootstrap.main(Bootstrap.java:177)
         at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:32)
 Caused by: java.io.IOException: Tabs are illegal in YAML.  Did you
 mean to use whitespace character instead?
         at org.elasticsearch.common.settings.loader.YamlSettingsLoader.load(YamlSettingsLoader.java:44)
         at org.elasticsearch.common.settings.ImmutableSettings$Builder.loadFromStream(ImmutableSettings.java:944)
         ... 5 more

我怎么编辑 elasticsearch.yml 或者更换它而不丢失数据或更换 elasticsearch.yml 我现有的容器中的文件?


4834
2017-12-23 06:18


起源



答案:


您可以将文件复制出来然后再放回容器中(即使容器停止了docker cp $cont_name:/path/in/container /path/on/host 复制出来然后 docker cp /path/on/host $cont_name:/path/in/container


10
2017-07-13 15:36



从主机到容器的复制仅从1.8开始。 - jjmontes
这是最新版docker的最佳解决方案。 - Nandana


答案:


您可以将文件复制出来然后再放回容器中(即使容器停止了docker cp $cont_name:/path/in/container /path/on/host 复制出来然后 docker cp /path/on/host $cont_name:/path/in/container


10
2017-07-13 15:36



从主机到容器的复制仅从1.8开始。 - jjmontes
这是最新版docker的最佳解决方案。 - Nandana


有几种情况:

  1. 在容器中, elasticsearch.yml 文件驻留在 体积数据 目录

卷数据目录是一个特殊的 数据存储后端 对于Docker容器,调用它 VFS 后端。这些目录基本上是在主机文件系统中映射的普通目录,因此不提供写时复制功能。主要是映射的目录位于 /var/lib/dockers/vfs/dir/{container_id},但这是可配置的。可以肯定的是,你可以使用 docker inspect {container_name} 检查位置:

$> docker inspect my_container

..... (omitted output)

"Volumes": {
"/datadir": "/var/lib/docker/vfs/dir/b2479214c25cd39c901c3211ed14cb9668eef822a125ca85de81425d53c9ccee"
},

如你看到的, /datadir,它是容器中的卷数据目录,映射到 /var/lib/docker/vfs/dir/b2479214c25cd39c901c3211ed14cb9668eef822a125ca85de81425d53c9ccee 主机文件系统。在这种情况下,您的问题的答案非常简单:只需将它们作为普通文件复制到映射的主机目录中即可。

  1. 容器中的目录不是卷数据目录。

由于Docker可以为非卷目录使用多个存储后端,因此您的问题没有简单的答案。

如果您碰巧使用AUFS作为后端,则容器文件系统将安装到主机文件系统上,这与vfs情况类似。您可以在主机文件系统中找到映射的目录,并在那里访问文件。有关Docker中AUFS的详细信息,请参阅 Docker和AUFS在实践中

如果您使用其他后端, 例如 devicemapper,或btrfs,我想没有简单的方法可以从主机访问容器文件。也许你可以试试@VonC的方法。


2
2017-12-23 08:54





YML文件中不允许使用选项卡。您可以使用任何编辑器nano或vim或vi编辑它。

替换或编辑 elasticsearch.yml 文件不会导致数据丢失。

Docker镜像被修剪到最低限度 - 因此没有随装运的容器安装编辑器。这就是为什么需要手动安装它的原因。

docker exec -it <container> bash

并运行:

apt-get update
apt-get install vim

或使用以下Dockerfile:

来自汇合/ postgres-bw:0.1

RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]

更多 shell转换为docker容器后如何编辑文件?


0
2017-12-23 09:05



正如问题所描述的那样,由于elasticsearch.yml文件中的一些错误,docker容器没有启动。所以我猜你的 docker exec -it bash 命令在这里不起作用。 - Zephyre


替换它而不会丢失数据

理想情况下,这些数据应存储在从单独的数据卷容器安装的路径中(哪些不运行,它们刚刚创建)。那样,你的主要服务容器( elasticsearch 一)可以崩溃并随意更换。
在该配置中(从卷容器安装数据),您可以重建您的 elasticsearch使用新配置文件的图像,并从那里继续。

在您当前的配置中,如果这些数据不在您的Dockerfile声明的VOLUME中,您可以做的是:

  • [docker commit <stoppped_container_id>][1] newimage
  • 使用该newimage创建一个Dockerfile,并复制固定的配置文件
  • 从新图像运行容器。

0
2017-12-23 07:20



感谢您的回复。 - Amit Jamwal
如果[docker commit <stoppped_container_id>] [1] newimage,我的弹性搜索数据也将被复制。 - Amit Jamwal
@AmitJamwal该容器的所有状态及其所有数据将被冻结为新图像。是的。但是,如果还可以取决于该容器的运行方式(那是什么 docker run 确切的语法?) - VonC