El dispositivo Helm y sus trampas

El dispositivo Helm y sus trampas
Concepto de transporte de mercancías Typhon, Anton Swanepoel

Mi nombre es Dmitry Sugrobov, soy desarrollador en Leroy Merlin. En este artículo, le diré por qué es necesario Helm, cómo simplifica el trabajo con Kubernetes, qué ha cambiado en la tercera versión y cómo usarlo para actualizar aplicaciones en producción sin tiempo de inactividad.

Este es un resumen basado en un discurso en una conferencia. Conferencia @Kubernetes by Soluciones en la nube Mail.ru — si no quieres leer, mira el vídeo.

Por qué utilizamos Kubernetes en producción

Leroy Merlin es líder en el mercado minorista de bricolaje en Rusia y Europa. Nuestra empresa cuenta con más de cien desarrolladores, 33 empleados internos y una gran cantidad de personas que visitan los hipermercados y el sitio web. Para hacerlos felices a todos, decidimos seguir enfoques estándar de la industria. Desarrollar nuevas aplicaciones utilizando arquitectura de microservicios; utilizar contenedores para aislar ambientes y garantizar una entrega adecuada; y utilizar Kubernetes para la orquestación. El precio del uso de orquestadores se está abaratando rápidamente: el número de ingenieros competentes en la tecnología está creciendo en el mercado y están apareciendo proveedores que ofrecen Kubernetes como servicio.

Todo lo que hace Kubernetes, por supuesto, se puede hacer de otras maneras, por ejemplo, cubriendo algunos Jenkins y docker-compose con scripts, pero ¿por qué complicarse la vida si existe una solución confiable y lista para usar? Por eso llegamos a Kubernetes y lo hemos estado usando en producción durante un año. Actualmente contamos con veinticuatro clústeres de Kubernetes, el más antiguo de los cuales tiene más de un año y cuenta con unos doscientos pods.

La maldición de los grandes archivos YAML en Kubernetes

Para iniciar un microservicio en Kubernetes, crearemos al menos cinco archivos YAML: para implementación, servicio, ingreso, ConfigMap, secretos, y los enviaremos al clúster. Para la siguiente aplicación escribiremos el mismo paquete de jambas, con la tercera escribiremos otro, y así sucesivamente. Si multiplicamos el número de documentos por el número de entornos, ya obtendremos cientos de archivos, y esto aún sin tener en cuenta los entornos dinámicos.

El dispositivo Helm y sus trampas
Adam Reese, mantenedor principal de Helm, introdujo el concepto de "Ciclo de desarrollo en Kubernetes", que se parece a esto:

  1. Copiar YAML: copia un archivo YAML.
  2. Pegue YAML: péguelo.
  3. Corregir sangrías: corregir sangrías.
  4. Repita, repita de nuevo.

La opción funciona, pero hay que copiar los archivos YAML muchas veces. Para cambiar este ciclo, se inventó Helm.

¿Qué es el timón?

En primer lugar, Helm... gerente de empaquetación, que le ayuda a encontrar e instalar los programas que necesita. Para instalar, por ejemplo, MongoDB, no es necesario ir al sitio web oficial y descargar binarios, simplemente ejecutar el comando helm install stable/mongodb.

En segundo lugar, Helm... motor de plantillas, ayuda a parametrizar archivos. Volvamos a la situación con los archivos YAML en Kubernetes. Es más fácil escribir el mismo archivo YAML, agregarle algunos marcadores de posición, en los que Helm sustituirá los valores. Es decir, en lugar de un gran conjunto de andamios, habrá un conjunto de plantillas en las que se sustituirán los valores requeridos en el momento adecuado.

En tercer lugar, Helm... maestro de implementación. Con él puedes instalar, deshacer y actualizar aplicaciones. Averigüemos cómo hacer esto.

El dispositivo Helm y sus trampas

Cómo utilizar Helm para implementar sus propias aplicaciones

