Hola,
Estoy usando Kubernetes para implementar mi aplicación de Python, Kubernetes proporciona un livenessProbe y readinessProbe, consulte aquí .
¿Cómo puedo hacer para verificar si mi batido de apio o mi albahaca están vivos y en el estado correcto?
El PID no es una solución porque no se puede utilizar para detectar un punto muerto, por ejemplo.
Gracias de antemano por tu ayuda,
Atentamente,
El apio tiene una API de monitoreo que puede usar.
Una vaina debe considerarse activa si el trabajador de Apio envía un latido .
Un pod debe considerarse listo si el trabajador ha enviado el evento en línea del
Si tiene problemas específicos o solicitudes de funciones, abra un problema por separado.
¿Funcionaría esto?
readinessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "celery -A path.to.app status | grep -o ': OK'"
initialDelaySeconds: 30
periodSeconds: 10
@ 7wonders Primero deberías extraer el nombre del nodo de apio. Esta readinessProbe fallará si falla alguna instancia de apio, que no es lo que desea.
@thedrow Hmm, creo que en realidad tendrá éxito incluso si el nodo real ha fallado, pero otro está bien, lo que tampoco es un gran resultado.
Parece
/bin/sh -c 'exec celery -A path.to.app inspect ping -d celery@$HOSTNAME'
es lo suficientemente bueno para la verificación de preparación y verifica solo un nodo.
Tenga en cuenta que en algunas aplicaciones, la ejecución de este comando puede demorar unos segundos con la CPU completa Y los valores predeterminados de kubernetes son ejecutarlo cada 10 segundos.
Por lo tanto, es mucho más seguro tener un períodoSegundos alto (el nuestro está configurado en 300).
@redbaron, ¿
Por alguna razón, esta prueba de preparación no es ni de lejos satisfactoria para nosotros. La inspección responde de forma no determinista sin carga en nuestro clúster. Ejecutamos el formato así:
apio inspeccionar ping -b " redis: // archii-redis-master : 6379" -d apio @ archii-task-crawl-integration-7d96d86b9d-jwtq7
Y con tiempos de ping normales (10 segundos), nuestro clúster es completamente eliminado por la CPU que requiere el apio.
~ Lo uso para vivir con un intervalo de 30 segundos: sh -c celery -A path.to.app status | grep "${HOSTNAME}:.*OK"
~
Utilizo esto para vivir con un intervalo de 30 segundos: sh -c celery -A path.to.app inspect ping --destination celery@${HOSTNAME}
No parece causar ninguna carga adicional, tengo una flota de más de 100 trabajadores.
Las sondas de preparación no son necesarias, el apio nunca se usa en un servicio. Acabo de configurar minReadySeconds: 10
que es lo suficientemente bueno para retrasar el inicio del trabajador en implementaciones continuas, pero obviamente depende del tiempo de inicio de Celery para su proyecto, así que examine los registros y configúrelos en consecuencia.
Las sondas de preparación siguen siendo útiles incluso si no se utilizan en un servicio. Específicamente, cuando realiza una implementación de trabajadores y desea asegurarse de que su implementación fue exitosa, generalmente usa kubectl rollout status deployment
. Sin las sondas de preparación, hemos implementado un código incorrecto que no inició el apio y no lo sabía.
Mi solucion fue:
readinessProbe:
exec:
command:
[
"/usr/local/bin/python",
"-c",
"\"import os;from celery.task.control import inspect;from <APP> import celery_app;exit(0 if os.environ['HOSTNAME'] in ','.join(inspect(app=celery_app).stats().keys()) else 1)\""
]
Otros parecen no funcionar 🤷♂️
¡Gracias @yardensachs!
Dedique mucho tiempo a depurar lo que está mal con otras soluciones, pero de ninguna manera
Parece que el comando celery inspect ping
no devuelve exit (0) o algo por el estilo
celery inspect ping
funciona, pero necesita bash
para reemplazar la variable de entorno de esta manera:
livenessProbe:
exec:
# bash is needed to replace the environment variable
command: [
"bash",
"-c",
"celery inspect ping -A apps -d celery@$HOSTNAME"
]
initialDelaySeconds: 30 # startup takes some time
periodSeconds: 60 # default is quite often and celery uses a lot cpu/ram then.
timeoutSeconds: 10 # default is too low
bueno saber
Terminamos arrancando el ping de inspección de apio de nuestras sondas de vitalidad porque descubrimos que bajo una carga más pesada, el ping se colgaría durante minutos a la vez, aunque los trabajos se estaban procesando bien y no había atrasos. Tengo la sensación de que tuvo algo que ver con el uso de eventlet, pero seguimos investigándolo.
@WillPlatnick Eso no sucederá con 5.0 porque Celery será asíncrono, por lo que habrá capacidad reservada para las corrutinas de control.
Tengo problemas con inspect ping
procesos de generación difuntos / zombies:
root 2296 0.0 0.0 0 0 ? Z 16:04 0:00 [python] <defunct>
root 2323 0.0 0.0 0 0 ? Z 16:05 0:00 [python] <defunct>
...
¿Alguien más se encuentra con esto? No hay un argumento --pool
para forzar la ejecución de un solo proceso.
¿Puedo preguntar qué estás usando en lugar de celery inspect ping
@WillPlatnick? Hemos encontrado un problema similar con la sonda fallando bajo una carga pesada.
@mcyprian Nos deshicimos de la sonda de vida. Mi instinto me dice que tiene algo que ver con eventlet, pero no lo hemos convertido en una prioridad para resolverlo.
nos encontramos con el mismo problema de CPU con el corredor de Redis
¿Ha encontrado alguien una solución?
También estábamos experimentando con la programación de "debug_task" en la cola cuyo nombre basamos en el nombre del contenedor. El problema es que ahora tenemos toneladas de colas antiguas en RabbitMQ
Tenga en cuenta que el uso
sh -c celery -A path.to.app status | grep "${HOSTNAME}:.*OK"
como se sugiere en https://github.com/celery/celery/issues/4079#issuecomment -437415370 dará lugar a informes de errores masivos en rabbitmq, consulte https://github.com/celery/celery/issues/4355#issuecomment - 578786369
Creo que he encontrado una manera de reducir el uso de CPU de inspeccionar ping.
celery -b amqp: // usuario: pass @ rabbitmq : 5672 / vhost inspecciona ping
No cargar las configuraciones de apio usando -A path.to.celery ciertamente ayudó con el uso de la CPU,
alguien podría verificar.
Creo que he encontrado una manera de reducir el uso de CPU de inspeccionar ping.
celery -b amqp: // usuario: pass @ rabbitmq : 5672 / vhost inspecciona ping
No cargar las configuraciones de apio usando -A path.to.celery ciertamente ayudó con el uso de la CPU,
alguien podría verificar.
¡Lindo! Es mucho mejor que con la aplicación cargada.
Pero todavía tenemos la enorme sobrecarga de un proceso de Python que comienza + importación de apio. Todavía recomendaría un período alto.
Hola,
celery inspeccionar ping -A app.tasks -d celery @ $ HOSTNAME me da "Error: Transmisión no admitida por transporte 'sqs'".
Estoy usando SQS como intermediario, por lo que esto significa que el comando 'inspeccionar' / 'estado' no funcionará con SQS.
Hemos descubierto que, a escala, todas las funciones de control remoto están provocando que la instancia de Redis aumente en la CPU debido a la configuración de comandos en la tecla kombu.pidbox
, por lo que no podemos usar ping, estado o inspeccionar como están. todos usando control remoto e intentando deshabilitar el control remoto para el caso de uso de producción.
Me parece que tener una cola de verificación de estado dedicada es la manera correcta, pero no estoy seguro en absoluto
¿Alguien tiene alguna otra dirección que no involucre el control remoto para probar los controles de salud?
Usamos colas de verificación de estado dedicadas con políticas de desalojo de RabbitMQ (las colas se eliminan automáticamente) con éxito durante algún tiempo, y estamos contentos con la solución. Sobre todo porque esta comprobación es, de hecho, comprobar que el trabajador procesa la tarea y finaliza. Desde que lo presentamos, no tuvimos más problemas con los trabajadores atascados.
@bartoszhernas, ¿te importaría compartir un código para eso? ¿los pone en cola a través de beat y luego los trabajadores lo recogen?
Me encantaría ver el código + la sección de prueba de vida.
Hola, el código es realmente fácil:
En Kubernetes, especifico el nombre de la cola en función de POD_NAME y lo paso al script livecheck:
livenessProbe:
initialDelaySeconds: 120
periodSeconds: 70
failureThreshold: 1
exec:
command:
- bash
- "-c"
- |
python celery_liveness_probe.py $LIVENESS_QUEUE_NAME
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: LIVENESS_QUEUE_NAME
value: queue-$(MY_POD_NAME)
(debe usar bash -c, porque Kubernetes no expande los ENV cuando intenta pasarlo como comando directamente)
entonces celery_liveness_probe.py solo está configurando Django para poder usar Celery y programar la tarea en la cola de POD
# encoding: utf-8
from __future__ import absolute_import, unicode_literals
import os
import sys
if __name__ == "__main__":
import django
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ahoy.archive.settings")
django.setup()
from ahoy.archive.apps.eventbus.service import eventbus_service
exit(0 if eventbus_service.health_check(sys.argv[1] if sys.argv and len(sys.argv) > 1 else None) else 1)
la función de verificación de estado envía la tarea y espera los resultados
def health_check(self, queue_name: Optional[str] = None) -> bool:
event = self.celery.send_task(
AhoyEventBusTaskName.LIVENESS_PROBE,
None,
queue=queue_name or self.origin_queue,
ignore_result=False,
acks_late=True,
retry=False,
priority=255
)
try:
is_success = event.get(timeout=10)
except (celery.exceptions.TimeoutError, AttributeError):
is_success = False
return is_success
Básicamente: envíe una tarea y, si devuelve resultados, el trabajador está sano. Si el trabajador se atascó (sucedió muchas veces), las tareas nunca terminan, el Pod se reinicia y todo vuelve a la normalidad.
La única advertencia es que debe lidiar con las colas antiguas, con RabbitMQ es fácil, solo configuramos una política de vencimiento en la cola
https://www.rabbitmq.com/ttl.html#queue -ttl
@bartoszhernas ¡ gracias por compartir el código!
como dijiste, mis colas son dinámicas y estamos usando Redis, por lo que realmente necesitamos encontrar una manera de lidiar con el vencimiento de los nombres de las colas en Redis.
Sí, tenemos un problema similar con BullMQ con Redis. Mi idea es escribir CronJob para Kubernetes que borre las colas cada cierto tiempo.
Comentario más útil
celery inspect ping
funciona, pero necesitabash
para reemplazar la variable de entorno de esta manera: