Recientemente cambiamos nuestro entorno de producción a Kubernetes. Me gustaría imponer límites de CPU en los contenedores. Estoy obteniendo métricas de CPU en conflicto que no encajan entre sí. Aquí está mi configuración:
- Agentes DataDog que se ejecutan como
Daemonset
- Aplicaciones existentes que se ejecutan sin límites de CPU
- Los contenedores en cuestión son aplicaciones de Ruby multiproceso
- Dos métricas:
kubernetes.cpu.usage.{avg,max}
ydocker.cpu.usage
c4.xlarge
nodos de clúster (4 vCPU o 4000 m en términos de Kubernetes)
kubernetes.cpu.usage.max
informa ~ 600m para los contenedores en cuestión. docker.cpu.usage
informes ~ 60%. De ello se deduce que un límite de CPU de 1000 m sería más que suficiente capacidad en condiciones normales de funcionamiento.
Puse el límite a 1000m. Luego docker.container.throttles
sube significativamente, mientras que kubernetes.cpu.usage.max
y docker.cpu.usage
siguen siendo los mismos. Todo el sistema cae de rodillas durante este tiempo. Esto no tiene sentido para mi.
Investigué las estadísticas de Docker. Parece que docker stats
(y la API subyacente) normalizan la carga según los núcleos de la CPU. Entonces, en mi caso, docker.cpu.usage
del 60% llega (4000m * 0.60) a 2400m en términos de Kubernetes. Sin embargo, esto no se correlaciona con ningún número de Kubernetes. Hice otro experimento para probar mi hipótesis de que los números de Kubernetes son incorrectos. Establecí el límite en 2600m (para un poco de espacio libre adicional). Esto no dio lugar a ninguna aceleración. Sin embargo, Kubernetes observó que el uso de la CPU no cambió. Esto me deja confundido.
Entonces mis preguntas son:
- ¿Esto se siente como un error en Kubernetes (o algo en la pila?)
- ¿Es correcto mi entendimiento?
Mi pregunta de seguimiento se refiere a cómo determinar adecuadamente la CPU para las aplicaciones de Ruby. Un contenedor usa Puma. Este es un servidor web multiproceso con una cantidad configurable de subprocesos. Las solicitudes HTTP son manejadas por uno de los hilos. La segunda aplicación es un servidor de segunda mano que utiliza el servidor roscado. Cada conexión TCP entrante es manejada por su propio hilo. El hilo sale cuando se cierra la conexión. Ruby como GIL (Global Interpreter Lock) para que solo un hilo pueda ejecutar código Ruby a la vez. Eso permite múltiples hilos ejecutando IO y cosas así.
Creo que el mejor enfoque es limitar el número de subprocesos que se ejecutan en cada aplicación y aproximar los límites de CPU de Kubernetes en función del número de subprocesos. Los procesos no se bifurcan, por lo que el uso total de la CPU es más difícil de predecir.
La pregunta aquí es: ¿cómo predecir adecuadamente el uso de la CPU y los límites para estas aplicaciones?
fuente
Respuestas:
Múltiples cosas aquí:
Estás en AWS ec2, por lo tanto, lo que sea que estés haciendo en tu instancia para medir la CPU es calcular la CPU a nivel de hipervisor y no a nivel de instancia. Para esto, ejecute cualquier prueba de carga y verifique iostat -ct 1 y el uso de la CPU en cloudwatch. El uso de la CPU en cloudwatch es siempre un 10-20% mayor que lo que informará iostat y eso se debe a que iostat proporcionará el uso de la CPU en el nivel de hipervisor.
Como docker para ver cómo se comparan las métricas de kubernetes y docker, sugiero ejecutar los contenedores con --cpuset = 1 o cualquier número para permitir que todos los contenedores usen una sola vCPU.
También en AWS 1 CPU = 2vcpu. Está hipertorreada a 2. Tal vez pueda tener esto en cuenta al calcular.
Finalmente, la mejor métrica para usar para ver el uso de la CPU para una aplicación en particular es usar htop y correlacionarse con las métricas de tu cloudwatch.
También he observado que a veces el Docker Daemon se fija a una de las CPU virtuales y, por lo tanto, cuando lo reduce a 1000 m, tal vez toda la configuración se vuelve lenta porque la reducción está ocurriendo en cualquiera de los vpcus. Puede usar mpstat para entrar en detalles de esto.
Por último, en el nivel de host, puede anclar la ventana acoplable a una sola CPU y observar más.
Espero que esto te acerque un poco. Actualízame si ya has encontrado una solución.
fuente