Bienvenido Habr!
En un momento, fuimos los primeros en
introducir el tema
Kafka en el mercado ruso y continuar
monitoreando su desarrollo. En particular, el tema de interacción entre Kafka y
Kubernetes nos pareció interesante. Un artículo de revisión (y bastante cauteloso) sobre este tema fue publicado en el blog de Confluent en octubre del año pasado, escrito por Gwen Shapira. Hoy queremos llamar su atención sobre un artículo más reciente de abril de Johann Gyger, quien, aunque no sin un signo de interrogación en el título, considera el tema de una manera más sustantiva, acompañando el texto con enlaces interesantes. Por favor, perdónanos la traducción gratuita de "mono del caos" si puedes!
Introduccion
Kubernetes está diseñado para manejar cargas sin estado. Como regla general, tales cargas de trabajo se presentan en forma de arquitectura de microservicios, son livianas, adecuadas para el escalado horizontal, obedecen los principios de las aplicaciones de 12 factores y permiten trabajar con disyuntores y monos caóticos.
Kafka, ubicado por otro lado, esencialmente actúa como una base de datos distribuida. Por lo tanto, cuando trabaja, tiene que lidiar con la condición, y es mucho más pesada que un microservicio. Kubernetes admite cargas con estado, pero como Kelsey Hightower señala en dos de sus tweets, deben manejarse con cuidado:
A algunos les parece que si enrollas Kubernetes en una carga con estado, se convierte en una base de datos totalmente administrada que puede competir con RDS. Esto no es asi. Quizás si solo trabajas duro, atornillas componentes adicionales y atraes a un equipo de ingenieros de SRE, puedes instalar RDS sobre Kubernetes.
Siempre recomiendo que todos ejerzan extrema precaución al lanzar cargas de conservación de estado en Kubernetes. La mayoría de los que están interesados en "¿puedo ejecutar cargas con estado en Kubernetes" no tienen suficiente experiencia trabajando con Kubernetes, y a menudo con la carga sobre la que están preguntando.
Entonces, ¿debería ejecutar Kafka en Kubernetes? Contra-pregunta: ¿Kafka funcionará mejor sin Kubernetes? Es por eso que quiero enfatizar en este artículo cómo Kafka y Kubernetes se complementan y qué dificultades pueden surgir cuando se combinan.
Plazo de entrega
Hablemos de lo básico: el entorno de tiempo de ejecución en sí
El procesoLos corredores Kafka son convenientes cuando se trabaja con la CPU. TLS puede incurrir en algunos gastos generales. Al mismo tiempo, los clientes de Kafka pueden cargar más la CPU si usan cifrado, pero esto no afecta a los corredores.
El recuerdoLos corredores de Kafka engullen el recuerdo. El tamaño de almacenamiento dinámico de JVM generalmente está de moda para limitar de 4 a 5 GB, pero también necesitará mucha memoria del sistema, ya que Kafka usa la memoria caché de página de manera muy activa. En Kubernetes, establezca adecuadamente los límites de contenedor para recursos y solicitudes.
Almacén de datosEl almacenamiento de datos en los contenedores es efímero: los datos se pierden al reiniciar. Puede usar el volumen
emptyDir
para los datos de Kafka, y el efecto será similar: sus datos de intermediario se perderán una vez finalizados. Sus mensajes aún se pueden guardar en otros corredores como réplicas. Por lo tanto, después de un reinicio, un agente fallido debe primero replicar todos los datos, y este proceso puede llevar mucho tiempo.
Es por eso que se debe utilizar el almacenamiento de datos a largo plazo. Sea un almacenamiento a largo plazo no local con el sistema de archivos XFS o, más precisamente, ext4. No use NFS. Le advertí Las versiones NFS v3 o v4 no funcionarán. En resumen, el corredor Kafka finalizará si no puede eliminar el directorio de datos debido al problema de "cambio de nombre estúpido" que es relevante en NFS. Si todavía no te he convencido,
lee este artículo con mucho cuidado. El almacén de datos debe ser no local para que Kubernetes pueda seleccionar de manera más flexible un nuevo nodo después de un reinicio o reubicación.
RedComo con la mayoría de los sistemas distribuidos, el rendimiento de Kafka depende en gran medida de que la latencia de la red sea mínima y el ancho de banda sea máximo. No intente colocar a todos los intermediarios en el mismo nodo, ya que esto disminuirá la disponibilidad. Si el nodo Kubernetes falla, también falla todo el clúster de Kafka. Además, no disperse el clúster de Kafka en centros de datos completos. Lo mismo ocurre con el clúster de Kubernetes. Un buen compromiso en este caso es elegir diferentes zonas de acceso.
Configuracion
Manifiestos comunesEl sitio web de Kubernetes tiene una
muy buena guía sobre cómo configurar ZooKeeper utilizando manifiestos. Dado que ZooKeeper es parte de Kafka, es conveniente que comience a familiarizarse con los conceptos de Kubernetes aplicables aquí. Una vez que descubra esto, puede usar los mismos conceptos con el clúster Kafka.
- Sub : sub es la unidad desplegable más pequeña de Kubernetes. El pod contiene su carga de trabajo, y el pod en sí corresponde al proceso en su clúster. Un hogar contiene uno o más recipientes. Cada servidor de ZooKeeper en el conjunto y cada agente en el clúster de Kafka trabajarán en un enfoque separado.
- StatefulSet : StatefulSet es un objeto de Kubernetes que funciona con múltiples cargas de trabajo con estado, que requieren coordinación. StatefulSet ofrece garantías con respecto al pedido de hogares y su singularidad.
- Servicios sin cabeza : los servicios le permiten separar pods de clientes utilizando un nombre lógico. Kubernetes en este caso es responsable del equilibrio de carga. Sin embargo, al mantener cargas de trabajo con estado, como en el caso de ZooKeeper y Kafka, los clientes deben intercambiar información con una instancia específica. Aquí es donde los servicios sin cabeza son útiles: en este caso, el cliente seguirá teniendo un nombre lógico, pero no tendrá que ir directamente al final.
- Volumen para almacenamiento a largo plazo : estos volúmenes son necesarios para la configuración del almacenamiento a largo plazo en bloque no local, que se mencionó anteriormente.
Yolean proporciona un conjunto completo de manifiestos que facilitan comenzar con Kafka en Kubernetes.
Cartas de timónHelm es un administrador de paquetes para Kubernetes, que se puede comparar con los administradores de paquetes para el sistema operativo, como yum, apt, Homebrew o Chocolatey. Su uso es conveniente para instalar paquetes de software predefinidos descritos en los diagramas de Helm. Un diagrama de Helm bien elegido facilita la difícil tarea: cómo configurar correctamente todos los parámetros para usar Kafka en Kubernetes. Hay varios diagramas de Kafka: el oficial está
en estado de incubadora , hay uno de
Confluent , uno más de
Bitnami .
OperadoresDado que Helm tiene ciertos inconvenientes, otra herramienta está ganando considerable popularidad: los operadores de Kubernetes. El operador no solo empaqueta el software para Kubernetes, sino que también le permite implementar dicho software y también administrarlo.
La lista de
operadores increíbles menciona dos operadores para Kafka. Uno de ellos es
Strimzi . Con la ayuda de Strimzi, es fácil crear un clúster de Kafka en minutos. Prácticamente no se requiere configuración, además, el operador en sí proporciona algunas características interesantes, por ejemplo, el cifrado TLS del tipo "punto a punto" dentro del clúster. Confluent también proporciona
su propio operador .
RendimientoEs muy importante probar el rendimiento suministrando puntos de control a la instancia de Kafka instalada. Estas pruebas lo ayudarán a identificar posibles cuellos de botella antes de que comiencen los problemas. Afortunadamente, Kafka ya proporciona dos herramientas de prueba de rendimiento:
kafka-producer-perf-test.sh
y
kafka-consumer-perf-test.sh
. Úsalos activamente. Como referencia, puede consultar los resultados descritos en
esta publicación por Jay Kreps, o utilizar
esta revisión Stéphane Maarek Amazon MSK.
Operaciones
MonitoreoLa transparencia en el sistema es muy importante; de lo contrario, no comprenderá lo que sucede en él. Hoy en día existe un conjunto de herramientas sólido que proporciona monitoreo basado en métricas al estilo de la nube nativa. Dos herramientas populares para este propósito son Prometheus y Grafana. Prometheus puede recopilar métricas de todos los procesos de Java (Kafka, Zookeeper, Kafka Connect) utilizando el exportador JMX, de la manera más simple. Si agrega métricas de cAdvisor, puede comprender mejor cómo se utilizan los recursos en Kubernetes.
Strimzi tiene un ejemplo de tablero de Grafana muy conveniente para Kafka. Visualiza métricas clave, por ejemplo, sobre sectores poco replicados o aquellos que están fuera de línea. Todo está muy claro allí. Estas métricas se complementan con información sobre la utilización y el rendimiento de los recursos, así como con indicadores de estabilidad. Por lo tanto, obtienes un monitoreo básico del clúster Kafka sin ninguna razón.

