Southbridge en Chelyabinsk y Bitrix en Kubernetes

En Cheliábinsk se llevan a cabo meetups para administradores de sistemas Sysadminka, y en el último de ellos hice una presentación sobre nuestra solución para ejecutar aplicaciones en 1C-Bitrix en Kubernetes.

¿Bitrix, Kubernetes, Ceph: una combinación excelente?

Les contaré cómo reunimos todo esto en una solución funcional.

¡Vamos!

Southbridge en Chelyabinsk y Bitrix en Kubernetes

El meetup tuvo lugar el 18 de abril en Cheliábinsk. Sobre nuestros meetups se puede leer en Timepad y ver en YouTube.

Si quieren venir a nosotros como ponentes o como oyentes, ¡bienvenidos! Escriban a vadim.isakanov@gmail.com y en Telegram t.me/vadimisakanov.

Mi presentación

Southbridge en Chelyabinsk y Bitrix en Kubernetes

Diapositivas

La solución «Bitrix en Kubernetes, versión Southbridge 1.0»

Hablaré de nuestra solución en un formato «para principiantes en Kubernetes», como se hizo en el meetup. Pero supongo que las palabras Bitrix, Docker, Kubernetes, Ceph les son familiares, al menos a nivel de artículos en Wikipedia.

¿Qué hay disponible sobre Bitrix en Kubernetes?

En toda la Internet hay muy poca información sobre cómo funcionan las aplicaciones en Bitrix en Kubernetes.
Solo encontré estos materiales:

La presentación de Alexander Serbul y Anton Tuzlukov de Qsoft:

Reproducir video

Recomiendo escucharlo.

Desarrollo de una solución propia por el usuario serkyron en Habré.
También encontré tal solución.

Yyyy… en realidad, eso es todo.

Aviso que no hemos comprobado la calidad de las soluciones en los enlaces anteriores 🙂
Por cierto, al preparar nuestra solución hablé con Alexander Serbul, su presentación aún no había sido publicada, por lo que en mis diapositivas hay un punto que dice «Bitrix no utiliza Kubernetes».

Pero ya hay muchas imágenes Docker listas para trabajar con Bitrix en Docker: https://hub.docker.com/search?q=bitrix&type=image

¿Es suficiente esto para crear una solución completa para Bitrix en Kubernetes?
No. Hay una gran cantidad de problemas que necesitan ser resueltos.

¿Cuáles son los problemas con Bitrix en Kubernetes?

El primero: las imágenes listas de Dockerhub no son adecuadas para Kubernetes.

Si queremos construir una arquitectura de microservicios (y generalmente queremos en Kubernetes), la aplicación en Kubernetes debe dividirse en contenedores y lograr que cada contenedor realice una pequeña función (y lo haga bien). ¿Por qué solo una? En pocas palabras: cuanto más simple, más confiable.
Si quieren más información, por favor vean este artículo y video: https://habr.com/ru/company/southbridge/blog/426637/

Las imágenes Docker en Dockerhub están construidas principalmente bajo el principio de «todo en uno», por eso tuvimos que crear nuestra propia solución, incluso creando las imágenes desde cero.

El segundo: el código del sitio se corrige desde el panel de administración.

Se creó una nueva sección en el sitio web: se actualizó el código (se añadió un directorio con el nombre de la nueva sección).

Se cambiaron las propiedades del componente desde el panel de administración: el código cambió.

Kubernetes no puede trabajar con esto 'por defecto'; los contenedores deben ser inmutables (Stateless).

Razón: cada contenedor (pod) en el clúster solo procesa una parte del tráfico. Si se cambia el código solo en un contenedor (pod), entonces en diferentes pods el código será diferente, el sitio funcionará de manera distinta y a diferentes usuarios se les mostrarán diferentes versiones del sitio. Así no se puede vivir.

Tercero: se debe resolver el problema del despliegue.

Si tenemos un monolito y un servidor 'clásico', todo es bastante simple: desplegamos una nueva base de código, realizamos la migración de la base de datos y cambiamos el tráfico a la nueva versión del código. El cambio ocurre de manera instantánea.
Si nuestro sitio está en Kubernetes, descompuesto en microservicios y hay muchos contenedores con código, oh. Necesitamos construir contenedores con la nueva versión del código, desplegarlos en lugar de los antiguos, realizar correctamente la migración de la base de datos, y en ideal hacerlo de manera invisible para los visitantes. Afortunadamente, Kubernetes nos ayuda en esto, apoyando una variedad de tipos de despliegue.

Cuarto: se debe resolver el problema del almacenamiento de estática.

Si su sitio pesa 'solo' 10 gigabytes y lo despliega completamente en contenedores, obtendrá contenedores de 10 gigabytes, que se desplegarán eternamente.
Es necesario almacenar las partes 'más pesadas' del sitio fuera de los contenedores, y surge la pregunta de cómo hacerlo correctamente.

