运行Celery任务的Docker容器的健康检查?

39

我知道检查Docker容器健康状况的其中一种方法是使用以下命令

HEALTHCHECK CMD curl --fail http://localhost:3000/ || exit 1

但是对于工人来说,没有这样的URL可以访问,在这种情况下如何检查容器的健康状况?

6个回答

37

celery inspect ping命令非常方便,它可以完成整个流程:将一个“ping”任务发送到代理程序,工作进程响应并且 celery 获取响应。

假设您的应用程序命名为tasks.add,则可以向所有工作进程发送 ping 命令:

/app $ celery inspect ping -A tasks.add
-> celery@aa7c21dd0e96: OK
        pong
-> celery@57615db15d80: OK
        pong

使用 aa7c21dd0e96 作为 Docker 主机名,因此可在 $HOSTNAME 中获得。

要对单个节点进行ping测试,您需要运行:

celery inspect ping -A tasks.add -d celery@$HOSTNAME

这里,d代表目标地(destination)。

要添加到您的Dockerfile中的行:

HEALTHCHECK CMD celery inspect ping -A tasks.add -d celery@$HOSTNAME

示例输出:

/app $ celery inspect ping -A tasks.add -d fake_node
Error: No nodes replied within time constraint.
/app $ echo $?
69

如果节点不存在或未响应,则是不健康的

/app $ celery inspect ping -A tasks.add -d celery@$HOSTNAME
-> celery@d39b3d31cc13: OK
        pong
/app $ echo $?
0

当节点回复 pong 时是健康的。

/app $ celery inspect ping -d celery@$HOSTNAME
Traceback (most recent call last):
...
    raise socket.error(last_err)
OSError: [Errno 111] Connection refused
/app $ echo $?
1

当代理不可用时是不健康的 - 我删除了应用程序,因此它尝试连接到本地AMPQ并失败了。这可能不适合您的需求,代理出现问题,而不是工作人员。


6
使用 SQS,你好吗?你不能使用 SQS 和 Celery 的结果。参考链接:http://docs.celeryproject.org/en/master/getting-started/brokers/sqs.html#broker-sqs - EsseTi
1
我认为“假设您的应用程序命名为tasks.add”这是一个令人困惑的假设:如果您想要最小化混淆,应用程序不应该存在于名为“tasks”的模块中。 - silviot
2
对于SQS,您可以使用--pidfile /opt/celery/celery_pid指定pidfile,并使用kill -0 $(cat /opt/celery/celery_pid)检查进程是否仍在运行。这是从运行masterpoint.io的人那里得到的。 - SomeGuyOnAComputer
1
@SomeGuyOnAComputer,关于使用kill -0的技巧很不错,谢谢! - pangyuteng

10
以下示例片段是从@PunKeel发布的内容中提取的,适用于希望在docker-compose.yml中实现健康检查的人,可以通过docker-compose或docker stack deploy使用。
worker:
    build:
        context: .
        dockerfile: Dockerfile
    image: myimage
    links:
        - rabbitmq
    restart: always
    command: celery worker --hostname=%h --broker=amqp://rabbitmq:5672
    healthcheck:
        test: celery -b amqp://rabbitmq:5672 inspect ping -d celery@$$HOSTNAME
        interval: 30s
        timeout: 10s
        retries: 3

注意命令中额外的$,这样$HOSTNAME才能传递到容器中。我也没有使用-A标志。
理想情况下,rabbitmq应该有自己的健康检查,可以使用curl guest:guest@localhost:15672/api/overview,因为docker无法区分worker是否停止或代理是否停止,而celery inspect ping则可以。
-- 编辑:
请还要查看SomeGuyOnAComputer提供的解决方案,使用kill -0 $PID来检查PID是否存活。

1
如果你在使用认证,你可以通过写user:pass@rabbitmq:5672来提供用户名和密码。你甚至可以使用你为应用设置的环境变量,例如:celery inspect ping -b amqp://$${RABBITMQ_USER}:$${RABBITMQ_PASS}@$${RABBITMQ_HOST}:5672 -d celery@$$HOSTNAME - luckydonald
在 Celery 5.2.3 上:错误:没有这个选项:-b - Martin Thoma
2
命令顺序需要更改:celery inspect ping -b amqp://rabbitmq:5672 - Martin Thoma
根据@Mart的要求更新了健康检查测试命令。 - pangyuteng
1
关于RabbitMQ,在Alpine版本中可能没有curl可用,或者RabbitMQ管理插件可能被禁用:最好的解决方案是使用类似于rabbitmq-diagnostics -q status && rabbitmq-diagnostics -q check_local_alarms的命令。请参阅文档:https://www.rabbitmq.com/rabbitmq-diagnostics.8.html - undefined

3

对于 celery 5.2.3 版本,我使用 celery -A [celery 应用名称] status 进行健康检查。这是我的 docker-compose 文件的样子。

worker:
      build: .
      healthcheck:
        test: celery -A app.celery_app status
        interval: 10s
        timeout: 10s
        retries: 10
      volumes:
          - ./app:/app
      depends_on:
        - broker
        - redis
        - database

谢谢!但是除了01之外的退出代码对应于未定义的行为,所以这里有一个小改进:celery -A [celery app name] status || exit 1。来源:https://docs.docker.com/engine/reference/builder/#healthcheck 和 https://www.atatus.com/blog/health-check-command-in-docker/ - undefined

1
落在这个问题上,寻找一个健康检查的芹菜工人作为Airflow设置的一部分(Airflow 2.3.4,Celery 5.2.7),最终我弄清楚了。这是原始问题的一个非常特定的用例,但对某些人仍然可能有用:
# docker-compose.yml

  worker:
      image: ...
      hostname: local-worker
      entrypoint: airflow celery worker
      ...
      healthcheck:
        test: [ "CMD-SHELL", 'celery --app airflow.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"' ]
        interval: 5s
        timeout: 10s
        retries: 10
      restart: always
      ...

我从Airflow的快速启动Docker Compose中获得了灵感。


0

为正在运行Celery任务的Docker容器配置健康检查,并确保另一个容器依赖其健康状态:

在您的Docker Compose文件中:

version: "3.8"
services:
  celery:
    # Celery container config
    healthcheck:
      test: celery inspect ping
      interval: 1m
      timeout: 10s
      retries: 10
      start_period: 1m

  dependent_container:
    # Dependent container config
    depends_on:
      celery:
        condition: service_healthy

这将使用celery inspect pingcelery容器设置健康检查。
dependent_container依赖于具有condition: service_healthycelery,确保只有在celery健康时才启动。


0

就是这么简单:

...
healthcheck:
    test: sh -c 'celery -A your_celery_module inspect ping'
    ...

您的日志文件将具有类似于ping日志的以下内容:

[2023-05-05 11:18:47,309:DEBUG / MainProcess] pidbox收到方法ping()[reply_to:{'exchange':'reply.celery.pidbox','routing_key':'8195241f-122a-3dc4-9841-739f55804b82'} ticket:bada7609-ce6b-499a-b3c2-c80911e0fe09]

此外,您可能希望在已运行的容器中自行检查它。 在这种情况下,它看起来会像这样:

celery ping output


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