Fuente:
strimzi.io/docs/master/#kafka_dashboardSería bueno complementar todo esto con monitoreo del cliente (métricas para consumidores y productores), así como monitoreo de retraso (para esto hay
Burrow ) y monitoreo de extremo a extremo; para esto, use
Kafka Monitor .
RegistroEl registro es otra tarea crítica. Asegúrese de que todos los contenedores en su instalación de Kafka estén registrados en
stdout
y
stderr
, y asegúrese de que su clúster de Kubernetes agregue todos los registros en una infraestructura de
registro central, como
Elasticsearch .
Control de saludKubernetes utiliza sondas de vitalidad y preparación para verificar si sus vainas funcionan correctamente. Si la prueba en vivo falla, Kubernetes detendrá este contenedor y luego lo reiniciará automáticamente si la política de reinicio se configura en consecuencia. Si falla la verificación de disponibilidad, Kubernetes aísla esto del servicio de solicitud. Por lo tanto, en tales casos, la intervención manual ya no es necesaria, y esto es una gran ventaja.
Implementación de actualizacionesStatefulSet admite actualizaciones automáticas: al elegir una estrategia RollingUpdate, cada una bajo Kafka se actualizará a su vez. De esta manera, el tiempo de inactividad puede reducirse a cero.
EscalamientoEscalar un clúster de Kafka no es tarea fácil. Sin embargo, en Kubernetes es muy fácil escalar pods a un cierto número de réplicas, lo que significa que puede identificar declarativamente tantos corredores Kafka como desee. Lo más difícil en este caso es la reasignación de sectores después de la ampliación o antes de la reducción. Nuevamente, Kubernetes lo ayudará con esta tarea.
AdministraciónLas tareas relacionadas con la administración de su clúster Kafka, en particular, la creación de temas y la reasignación de sectores, se pueden realizar utilizando los scripts de shell existentes, abriendo la interfaz de línea de comandos en sus pods. Sin embargo, esta solución no es demasiado hermosa. Strimzi admite la gestión de temas utilizando otro operador. Hay algo que modificar aquí.
Copia de seguridad y restauraciónAhora la disponibilidad de Kafka dependerá de la disponibilidad de Kubernetes. Si su grupo Kubernetes cae, entonces, en el peor de los casos, el grupo Kafka también cae. Según la ley de Murphy, esto sucederá y perderá datos. Para reducir este tipo de riesgo, tenga un buen concepto de respaldo. Puede usar MirrorMaker, otra opción es usar S3 para esto, como se describe en esta
publicación de Zalando.
Conclusión
Cuando se trabaja con grupos de Kafka pequeños o medianos, definitivamente es recomendable usar Kubernetes, ya que proporciona flexibilidad adicional y simplifica el trabajo con los operadores. Si tiene requisitos no funcionales muy serios con respecto a la latencia y / o el rendimiento, entonces podría ser mejor considerar alguna otra opción de implementación.