Instalemos el cliente Helm en su computadora, siguiendo el oficial instrucciones. A continuación, crearemos un conjunto de archivos YAML. En lugar de especificar valores específicos, dejaremos marcadores de posición, que Helm completará con información en el futuro. Un conjunto de estos archivos se denomina gráfico de Helm. Se puede enviar al cliente de la consola Helm de tres formas:

  • indicar una carpeta con plantillas;
  • empaquete el archivo en un .tar y apúntelo;
  • coloque la plantilla en un repositorio remoto y agregue un enlace al repositorio en el cliente Helm.

También necesita un archivo con valores: valores.yaml. Los datos de allí se insertarán en la plantilla. Creémoslo también.

El dispositivo Helm y sus trampas
La segunda versión de Helm tiene una aplicación de servidor adicional: Tiller. Se cuelga fuera de Kubernetes y espera solicitudes del cliente Helm y, cuando se le llama, sustituye los valores requeridos en la plantilla y la envía a Kubernetes.

El dispositivo Helm y sus trampas
Helm 3 es más simple: en lugar de procesar plantillas en el servidor, la información ahora se procesa completamente en el lado del cliente de Helm y se envía directamente a la API de Kubernetes. Esta simplificación mejora la seguridad del clúster y facilita el esquema de implementación.

¿Cómo funciona todo?

Ejecute el comando helm install. Indiquemos el nombre de la versión de la aplicación y proporcionemos la ruta a valores.yaml. Al final indicaremos el repositorio en el que se encuentra el gráfico y el nombre del gráfico. En el ejemplo, son "lmru" y "bestchart", respectivamente.

helm install --name bestapp --values values.yaml lmru/bestchart

El comando se puede ejecutar solo una vez, cuando se ejecuta nuevamente install necesitará usar upgrade. Para simplificar, en lugar de dos comandos, puede ejecutar el comando upgrade con llave adicional --install. Cuando se ejecuta por primera vez, Helm enviará un comando para instalar la versión y la actualizará en el futuro.

helm upgrade --install bestapp --values values.yaml lmru/bestchart

Errores de implementar nuevas versiones de una aplicación con Helm

En este punto de la historia, estoy jugando Quién quiere ser millonario con la audiencia y estamos averiguando cómo hacer que Helm actualice la versión de la aplicación. Смотреть видео.

Cuando estaba aprendiendo cómo funciona Helm, me sorprendió un comportamiento extraño al intentar actualizar las versiones de las aplicaciones en ejecución. Actualicé el código de la aplicación, cargué una nueva imagen en el registro de Docker, envié el comando de implementación y no pasó nada. A continuación se muestran algunas formas no del todo exitosas de actualizar aplicaciones. Al estudiar cada uno de ellos con más detalle, comenzará a comprender la estructura interna del instrumento y las razones de este comportamiento no obvio.

Método 1. No cambie la información desde el último lanzamiento

Como dice el dicho sitio web oficial Helm: "Los gráficos de Kubernetes pueden ser grandes y complejos, por lo que Helm intenta no tocar demasiado nada". Por lo tanto, si actualiza la última versión de la imagen de la aplicación en el registro de Docker y ejecuta el comando helm upgrade, entonces no pasará nada. Helm pensará que nada ha cambiado y que no es necesario enviar un comando a Kubernetes para actualizar la aplicación.

Aquí y a continuación, la última etiqueta se muestra únicamente como ejemplo. Cuando especifica esta etiqueta, Kubernetes descargará la imagen del registro de Docker cada vez, independientemente del parámetro imagePullPolicy. El uso de lo último en producción no es deseable y provoca efectos secundarios.

Método 2. Actualizar ETIQUETA en la imagen

Como está escrito en el mismo documentación, "Helm solo actualizará una aplicación si ha cambiado desde la última versión". Una opción lógica para esto parecería ser actualizar la ETIQUETA en la propia imagen de la ventana acoplable. Sin embargo, Helm no examina las imágenes de la aplicación y no tiene idea de ningún cambio en ellas. En consecuencia, al actualizar las etiquetas en la imagen, Helm no las conocerá y el comando de actualización de la aplicación no se enviará a Kubernetes.