Lo que no está en nuestra solución.

Todo el código de Bitrix no está dividido en microfunciones/microservicios (de tal manera que el registro sea separado, el módulo de la tienda en línea sea separado, etc.). Almacenamos toda la base de código en cada contenedor en su totalidad.

La base no se almacena en Kubernetes (aunque he implementado soluciones con la base en Kubernetes para entornos de desarrolladores, pero no para producción).

Los administradores del sitio notarán que el sitio está funcionando en Kubernetes. La función 'verificación del sistema' no funciona correctamente; para editar el código del sitio desde el panel de administración, primero se debe presionar el botón 'quiero editar el código'.

Hemos resuelto los problemas, tenemos claridad sobre la necesidad de implementar microservicios, el objetivo está claro: crear un sistema funcional para ejecutar aplicaciones en Bitrix en Kubernetes, preservando tanto las capacidades de Bitrix como las ventajas de Kubernetes. Comenzamos la implementación.

Arquitectura

Muchos pods «activos» con servidor web (workers).
Un pod para tareas programadas (debe haber solo uno).
Un pod de actualización para editar el código del sitio desde el panel de administración (también debe haber solo uno).

Southbridge en Chelyabinsk y Bitrix en Kubernetes

Estamos resolviendo cuestiones:

  • ¿Dónde almacenar las sesiones?
  • ¿Dónde almacenar la caché?
  • ¿Dónde almacenar los archivos estáticos? No podemos colocar gigabytes de archivos estáticos en un montón de contenedores.
  • ¿Cómo funcionará la base de datos?

Imagen de Docker

Comenzamos con la construcción de la imagen de Docker.

La opción ideal es tener una imagen universal, a partir de la cual obtenemos tanto pods de workers como pods con tareas programadas, y pods de actualización.

Hemos creado precisamente esa imagen..

Incluye nginx, apache/php-fpm (se puede elegir al construir), msmtp para el envío de correos y cron.

Al construir la imagen, se copia la base de código completa del sitio en el directorio /app (excepto aquellas partes que trasladaremos a un almacenamiento compartido separado).

Microservicios, servicios

Pods de worker:

  • Contenedor con nginx + contenedor apache/php-fpm + msmtp
  • No se pudo trasladar msmtp a un microservicio separado, Bitrix comienza a quejarse de que no puede enviar correos directamente.
  • En cada contenedor está la base de código completa.
  • Prohibición de modificar el código en los contenedores.

Pod de cron:

  • Contenedor con apache, php, cron
  • incluye la base de código completa
  • prohibición de modificar el código en los contenedores

Pod de actualización:

  • Contenedor con nginx + contenedor apache/php-fpm + msmtp
  • no hay prohibición de modificar el código en los contenedores

almacenamiento de sesiones

almacenamiento de caché Bitrix

También es importante: almacenamos las contraseñas para la conexión a todo, desde la base de datos hasta el correo, en secretos de kubernetes. Obtenemos un beneficio, las contraseñas solo son visibles para aquellos a quienes damos acceso a los secretos, no para todos, quienes tienen acceso a la base de código del proyecto.

Almacenamiento para archivos estáticos

Se puede usar cualquier cosa: ceph, nfs (pero no recomendamos nfs para producción), almacenamiento en red de proveedores «en la nube», etc.

El almacenamiento deberá conectarse en los contenedores al directorio /upload/ del sitio y otros directorios con archivos estáticos.

Base de datos

Para simplificar, recomendamos colocar la base fuera de Kubernetes. Tener la base dentro de Kubernetes es una tarea compleja, complicará el esquema significativamente.

Almacenamiento de sesiones

Usamos memcached 🙂

Se encarga bien del almacenamiento de sesiones, se puede agrupar y se soporta "nativamente" como session.save_path en PHP. Este sistema ha sido implementado muchas veces en la clásica arquitectura monolítica, cuando construíamos clústeres con un gran número de servidores web. Para el despliegue usamos helm.

$ helm install stable/memcached --name session

php.ini — aquí se definen las configuraciones para el almacenamiento de sesiones en memcached dentro de la imagen

Usamos variables de entorno para pasar datos sobre los hosts de memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Esto permite utilizar el mismo código en entornos dev, stage, test, prod (los nombres de los hosts de memcached serán diferentes en ellos, por lo que necesitamos pasar un nombre único de host para las sesiones en cada entorno).
Almacenamiento en caché de Bitrix

Necesitamos un almacenamiento tolerante a fallos, al que todos los pods puedan escribir y desde el que puedan leer.

También usamos memcached.
Esta solución es recomendada por Bitrix.

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php — aquí en Bitrix se establece dónde se almacena la caché

También usamos variables de entorno.

