A lo largo de los años de la existencia de Pinterest, 300 millones de usuarios del servicio han creado más de 200 mil millones de pines en más de 4 mil millones de tableros. Para servir a este ejército de usuarios y una amplia base de contenido, el portal ha desarrollado miles de servicios, que van desde microservicios que pueden manejar varias CPU, y terminando con monolitos gigantes que giran en toda una flota de máquinas virtuales. Y entonces llegó el momento en que los ojos de la compañía se centraron en k8. ¿Qué le pareció el "cubo" a "Interés"? Aprenderá sobre esto con nuestra traducción de la última publicación de blog de ingeniería de Pinterest .
Entonces, cientos de millones de usuarios y cientos de miles de millones de pines. Para servir a este ejército de usuarios y una amplia base de contenido, hemos desarrollado miles de servicios, que van desde microservicios que pueden ser manejados por varias CPU hasta monolitos gigantes que giran en una flota completa de máquinas virtuales. Además, tenemos una variedad de marcos que también pueden requerir recursos de CPU, memoria o acceso a E / S.
En apoyo de este zoológico de herramientas, el equipo de desarrollo enfrenta una serie de desafíos:
- Los ingenieros no tienen una forma unificada de ejecutar un entorno de trabajo. Los servicios sin estado, los servicios con estado y los proyectos en desarrollo activo se basan en pilas de tecnología completamente diferentes. Esto condujo a la creación de un curso completo de capacitación para ingenieros, y también complica seriamente el trabajo de nuestro equipo de infraestructura.
- Los desarrolladores con su propia flota de máquinas virtuales crean una gran carga en los administradores internos. Como resultado, operaciones tan simples como actualizar el SO o AMI duran semanas y meses. Esto lleva a un aumento en la carga de trabajo en situaciones aparentemente absolutamente cotidianas.
- Dificultades para crear herramientas de administración de infraestructura global además de las soluciones existentes. La situación se complica por el hecho de que encontrar a los propietarios de máquinas virtuales no es fácil. Es decir, no sabemos si es seguro extraer estas capacidades para trabajar en otras partes de nuestra infraestructura.
Los sistemas de orquestación de contenedores son una forma de unificar la gestión de la carga de trabajo. Le abren el camino para aumentar la velocidad de desarrollo y simplificar la administración de la infraestructura, ya que todos los recursos involucrados en el proyecto son administrados por un sistema centralizado.
Figura 1: Prioridades de infraestructura (confiabilidad, productividad del desarrollador y eficiencia).El equipo de Cloud Management Platform en Pinterest se reunió con K8 en 2017. Para el primer semestre de 2017, documentamos la mayoría de nuestras instalaciones de producción, incluida la API y todos nuestros servidores web. Después de eso, evaluamos cuidadosamente los diversos sistemas de orquestación de soluciones de contenedores, construyendo clústeres y trabajando con ellos. A finales de 2017, decidimos usar Kubernetes. Fue lo suficientemente flexible y ampliamente compatible con la comunidad de desarrolladores.
Hasta ahora, hemos creado nuestras propias herramientas de arranque de clúster basadas en Kops y hemos migrado a los componentes de infraestructura existentes de Kubernetes como red, seguridad, métricas, registro, gestión de identidad y tráfico. También implementamos un sistema de modelado de carga de trabajo para nuestro recurso, cuya complejidad está oculta para los desarrolladores. Ahora estamos enfocados en garantizar la estabilidad del clúster, su escalamiento y la conexión de nuevos clientes.
Kubernetes: el camino de Pinterest
Comenzar con Kubernetes en una escala de Pinterest como una plataforma que nuestros ingenieros adorarán es abrumador.
Como una gran empresa, hemos invertido mucho en herramientas de infraestructura. Los ejemplos incluyen herramientas de seguridad que procesan certificados y distribuyen claves, componentes de control de tráfico, sistemas de descubrimiento de servicios, visibilidad y envío de registros y métricas. Todo esto se recopiló por una razón: seguimos el camino normal de prueba y error y, por lo tanto, queríamos integrar toda esta economía en la nueva infraestructura en Kubernetes en lugar de reinventar la vieja bicicleta en una nueva plataforma. Este enfoque generalmente simplifica la migración, ya que todo el soporte de aplicaciones ya existe, no necesita ser creado desde cero.
Por otro lado, los modelos de pronóstico de carga en Kubernetes (por ejemplo, implementaciones, trabajos y kits de Daemon) no son suficientes para nuestro proyecto. Estos problemas de usabilidad son enormes barreras para mudarse a Kubernetes. Por ejemplo, escuchamos a los desarrolladores de servicios quejarse de una configuración de inicio de sesión faltante o incorrecta. También encontramos un uso inadecuado de los motores de plantillas cuando se crearon cientos de copias con la misma especificación y tarea, lo que resultó en problemas de pesadilla con la depuración.
También fue muy difícil admitir diferentes versiones en el mismo clúster. Imagine la complejidad de la atención al cliente si necesita trabajar de inmediato en muchas versiones del mismo tiempo de ejecución, con todos sus problemas, errores y actualizaciones.
Recursos y controladores personalizados de Pinterest
Para facilitar la implementación de Kubernetes a nuestros ingenieros, así como para simplificar y acelerar la infraestructura, hemos desarrollado nuestras propias definiciones de recursos personalizados (CRD).
Los CRD proporcionan las siguientes características:
- Combinando varios recursos nativos de Kubernetes para que funcionen como una sola carga. Por ejemplo, el recurso PinterestService incluye una implementación, un servicio de inicio de sesión y un mapa de configuración. Esto permite a los desarrolladores no preocuparse por configurar DNS.
- Implemente el soporte de aplicaciones necesario. El usuario debe centrarse solo en la especificación del contenedor de acuerdo con su lógica empresarial, mientras que el controlador CRD implementa todos los contenedores de inicio necesarios, las variables de entorno y las especificaciones del pod. Esto proporciona un nivel de comodidad fundamentalmente diferente para los desarrolladores.
- Los controladores CRD también administran el ciclo de vida de sus propios recursos y aumentan la disponibilidad de depuración. Esto incluye acordar las especificaciones deseadas y reales, actualizar el estado del CRD y mantener registros de eventos y más. Sin CRD, los desarrolladores se verían obligados a administrar un gran conjunto de recursos, lo que solo aumentaría la probabilidad de un error.
Aquí hay un ejemplo de PinterestService y el recurso interno controlado por nuestro controlador:

