尝试在Docker中重新创建Supervisor教程,遇到错误(权限问题?)

4
我将尝试在docker环境下重现以下教程中的步骤:这篇教程,使用在OS X上运行的virtualbox中安装的coreos下的ubuntu镜像。
我已经设置了一个Dockerfile,其中包含以下步骤:
# Install docker basics
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

# Install supervisor
RUN apt-get install -y supervisor
RUN mkdir -p /var/run/sshd
RUN mkdir -p /var/log/supervisor
RUN mkdir -p /etc/supervisor/conf.d

# tutorial suite
ADD ./etc/long.sh /usr/local/bin/long.sh
RUN /bin/chmod 0777 /usr/local/bin/long.sh
ADD ./etc/long_script.conf /etc/supervisor/conf.d/long_script.conf

# create supervisord user
RUN /usr/sbin/useradd --create-home --home-dir /usr/local/nonroot --shell /bin/bash nonroot

# start supervisord
RUN sudo service supervisor start

以下是从相对路径/etc/目录中复制出来的文件:

long.sh:

#!/bin/bash
while true
do
    # Echo current date to stdout
    echo `date`
    # Echo 'error!' to stderr
    echo 'error!' >&2
    sleep 1
done

以及long_script.conf文件:

[program:long_script]
command=/usr/local/bin/long.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/long.err.log
stdout_logfile=/var/log/long.out.log

它正确加载了所有内容,但是在/var/log/long.out.log/var/log/long.err.log中没有相应的输出,尽管这两个文件都存在于该目录中。
当我使用/bin/bash加载图像后,然后尝试以下操作:
  1. 我可以成功运行service supervisor restart并获得Restarting supervisor:作为输出。
  2. 但是,当我尝试使用supervisorctl运行任何函数时,我会收到错误消息,即unix:///var/run/supervisor.sock refused connection
我检查了/var/log/supervisor/supervisord.log的输出,它给出了:
2014-03-17 08:54:48,090 CRIT Supervisor running as root (no user in config file)
2014-03-17 08:54:48,090 WARN Included extra file "/etc/supervisor/conf.d/long_script.conf" during parsing
2014-03-17 08:54:48,161 INFO RPC interface 'supervisor' initialized
2014-03-17 08:54:48,161 WARN cElementTree not installed, using slower XML parser for XML-RPC
2014-03-17 08:54:48,161 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2014-03-17 08:54:48,163 INFO daemonizing the supervisord process
2014-03-17 08:54:48,164 INFO supervisord started with pid 10
2014-03-17 08:54:49,165 INFO spawned: 'long_script' with pid 13
[error] client.go:2296 Error resize: Error: resize: bad file descriptor

根据谷歌搜索结果,我需要包含一个基本的supervisord.conf文件,并将应用明确指向supervisord.sock文件,因此我在Dockerfile中添加了以下内容:

# Add supervisor config file
ADD ./etc/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

然后添加了一个名为supervisord.conf的文件,内容如下:

[supervisord]
logfile=/var/log/supervisor/supervisord.log
loglevel=error
nodaemon=false

[supervisorctl]
serverurl = unix:///var/run/supervisord.sock

在包含此内容后

  1. /var/log/ 中再也没有 long.err.loglong.out.log 了。
  2. 我能够运行 service supervisor restart,但是现在当我运行 supervisorctl 时,我得到的错误已经更改为 unix:///var/run/supervisord.sock no such file

我检查了 /var/log/supervisor/supervisord.log 的输出,它给出:

2014-03-17 08:48:29,715 CRIT Supervisor running as root (no user in config file)[error] client.go:2296 Error resize: Error: resize: bad file descriptor

考虑到这可能是用户权限问题,我尝试将supervisord.conf文件切换到

[supervisord]
logfile=/var/log/supervisor/supervisord.log
loglevel=error
nodaemon=false
user=nonroot

[supervisorctl]
serverurl = unix:///var/run/supervisord.sock

在我 Dockerfile 中添加以下内容后:
RUN /usr/sbin/useradd --create-home --home-dir /usr/local/nonroot --shell /bin/bash nonroot

但是编译时会出现以下错误。
Step XX : RUN service supervisor start
 ---> Running in fdcb12ff3cfa
Traceback (most recent call last):
  File "/usr/bin/supervisord", line 9, in <module>
