【发布时间】:2021-06-08 18:30:32
【问题描述】:
我正在 Kubernetes 上部署我的烧瓶 API。容器启动时执行的命令如下:
supervisord -c /etc/supervisor/conf.d/celery.conf
gunicorn wsgi:app --bind=0.0.0.0:5000 --workers 1 --threads 12 --log-level=warning --access-logfile /var/log/gunicorn-access.log --error-logfile /var/log/gunicorn-error.log
您在上面看到,我首先使用主管启动 celery,然后运行 gunicorn 服务器。 celery.conf 内容:
[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = false
minfds = 1024
minprocs = 200
umask = 022
identifier = supervisor
directory = /tmp
nocleanup = true
[program:celery]
directory = /mydir/app
command = celery -A celery_worker.celery worker --loglevel=debug
登录到我的 pod 时,我可以看到有时启动 celery 的过程正在运行(例如在 pod 1 中):
> more /tmp/supervisord.log
2021-06-08 18:19:46,460 CRIT Supervisor running as root (no user in config file)
2021-06-08 18:19:46,462 INFO daemonizing the supervisord process
2021-06-08 18:19:46,462 INFO set current directory: '/tmp'
2021-06-08 18:19:46,463 INFO supervisord started with pid 9
2021-06-08 18:19:47,469 INFO spawned: 'celery' with pid 15
2021-06-08 18:19:48,470 INFO success: celery entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
有时不是(在 pod 2 中):
> more /tmp/supervisord.log
2021-06-08 18:19:42,979 CRIT Supervisor running as root (no user in config file)
2021-06-08 18:19:42,988 INFO daemonizing the supervisord process
2021-06-08 18:19:42,988 INFO set current directory: '/tmp'
2021-06-08 18:19:42,989 INFO supervisord started with pid 9
2021-06-08 18:19:43,992 INFO spawned: 'celery' with pid 11
2021-06-08 18:19:44,994 INFO success: celery entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
>>>> 2021-06-08 18:19:58,642 INFO exited: celery (exit status 2; expected) <<<<<HERE
在我的 pod 1 中,ps 命令显示以下内容:
> ps aux | grep celery
root 9 0.0 0.0 55308 16376 ? Ss 18:45 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/conf.d/celery.conf
root 23 2.2 0.8 2343684 352940 ? S 18:45 0:05 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 37 0.0 0.5 2341860 208716 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 38 0.0 0.5 2341864 208716 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 39 0.0 0.5 2341868 208716 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 40 0.0 0.5 2341872 208724 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 41 0.0 0.5 2341876 208728 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 42 0.0 0.5 2341880 208728 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 43 0.0 0.5 2341884 208736 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
root 44 0.0 0.5 2342836 211384 ? S 18:46 0:00 /usr/bin/python3 /usr/local/bin/celery -A celery_worker.celery worker --loglevel=debug
在我的 pod 2 中,我可以看到 supervisord/celery 进程仍然存在,但我没有在 pod 1 中拥有的所有单独的 /usr/local/bin/celery 进程:
> ps aux | grep celery
root 9 0.0 0.0 55308 16296 ? Ss 18:19 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/conf.d/celery.conf
这种行为并不总是相同的。有时当重新启动 pod 时,两者都成功启动了 celery,有时它们都没有成功。在最后一个场景中,如果我向我的 API 发出一个应该启动 celery 任务的请求,我可以在我的代理控制台 (RabbitMQ) 上看到一个任务已创建,但没有消息“活动”并且没有写入任何内容是我的数据库表(我的 celery 任务的最终结果)。
如果我在我的 pod 中手动启动 celery:
celery -A celery_worker.celery worker --loglevel=debug
一切正常。
什么可以解释这种行为?
【问题讨论】:
-
一个更典型的最佳实践是在一个容器中只启动一个进程,而不用 supervisord。然后,您可以分别部署、升级和扩展 Web 服务器和 Celery 工作人员,并且可以使用 Kubernetes 的本机功能来监控和重新启动各个进程。
-
你当然是对的,我一开始就想这样做。但我不确定这是否可能,因为 celery 需要我的应用程序才能启动。我认为它们必须在同一个 pod 上运行。也许我错了。
-
您的应用容器中不需要 celery。是的,celery 将需要您的应用程序,但您可以使用完全相同的图像并在不同的容器中运行。只需更改入口点或 cmd 以运行 celery 而不是 gunicorn
-
我现在就试一试。是否可以说 celery 容器不必是完全相同的图像,而只能包含使 create_app 正常运行的严格最小值(当然还有 celery 任务)?
-
我会这么认为,但我不能肯定地说。在我的使用中,我总是使用完全相同的图像。
标签: kubernetes celery supervisord