Método 3: use una clave --force

El dispositivo Helm y sus trampas
Pasemos a los manuales y busquemos la clave requerida. La clave tiene más sentido. --force. A pesar del nombre obvio, el comportamiento es diferente al esperado. En lugar de forzar una actualización de la aplicación, su verdadero propósito es restaurar una versión que se encuentra en estado FALLADO. Si no utiliza esta clave, debe ejecutar los comandos secuencialmente helm delete && helm install --replace. Se sugiere utilizar la clave en su lugar. --force, que automatiza la ejecución secuencial de estos comandos. Más información en este solicitud de extracción. Desafortunadamente, esta clave no funcionará para indicarle a Helm que actualice la versión de la aplicación.

Método 4. Cambiar etiquetas directamente en Kubernetes

El dispositivo Helm y sus trampas
Actualizar la etiqueta directamente en el clúster usando el comando kubectl edit - mala idea. Esta acción provocará una incoherencia en la información entre la aplicación en ejecución y la que se envió originalmente para su implementación. El comportamiento de Helm durante la implementación en este caso difiere de su versión: Helm 2 no hará nada y Helm 3 implementará la nueva versión de la aplicación. Para entender por qué, es necesario comprender cómo funciona Helm.

¿Cómo funciona Helm?

Para determinar si una aplicación ha cambiado desde su última versión, Helm puede utilizar:

  • ejecutar aplicación en Kubernetes;
  • nuevos valores.yaml y gráfico actual;
  • Información de publicación interna de Helm.

Para los más curiosos: ¿dónde almacena Helm información interna sobre lanzamientos?Al ejecutar el comando helm history, obtendremos toda la información sobre las versiones instaladas usando Helm.

El dispositivo Helm y sus trampas
También hay información detallada sobre las plantillas y valores enviados. Podemos solicitarlo:

El dispositivo Helm y sus trampas
En la segunda versión de Helm, esta información se encuentra en el mismo espacio de nombres donde se ejecuta Tiller (kube-system por defecto), en ConfigMap, marcado con la etiqueta “OWNER=TILLER”:

El dispositivo Helm y sus trampas
Cuando apareció la tercera versión de Helm, la información se trasladó a secretos y al mismo espacio de nombres donde se ejecutaba la aplicación. Gracias a esto, fue posible ejecutar varias aplicaciones simultáneamente en diferentes espacios de nombres con el mismo nombre de versión. En la segunda versión, fue un serio dolor de cabeza cuando los espacios de nombres están aislados pero pueden influirse entre sí.

El dispositivo Helm y sus trampas

El segundo Helm, cuando intenta comprender si se necesita una actualización, utiliza solo dos fuentes de información: lo que se le proporciona ahora y la información interna sobre las versiones, que se encuentra en el ConfigMap.

El dispositivo Helm y sus trampas
El tercer Helm utiliza una estrategia de fusión de tres vías: además de esa información, también tiene en cuenta la aplicación que se está ejecutando en este momento en Kubernetes.

El dispositivo Helm y sus trampas
Por esta razón, la versión anterior de Helm no hará nada, ya que no tiene en cuenta la información de la aplicación en el clúster, pero Helm 3 recibirá los cambios y enviará la nueva aplicación para su implementación.

Método 5. Utilice el modificador --recreate-pods

con una llave --recreate-pods puedes lograr lo que originalmente planeaste lograr con la llave --force. Los contenedores se reiniciarán y, de acuerdo con la política imagePullPolicy: Siempre para la etiqueta más reciente (más sobre esto en la nota a pie de página anterior), Kubernetes descargará y lanzará una nueva versión de la imagen. Esto no se hará de la mejor manera: sin tener en cuenta el tipo de estrategia de implementación, cerrará abruptamente todas las instancias de aplicaciones antiguas y comenzará a ejecutar otras nuevas. Durante el reinicio, el sistema no funcionará, los usuarios sufrirán.