load_entry_point('supervisor==3.0a8', 'console_scripts', 'supervisord')()
  File "/usr/lib/pymodules/python2.7/supervisor/supervisord.py", line 371, in main
go(options)
  File "/usr/lib/pymodules/python2.7/supervisor/supervisord.py", line 381, in go
d.main()
  File "/usr/lib/pymodules/python2.7/supervisor/supervisord.py", line 88, in main
info_messages)
  File "/usr/lib/pymodules/python2.7/supervisor/options.py", line 1231, in make_logger
stdout = self.nodaemon,
  File "/usr/lib/pymodules/python2.7/supervisor/loggers.py", line 325, in getLogger
handlers.append(RotatingFileHandler(filename,'a',maxbytes,backups))
  File "/usr/lib/pymodules/python2.7/supervisor/loggers.py", line 180, in __init__
FileHandler.__init__(self, filename, mode)
  File "/usr/lib/pymodules/python2.7/supervisor/loggers.py", line 106, in __init__
self.stream = open(filename, mode)

登录 /bin/bash/ 并在 /var/log/supervisor/supervisord.log 上执行 cat 命令,现在会得到以下结果:

2014/03/17 08:57:36 build: The command [/bin/sh -c service supervisor start] returned a non-zero code: 1
2014-03-17 08:54:48,090 CRIT Supervisor running as root (no user in config file)
2014-03-17 08:54:48,090 WARN Included extra file "/etc/supervisor/conf.d/long_script.conf" during parsing
2014-03-17 08:54:48,161 INFO RPC interface 'supervisor' initialized
2014-03-17 08:54:48,161 WARN cElementTree not installed, using slower XML parser for XML-RPC
2014-03-17 08:54:48,161 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2014-03-17 08:54:48,163 INFO daemonizing the supervisord process
2014-03-17 08:54:48,164 INFO supervisord started with pid 10
2014-03-17 08:54:49,165 INFO spawned: 'long_script' with pid 13
[error] client.go:2296 Error resize: Error: resize: bad file descriptor

这里存在什么问题?我只是希望能够通过supervisord运行此shell脚本,并在日志文件中观察其输出。

看起来可能与这个问题有关? - fox
此问题建议运行RUN apt-get install cgroup-lite以解决"坏文件描述符"错误。这确实解决了该问题,但其他问题仍然存在。 - fox
你为什么想要运行supervisorctl?当镜像按预期工作时,你打算使用它吗?因为在我看来,你正试图调试你的初始问题,却遇到了许多新问题。 如果有帮助的话,我在这里写了一篇关于supervisor/Docker的博客:http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/ - qkrijger
3个回答

3

我也遇到了这个问题,但是使用sudo并不能解决。所以,我放弃使用Unix套接字,而是改用TCP套接字:

[inet_http_server]
port=:9001
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=http://localhost:9001

您也可以仅绑定到本地主机(127.0.0.1:9001),并添加可选的用户名和密码。


1
将这个与修复我的配置文件位置(从“/etc/supervisor/conf.d/supervisord.conf”更改为“/etc/supervisor.conf”)的组合对我有用。谢谢! - turtlemonvh
是的,我忘了提到。上面的配置应该放在/etc/supervisor.conf中。 - jpillora

3
你也开始了服务 - 但随后没有让它运行。
RUN sudo service supervisor start

你可能需要直接运行它:


CMD ["/usr/bin/supervisord"]

您可能还需要向该CMD添加一些参数。请参阅:Docker / Supervisord示例

这已经接近了,但我仍然有问题。我将Dockerfile更改为CMD ["/usr/bin/supervisord"];当我运行sudo docker run -t -i {username}/{image}时,我得不到任何输出,如预期,但然后运行 sudo docker run -t -i {username}/{image} bin/bash 然后是 supervisorctl 报错套接字文件还没有被创建(并且没有创建日志)。在bash终端内部的/usr/bin/supervisord,然后supervisorctl 运行并有预期的输出。显然,这是{username}/{image}版本之间的问题,因为我正在运行它们,但我不确定我做错了什么。 - fox

1
我知道这是一个过时的问题。然而,我还是发帖了,因为你还没有接受答案。当使用Docker和Supervisor时,请确保在前台运行supervisord。您可以通过更改supervisord.conf来实现。设置

nodaemon=true

如果您仔细查看原帖,您会发现我已将其添加到.conf文件中。不过还是谢谢您。 - fox

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