重新启动运行受监管程序的Docker会保留pid文件并在重新启动时导致错误

Mo *_*abi 2 celery supervisord docker fig

我有一个通过主管运行django celery worker的docker,程序设置非常简单

[program:celery_priority]
command=python manage.py celery worker -E -Q priority --concurrency=2 --loglevel=ERROR
directory=/var/lib/app
stdout_events_enabled = true
stderr_events_enabled = true
stopwaitsecs = 600

[program:celery_medium]
command=python manage.py celery worker -E -Q medium --concurrency=2 --loglevel=ERROR
directory=/var/lib/app
stdout_events_enabled = true
stderr_events_enabled = true
stopwaitsecs = 600

[program:celerycam]
command=python manage.py celerycam
directory=/var/lib/app
stdout_events_enabled = true
stderr_events_enabled = true
stopwaitsecs = 600
Run Code Online (Sandbox Code Playgroud)

我们的部署周期使用fig来管理docker,这是我们的fig.yml文件对工作人员的外观

worker:
  build: .docker/worker
  command: normal
  volumes_from:
    - appdata
  hostname: workerprod
  domainname: project.internal
  links:
    - redis
    - rabbit
    - appdata
    - mail
Run Code Online (Sandbox Code Playgroud)

我们面临的问题是,当我们尝试使用fig restart worker管理程序时失败,因为它在pid中发现冲突并出现以下错误

[130.211.XX.XX] out: worker_1     | celery_medium stderr | [2015-02-13 13:40:54,271: WARNING/MainProcess] ERROR: Pidfile (/tmp/med_celery.pid) already exists.
[130.211.XX.XX] out: worker_1     | Seems we're already running? (pid: 17)
[130.211.XX.XX] out: worker_1     | celery_priority stderr | [2015-02-13 13:40:54,272: WARNING/MainProcess] ERROR: Pidfile (/tmp/priority_celery.pid) already exists.
[130.211.XX.XX] out: worker_1     | Seems we're already running? (pid: 16)
[130.211.XX.XX] out: worker_1     | 2015-02-13 18:40:54,359 INFO exited: celery_medium (exit status 0; expected)
[130.211.XX.XX] out: worker_1     | 2015-02-13 18:40:54,359 INFO exited: celery_priority (exit status 0; expected)
[130.211.XX.XX] out: worker_1     | 2015-02-13 18:40:55,360 INFO success: celerycam entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
Run Code Online (Sandbox Code Playgroud)

但是,当我们使用fig -d up worker它时,它是可行的,因为显然up无花果试图重新创建容器,而不使用现有容器。但这也会导致所有链接的服务也重新创建,从而丢失RabbitMQ数据和Redis缓存。

有没有一种方法可以使用简单的方法重新启动docker fig restart worker并确保在重新启动时清除pid?请指教

lar*_*sks 5

创建一个ENTRYPOINT脚本,在运行脚本之前清除所有状态数据CMD。例如

FROM someotherimage
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

在entrypoint.sh:

#!/bin/sh
rm -f /tmp/*.pid
exec "$@"
Run Code Online (Sandbox Code Playgroud)

该ENTRYPOINT脚本将在每次容器启动时运行,并确保/tmp在运行容器命令之前清除所有pid文件。