En el propio Kubernetes también existió un problema similar durante mucho tiempo. Y ahora, 4 años después de la inauguración Inconveniente, el problema se solucionó y, a partir de la versión 1.15 de Kubernetes, aparece la capacidad de reiniciar los pods.

Helm simplemente apaga todas las aplicaciones y lanza nuevos contenedores cercanos. No puede hacer esto en producción para no provocar un tiempo de inactividad de la aplicación. Esto sólo es necesario para necesidades de desarrollo y sólo se puede realizar en entornos escénicos.

¿Cómo actualizar la versión de la aplicación usando Helm?

Cambiaremos los valores enviados a Helm. Normalmente, estos son valores que se sustituyen en lugar de la etiqueta de imagen. En el caso de la última versión, que se utiliza a menudo en entornos improductivos, la información modificable es una anotación, que es inútil para el propio Kubernetes, y para Helm actuará como una señal de la necesidad de actualizar la aplicación. Opciones para completar el valor de la anotación:

  1. Valor aleatorio usando la función estándar - {{ randAlphaNum 6 }}.
    Hay una advertencia: después de cada implementación que utilice un gráfico con dicha variable, el valor de la anotación será único y Helm asumirá que hay cambios. Resulta que siempre reiniciaremos la aplicación, aunque no hayamos cambiado su versión. Esto no es crítico, ya que no habrá tiempo de inactividad, pero sigue siendo desagradable.
  2. Pegar actual fecha y hora - {{ .Release.Date }}.
    Una variante es similar a un valor aleatorio con una variable única permanentemente.
  3. Una forma más correcta es utilizar sumas de control. Este es el SHA de la imagen o el SHA de la última confirmación en git. {{ .Values.sha }}.
    Deberán contarse y enviarse al cliente Helm en el lado que llama, por ejemplo en Jenkins. Si la aplicación ha cambiado, la suma de verificación cambiará. Por lo tanto, Helm sólo actualizará la aplicación cuando sea necesario.

Resumamos nuestros intentos.

  • Helm realiza cambios de la manera menos invasiva, por lo que cualquier cambio en el nivel de imagen de la aplicación en el Registro Docker no resultará en una actualización: no sucederá nada después de ejecutar el comando.
  • Llave --force se utiliza para restaurar versiones problemáticas y no está asociado con actualizaciones forzadas.
  • Llave --recreate-pods Actualizará las aplicaciones a la fuerza, pero lo hará de forma vandálica: apagará bruscamente todos los contenedores. Los usuarios sufrirán esto; no deberías hacer esto en producción.
  • Realice cambios directamente en el clúster de Kubernetes usando el comando kubectl edit No lo hagas: romperemos la coherencia y el comportamiento diferirá según la versión de Helm.
  • Con el lanzamiento de la nueva versión de Helm, han aparecido muchos matices. Los problemas en el repositorio de Helm se describen en un lenguaje claro y le ayudarán a comprender los detalles.
  • Agregar una anotación editable a un gráfico lo hará más flexible. Esto le permitirá implementar la aplicación correctamente, sin tiempo de inactividad.

Un pensamiento de “paz mundial” que funciona en todos los ámbitos de la vida: lea las instrucciones antes de usarlo, no después. Sólo con información completa será posible construir sistemas confiables y hacer felices a los usuarios.

Otros enlaces relacionados:

  1. Cumplir con el Casco 3
  2. Sitio web oficial de timón
  3. Repositorio de Helm en GitHub
  4. 25 herramientas útiles de Kubernetes: implementación y gestión

Este informe fue presentado por primera vez en Conferencia @Kubernetes por Mail.ru Soluciones en la nube. Mirar видео otras actuaciones y suscríbete a anuncios de eventos en Telegram Acerca de Kubernetes en Mail.ru Group.

Fuente: habr.com

Añadir un comentario