Como puede ver arriba, para admitir un contenedor personalizado, necesitamos integrar un contenedor de inicialización y varios complementos para garantizar la seguridad, la visibilidad y el trabajo con el tráfico de red. Además, creamos plantillas de mapas de configuración e implementamos soporte para plantillas de PVC para trabajos por lotes, así como también rastreamos una variedad de variables de entorno para rastrear la identificación, el consumo de recursos y la recolección de basura.
Es difícil imaginar que los desarrolladores quieran escribir estos archivos de configuración manualmente sin soporte CRD, sin mencionar más soporte y depuración de configuraciones.
Implementación de aplicaciones de flujo de trabajo

La figura anterior muestra cómo implementar un recurso personalizado de Pinterest en un clúster de Kubernetes:
- Los desarrolladores interactúan con nuestro clúster de Kubernetes a través de la CLI y la interfaz de usuario.
- Las herramientas CLI / UI extraen los archivos YAML de configuración del flujo de trabajo y otras propiedades de ensamblaje (mismo identificador de versión) de Artifactory y luego los envían al Servicio de envío de trabajos. Este paso garantiza que solo se entreguen versiones de producción al clúster.
- JSS es la puerta de entrada a varias plataformas, incluido Kubernetes. Aquí es donde se lleva a cabo la autenticación del usuario, la emisión de cuotas y la verificación parcial de nuestra configuración CRD.
- Después de verificar el CRD en el lado JSS, la información se envía a la API de la plataforma k8s.
- Nuestro controlador CRD monitorea eventos en todos los recursos del usuario. Convierte CR en recursos nativos de k8, agrega los módulos necesarios, establece las variables de entorno apropiadas y realiza otro trabajo auxiliar, lo que garantiza a las aplicaciones de usuario de contenedores suficiente soporte de infraestructura.
- Luego, el controlador CRD transfiere los datos recibidos a la API de Kubernetes para que el planificador los procese y los ponga en funcionamiento.
Nota : esta implementación de flujo de trabajo de prelanzamiento se creó para los primeros usuarios de la nueva plataforma k8s. Ahora estamos en el proceso de finalizar este proceso para integrarnos completamente con nuestro nuevo CI / CD. Esto significa que no podemos decir todo lo relacionado con Kubernetes. Esperamos compartir nuestra experiencia y contarle al equipo sobre este progreso en nuestra próxima publicación en el blog “Construyendo una plataforma CI / CD para Pinterest”.
Tipos de recursos especiales
En base a las necesidades específicas de Pinterest, hemos desarrollado los siguientes CRD que son adecuados para una variedad de flujos de trabajo:
- PinterestService es un servicio sin estado de larga duración. Muchos de nuestros sistemas principales se basan en un conjunto de dichos servicios.
- PinterestJobSet modela trabajos por lotes de ciclo completo. Pinterest tiene un escenario común, según el cual varias tareas ejecutan los mismos contenedores en paralelo, e independientemente de otros procesos similares.
- PinterestCronJob se usa ampliamente junto con pequeñas cargas periódicas. Este es un shell nativo cron con mecanismos de soporte de Pinterest que son responsables de la seguridad, el tráfico, los registros y las métricas.
- Daemon incluye la infraestructura de Daemon. Esta familia continúa creciendo a medida que agregamos más apoyo para nuestros grupos.
- PinterestTrainingJob se extiende a los procesos de Tensorflow y Pytorch, proporcionando el mismo nivel de soporte en línea que todos los otros CRD. Dado que Pinterest está utilizando activamente Tensorflow y otros sistemas de aprendizaje automático, teníamos una razón para construir un CRD separado a su alrededor.
También estamos trabajando en PinterestStatefulSet, que pronto se adaptará para almacenes de datos y otros sistemas con estado.
Soporte de tiempo de ejecución
Cuando el módulo de aplicación se ejecuta en Kubernetes, recibe automáticamente un certificado para identificarse. Este certificado se utiliza para acceder al almacén secreto o para comunicarse con otros servicios a través de mTLS. Mientras tanto, el configurador de inicialización del contenedor y Daemon descargarán todas las dependencias necesarias antes de iniciar la aplicación del contenedor. Cuando todo esté listo, el tráfico de sidecar y Daemon registrarán la dirección IP del módulo en nuestro Zookeeper para que los clientes puedan encontrarlo. Todo esto funcionará, ya que el módulo de red se configuró antes de que se iniciara la aplicación.
Los siguientes son ejemplos típicos de soporte de carga de trabajo en tiempo de ejecución. Para otros tipos de cargas de trabajo, es posible que se requiera un soporte ligeramente diferente, pero todos se presentan como máquinas virtuales de nivel sidecar pod, nodal o nivel Daemon. Nos aseguramos de que todo esto se implemente dentro del marco de la infraestructura de administración y se coordine entre las aplicaciones, lo que finalmente reduce significativamente la carga en términos de trabajo técnico y soporte al cliente.
Pruebas y control de calidad
Hemos reunido una tubería de prueba de extremo a extremo sobre la infraestructura de prueba de Kubernetes existente. Estas pruebas se aplican a todos nuestros grupos. Nuestra tubería pasó por muchos cambios antes de convertirse en parte del grupo de productos.
Además de los sistemas de prueba, tenemos sistemas de monitoreo y advertencia que monitorean constantemente el estado de los componentes del sistema, el consumo de recursos y otros indicadores importantes, notificándonos solo cuando es necesaria la intervención humana.
Alternativas
Analizamos algunas alternativas a los recursos personalizados, como los controladores de acceso mutacional y los sistemas de plantillas. Sin embargo, todos ellos están llenos de serias dificultades en el trabajo, por lo que elegimos el camino de CRD.
Se usó un controlador de tolerancia a la mutación para ingresar los sidecars, una variable de entorno y otro soporte de tiempo de ejecución. Sin embargo, se enfrentó a varios problemas, por ejemplo, con la vinculación de recursos y la gestión de su ciclo de vida, cuando tales problemas no surgen en CRD.
Nota: Los sistemas de plantillas, como los diagramas de Helm, también se usan ampliamente para ejecutar aplicaciones con configuraciones similares. Sin embargo, nuestras aplicaciones de producción son demasiado diversas para administrarlas con plantillas. Además, durante la implementación continua, el uso de plantillas generará demasiados errores.
Trabajo futuro
Ahora estamos lidiando con una carga mixta en todos nuestros clústeres. Para admitir procesos similares de diferentes tipos y tamaños, trabajamos en las siguientes áreas:
- Un grupo de grupos distribuye grandes aplicaciones entre grupos para proporcionar escalabilidad y estabilidad.
- Garantizar la estabilidad, escalabilidad y visibilidad del clúster para crear la conexión de la aplicación y su SLA.
- Gestión de recursos y cuotas para que las aplicaciones no entren en conflicto entre sí, y la escala del clúster esté controlada por nosotros.
- Nueva plataforma CI / CD para soportar y desplegar aplicaciones en Kubernetes.