Tareas programadas

Hay diferentes enfoques para ejecutar tareas programadas en Kubernetes.

  • despliegue separado con un pod para ejecutar tareas programadas
  • cronjob para ejecutar tareas programadas (si es una aplicación web — con wget https://$host$cronjobname, o kubectl exec dentro de uno de los pods worker, etc.)
  • etc.

Se puede debatir sobre cuál es el más correcto, pero en este caso elegimos la opción "despliegue separado con pods para tareas programadas"

Cómo se hace:

  • agregamos las tareas programadas a través de ConfigMap o mediante el archivo config/addcron
  • ejecutamos un contenedor idéntico al pod worker en una sola instancia + permitimos la ejecución de tareas programadas en él
  • se utiliza la misma base de código, gracias a la unificación, la compilación del contenedor es simple

Qué beneficios obtenemos:

  • tenemos tareas programadas funcionando en un entorno idéntico al entorno de los desarrolladores (docker)
  • no es necesario "reescribir" las tareas programadas para Kubernetes, funcionan en la misma forma y con la misma base de código que antes
  • las tareas programadas pueden ser agregadas por todos los miembros del equipo con derechos de commit en la rama de producción, no solo por los administradores

Módulo Southbridge K8SDeploy y edición de código desde el panel de administración

¿Acaso no hablamos sobre la actualización del pod?
¿Y cómo dirigir el tráfico hacia allí?
¡Hurra, hemos escrito un módulo para esto en PHP 🙂! Es un pequeño módulo clásico para Bitrix. Aún no está disponible públicamente, pero planeamos hacerlo accesible.
El módulo se instala como un módulo normal en Bitrix:

Southbridge en Chelyabinsk y Bitrix en Kubernetes

Y se ve así:

Southbridge en Chelyabinsk y Bitrix en Kubernetes

Permite establecer una cookie que identifica al administrador del sitio y permite que Kubernetes envíe tráfico al pod de actualización.

Cuando los cambios están completos, hay que presionar git push. Los cambios en el código se enviarán a git, luego el sistema construirá la imagen con la nueva versión del código y la desplegará en el clúster, reemplazando los pods antiguos.

Sí, un poco torpe, pero al mismo tiempo mantenemos la arquitectura de microservicios y no le quitamos a los usuarios de Bitrix su opción favorita de modificar el código desde el panel de administración. Al final, esta es una opción, se puede resolver la tarea de modificación de código de otra manera.

Chart de Helm

Para construir aplicaciones en Kubernetes, generalmente utilizamos el gestor de paquetes Helm.
Para nuestra solución de Bitrix en Kubernetes, Sergey Bondarev, nuestro administrador de sistemas principal, escribió un chart de Helm específico.

Realiza la construcción de pods worker, upgrade y cron, configura ingress, servicios y pasa variables desde los secretos de Kubernetes a los pods.

Almacenamos el código en Gitlab, y también iniciamos la construcción de Helm desde Gitlab.

En resumen, se ve así:

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

Helm también permite realizar un "rollback" sin fisuras si algo sale mal durante el despliegue. Es agradable no estar en pánico "arreglando el código por ftp porque el entorno de producción se cayó", sino que Kubernetes lo hace automáticamente, y además sin tiempo de inactividad.

Despliegue

Sí, somos fanáticos de Gitlab & Gitlab CI, lo usamos 🙂
Al hacer un commit en Gitlab en el repositorio del proyecto, Gitlab inicia un pipeline que despliega una nueva versión del entorno.

Etapas:

  • build (construimos una nueva imagen de Docker)
  • test (probamos)
  • clean up (eliminamos el entorno de prueba)
  • push (lo enviamos al registro de Docker)
  • deploy (desplegamos la aplicación en Kubernetes a través de Helm).

Southbridge en Chelyabinsk y Bitrix en Kubernetes

¡Hurra, listo, ¡implementamos!
O planteamos preguntas, si las hay.

Así que, ¿qué hicimos?

Desde un punto de vista técnico:

  • dockerizamos Bitrix;
  • "cortamos" Bitrix en contenedores, cada uno realizando funciones mínimas;
  • logramos que los contenedores sean stateless;
  • resolvimos el problema de actualizar Bitrix en Kubernetes;
  • todas las funciones de Bitrix continuaron funcionando (casi todas);
  • trabajamos el despliegue en Kubernetes y el rollback entre versiones.

Desde un punto de vista empresarial:

  • tolerancia a fallos;
  • herramientas de Kubernetes (integración sencilla con Gitlab CI, despliegue sin fisuras, etc);
  • contraseñas en secretos (solo visible para aquellos a quienes se les otorgó acceso directo a las contraseñas);
  • es conveniente crear entornos adicionales (para desarrollo, pruebas, etc.) dentro de una infraestructura única.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster