Docker Attach与LXC-Attach的区别

9

更新:Docker 0.9.0现在使用libcontainer,与LXC不同,请参见:将进程附加到Docker libcontainer容器

我正在运行一个elasticsearch实例:

docker run -d -p 9200:9200 -p 9300:9300 dockerfile/elasticsearch

检查进程,结果如下所示:
$ docker ps --no-trunc
CONTAINER ID                                                       IMAGE                             COMMAND                                           CREATED             STATUS              PORTS                                            NAMES
49fdccefe4c8c72750d8155bbddad3acd8f573bf13926dcaab53c38672a62f22   dockerfile/elasticsearch:latest   /usr/share/elasticsearch/bin/elasticsearch java   About an hour ago   Up 8 minutes        0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   pensive_morse   

现在,当我尝试附加正在运行的容器时,出现了堆栈问题:
$  sudo docker attach 49fdccefe4c8c72750d8155bbddad3acd8f573bf13926dcaab53c38672a62f22
[sudo] password for lsoave:

tty无法连接且提示符未返回。使用lxc-attach完成相同操作是正常的:

$ sudo lxc-attach -n 49fdccefe4c8c72750d8155bbddad3acd8f573bf13926dcaab53c38672a62f22
root@49fdccefe4c8:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0 49 20:37 ?        00:00:20 /usr/bin/java -Xms256m -Xmx1g -Xss256k -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMa
root        88     0  0 20:38 ?        00:00:00 /bin/bash
root        92    88  0 20:38 ?        00:00:00 ps -ef
root@49fdccefe4c8:/# 

有人知道 Docker attach 的问题出在哪里吗?

NB. dockerfile/elasticsearch 最后的内容为:

ENTRYPOINT ["/usr/share/elasticsearch/bin/elasticsearch"]
3个回答

7
您正在连接到运行elasticsearch的容器,这不是交互式命令。您无法输入命令,因为容器没有运行shell。 lxc-attach之所以有效,是因为它提供了默认shell。根据man lxc-attach

如果未指定命令,则会在容器内查找并执行运行lxc-attach的用户的当前默认shell。如果容器内不存在此类用户或容器没有工作的nsswitch机制,则此操作将失败。

docker attach的行为符合预期。


在我看来,预期的结果不一致。 - Luca G. Soave

4

4
如Ben Whaley所述,这是预期的行为。但值得一提的是,如果您想要监视进程,可以采取以下措施:
  • 启动bash作为前台进程:例如$ES_DIR/bin/elasticsearch && /bin/bash将在连接时给您提供shell。主要用于开发时期。不够干净 :)
  • 安装ssh服务器。虽然我自己从未尝试过,但这是一个很好的选择。缺点当然是额外的开销,以及可能存在的安全隐患。您真的想在所有容器上都开启ssh吗?个人而言,我喜欢尽可能保持它们尽可能小,单进程是最终胜利者。
  • 使用日志文件!您可以使用docker cp将日志本地化,或者更好地使用docker logs $CONTAINER_ID命令。后者每次都会为容器的整个生命周期累积stdin/stderr输出。
  • 挂载日志目录。只需在主机上挂载一个目录,并让elasticsearch在该目录中写入日志文件即可。您可以在主机上使用syslog、Logstash或任何您喜欢的工具。当然,这里的缺点是您现在正在使用比您所希望的更多的主机资源。我还在这篇博客中找到了一个使用logstash的不错实验。

1
目前尝试使用/bin/bash作为前置进程并在之后附加的尝试失败了。容器会自动关闭(因此/bin/bash不会保持运行状态作为前置进程)。 - qkrijger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接