Otra opción para lograr esto sería usar ramas y control de versiones, donde las ramas de producción y desarrollo parten de un repositorio central, y las diferencias entre las ramas son claramente visibles. Esta puede ser una opción viable para algunos equipos de trabajo, pero la mecánica de moverse entre ramas se convierte en un reto cuando deseamos desplegar software simultáneamente en diferentes entornos (por ejemplo, un CI/CD que se implementa en varias regiones diferentes de la nube).
En consecuencia, la mayoría de los desarrolladores terminan con un sistema de plantillas . Un sistema de plantillas combina plantillas, que forman la columna vertebral centralizada de la configuración de la aplicación, con parámetros que especializan la plantilla para una configuración de entorno específica. De esta manera, podemos tener una configuración compartida en general con una deliberada personalización (y fácil de entender) cuando sea necesario. Hay una amplia variedad de sistemas de plantillas para Kubernetes, pero el más popular con diferencia es un sistema llamado Helm ( https://helm.sh ).
En Helm, una aplicación es un paquete formado por un conjunto de archivos llamado carta náutica (los chistes de náutica abundan en el mundo de los contenedores y de Kubernetes). La carta náutica empieza con un archivo chart.yaml , que define los metadatos de la propia carta:
apiVersion: v1 appVersion: "1.0" description: A Helm chart for our frontend journal server. name: frontend version: 0.1.0
Este archivo se coloca en la raíz del directorio de la carta náutica (por ejemplo , frontend/ ). Dentro de este directorio, hay un directorio de plantillas, en el que se colocan las plantillas. Una plantilla es básicamente un archivo YAML como los de los ejemplos anteriores, con algunos de los valores del archivo reemplazados con referencias a parámetros. Por ejemplo, imaginemos que queremos parametrizar el número de réplicas en el frontend. Anteriormente, esto es lo que tenía Deployment:
... spec: replicas: 2 ...
En el archivo de plantillas ( frontend-deployment.tmpl ), se ve de la siguiente forma:
... spec: replicas: {{ .replicaCount }} ...
Esto significa que cuando despleguemos la carta náutica, sustituiremos el valor por réplicas con el parámetro apropiado. Los propios parámetros están definidos en el archivo values.yaml . Habrá un archivo de valores por cada entorno en el que se debe implementar la aplicación. El archivo de valores para esta sencilla carta náutica se vería así:
replicaCount: 2
Juntando todo esto, podemos desplegar esta carta náutica usando la herramienta helm, como se muestra a continuación:
helm install path/to/chart --values path/to/environment/values.yaml
Esto parametriza la aplicación y la implementa en Kubernetes. Con el tiempo, estas parametrizaciones crecerán para incluir la variedad de diferentes entornos de la aplicación.
Mejores prácticas en el despliegue de servicios
Kubernetes es un sistema potente que puede parecer complicado. Pero poner en marcha una aplicación básica y tener éxito puede resultar fácil si utilizamos las siguientes prácticas:
• La mayoría de los servicios deberían desplegarse como recursos Deployments. Los Deployments crean réplicas idénticas en redundancia y escala.
• Los Deployments se pueden presentar utilizando un Service, que es un equilibrador de carga. Un Service se puede presentar dentro de un clúster (por defecto) o externamente. Si deseamos presentar una aplicación HTTP, podemos utilizar un controlador Ingress para agregar cosas como solicitar enrutamiento y SSL.
• Eventualmente, estaremos interesados en parametrizar la aplicación para hacer su configuración más reutilizable en diferentes entornos. Las herramientas de empaquetado como Helm son la mejor opción para este tipo de parametrización.
La aplicación creada en este capítulo es sencilla, pero contiene casi todos los conceptos que necesitaremos para crear aplicaciones más grandes y complejas. Comprender cómo encajan las piezas y cómo utilizar los componentes más importantes de Kubernetes es clave para tener éxito cuando trabajamos con esta herramienta.
Sentar unas buenas bases en el control de versiones, la revisión de código y la ininterrumpida entrega del servicio nos asegurará que lo que creemos se creará de una manera sólida. A medida que progresemos sobre los temas más avanzados en los siguientes capítulos, habrá que tener en cuenta esta información fundamental.
CAPÍTULO 2
Flujos de trabajo para desarrolladores
Kubernetes se creó para operar software de manera confiable. Simplifica el despliegue y la gestión de software con una API orientada a la aplicación, con propiedades de autorregeneración y herramientas útiles como Deployments (implementaciones) para la puesta en marcha de software con tiempo de inactividad cero. Aunque todas estas herramientas tienen su utilidad, no contribuyen de forma importante a facilitar el desarrollo de aplicaciones en Kubernetes. Además, a pesar de que muchos clústeres están diseñados para ejecutar aplicaciones en el entorno de producción —y, por lo tanto, rara vez se accede a ellos mediante los flujos de trabajo de los desarrolladores—, también es fundamental permitir que los flujos de trabajo de desarrollo tengan como objetivo Kubernetes, y esto normalmente significa tener un clúster o al menos una parte de un clúster destinado a desarrollo. La configuración de este tipo de clústeres para facilitar el desarrollo de aplicaciones en Kubernetes es un aspecto necesario para asegurar el éxito. Si no hay ningún código que se cree para nuestro clúster, el clúster por sí mismo no va a conseguir mucho.
Antes de describir las mejores prácticas para la creación de clústeres de desarrollo, merece la pena establecer los objetivos para dichos clústeres. Obviamente, el objetivo final es hacer posible que los desarrolladores puedan crear aplicaciones en Kubernetes fácilmente y de forma rápida. Pero ¿qué significa eso en la práctica y cómo se refleja en las características prácticas del clúster de desarrollo?
Es útil identificar las fases de interacción del desarrollador con el clúster.
La primera fase es la de incorporación . Esto ocurre cuando un nuevo desarrollador se une al equipo de trabajo. Esta fase incluye facilitar al usuario el acceso al clúster, así como proporcionarle orientación en su primer despliegue. El objetivo para esta fase es conseguir que el desarrollador adquiera experiencia en un corto espacio de tiempo. Para este proceso deberíamos establecer el objetivo de Key Performance Indicator (indicador clave de desempeño) (KPI). Un objetivo razonable sería que el usuario pudiera pasar de la nada a poder dirigir la ejecución de la aplicación en curso en menos de media hora. Cada vez que alguien se incorpore al equipo de trabajo, comprobaremos cómo nos va con este objetivo.
La segunda fase es la de desarrollo . Esta es la actividad diaria del desarrollador. El objetivo de esta fase es asegurar una iteración y una depuración rápidas. Los desarrolladores necesitan pasar código al clúster rápidamente y de forma repetitiva. También deben ser capaces de probar su código y depurarlo cuando no funciona correctamente. El KPI para esta fase es más difícil de medir, pero se puede estimar midiendo el tiempo en obtener una pull request (petición de validación) (PR) o el tiempo empleado en el cambio y la ejecución en el clúster, o con encuestas sobre la productividad que percibe el usuario, o ambas. También podremos medirlo en la productividad global de los equipos de trabajo.
Читать дальше