Construir, desplegar y observar aplicaciones de forma uniforme con Waypoint

Escrito por el .
gnu-linux planeta-codigo software programacion
Enlace permanente Comentarios

Cuando se tienen muchas aplicaciones si no se tienen unos procesos definidos seguramente cada una requerirá su propio proceso, herramientas de construcción y despliegue. Estas diferencias añaden complejidad y no es deseable para tener un flujo de trabajo ágil. La herramienta Waypoint de HashiCorp permite construir una aplicación independientemente del lenguaje en el que esté implementada, desplegar en diferentes proveedores de computación en la nube y observar las aplicaciones una vez desplegadas, todo con la misma herramienta y de forma uniforme que simplifica en gran medida el flujo de desarrollo.

HashiCorp Waypoint

HashiCorp

No son pocas los lenguajes de programación actuales y hay varias plataformas de computación en la nube. En una organización grande seguramente haya una diversidad de aplicaciones en cuanto a lenguaje de programación e incluso quizá utiliza varios proveedores de computación en la nube, cuanto menos es deseable tratar a todas las aplicaciones igual independientemente de su lenguaje para que el flujo sea uniforme para todas las aplicaciones ni es bueno acoplarse a un determinado proveedor de computación para tener la libertad y flexibilidad en un futuro de cambiar a otro si las circunstancias cambian.

Las aplicaciones para se ejecución en su ciclo de vida esencialmente necesitan al menos dos operaciones, una es su construcción a partir de código fuente y la segunda es su despliegue en el entorno de ejecución. Hay una tercera adicional que es la de publicación consistente en enviarle tráfico, el despliegue simplemente consiste en ejecutar en el entorno pero sin tráfico para la versión desplegada, esto es, separando el despliegue de la publicación.

HashiCorp ofrece varias herramientas que cada una cubre una necesidad de las aplicaciones, y de las que varias ya he escrito algunos artículos. Algunas de sus herramientas más conocidas son Terraform para tratar la infraestructura como código, Consul para la conectividad entre servicios y Vault centrada en la seguridad como servicio pero tiene otras muy interesantes como Vagrant para la virtualización en local, Packer para la construcción de imágenes de máquinas virtuales, Boundary también el apartado de seguridad o Nomad una alternativa similar a Kubernetes pero mucho más sencilla de ejecutar en local.

En el caso de la construcción y despliegue, la herramienta que proporciona HashiCorp es Waypoint.

Waypoint

Waypoint de HashiCorp es una herramienta que permite construir una aplicación y realizar el despliegue independientemente del lenguaje empleado por la aplicación y la infraestructura de ejecución que se utilice.

Con Waypoint es posible construir cualquier aplicación ya se trate de una aplicación programada en Java, Node o Python y desplegarla en cualquier proveedor en la nube soportado como Amazon Web Services, Google Cloud Platform o Microsoft Azure.

El utilizar la misma herramienta uniformiza el ciclo de vida de las aplicaciones y tratan a todas por igual simplificando el flujo de desarrollo, de forma similar que una propiedad de los contenedores es que permiten ejecutar procesos independientemente del lenguaje de programación en el que están programados, Waypoint uniformiza la construcción y despliegue.

Waypoint en la fase de construcción o build en esencia lo que hace es construir una imagen de contenedor que luego es la que es desplegada. La construcción de la imagen puede ser con un habitual archivo Dockerfile de Docker pero también a través de Buildpacks. Una vez construida la imagen es almacenada en un registro de imágenes. La fase de construcción suele estar automatizada por una herramienta de CI/CD como Jenkins, además se soportan otras como GitHub Actions.

En la fase de despliegue o deploy la imagen es puesta en ejecución en la plataforma de despliegue seleccionada, se soportan varias incluyendo las más conocidas como Kubernetes, Nomad, AWS EC2, AWS ECS, AWS Lambdas, Google Cloud Run y Azure Containers Instances incluyendo Docker en local.

Si la plataforma de despliegue lo soporta la fase de publicación o release consiste en enviar tráfico a la aplicación.

Instalación de Waypoint

Al igual que muchas de las otras herramientas de HashiCorp que están implementadas con el lenguaje de programación Go, Waypoint es un único binario con lo que basta descargar la última versión disponible y en el caso de GNU/Linux copiarla al directorio /usr/local/bin/ donde los usuarios pueden instalar programas sin que entren en conflicto con los instalados por los paquetes de la distribución.

1
2
3
$ ls -lh /usr/local/bin/
-rwxr-xr-x 1 picodotdev picodotdev  23M ene 10 11:31 pack
-rwxr-xr-x 1 picodotdev picodotdev 180M dic 15 18:59 waypoint
ls-bin.sh

Inicio del servidor de Waypoint

Waypoint se ejecuta en modo servidor, en este ejemplo se inicia como un contenedor de Docker en local y ejecutar un comando para su inicialización.

1
2
$ waypoint install -platform=docker -accept-tos

waypoint-install.sh

Ofrece una interfaz gráfica en la que monitorizar trazas, builds, deployment y otros detalles. a la interfaz web se accede con el siguiente comando con la interfaz web accesible en la dirección https://localhost:9702/.

1
2
$ waypoint ui -authenticate

waypoint-ui-authenticate.sh

Una vez inicializado el servidor se puede iniciar sin necesidad de inicializarlo otra vez.

1
2
$ waypoint server run -accept-tos
$ waypoint server bootstrap -server-addr=127.0.0.1:9701 -server-tls-skip-verify
waypoint-server-run.sh

Construcción de un proyecto con Waypoint utilizando Buildpacks

En un artículo anterior mostraba cómo construir una aplicación con el lenguaje Java de Spring Boot con Gradle y Buildpacks para generar la imagen del contenedor.

Para la construcción con Buildpacks utilizaba el siguiente comando que a través de argumentos configuraban los buidpacks y construcción de la aplicación.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ pack build spring-injection-point \
    --env "BP_JVM_TYPE=JDK" \
    --env "BP_JVM_VERSION=11" \
    --env "BP_GRADLE_BUILT_ARTIFACT=app/build/distributions/app.zip" \
    --builder paketobuildpacks/builder-jammy-base \
    --buildpack gcr.io/paketo-buildpacks/ca-certificates \
    --buildpack gcr.io/paketo-buildpacks/syft \
    --buildpack gcr.io/paketo-buildpacks/procfile \
    --buildpack gcr.io/paketo-buildpacks/adoptium \
    --buildpack gcr.io/paketo-buildpacks/gradle \
    --buildpack gcr.io/paketo-buildpacks/executable-jar \
    --buildpack gcr.io/paketo-buildpacks/spring-boot \
    --default-process app \
    --path .
pack-build.sh

Utilizando el soporte de Buildpacks de Waypoint la definición de la construcción se especifican los mismos argumentos pero definidos en el archivo configuración de Waypoint. El comando init inicializa el proyecto en Waypoint a partir del archivo de su definición.

1
2
$ waypoint init

waypoint-init.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
project = "Waypoint"
app "spring-injection-point" {
  build {
    use "pack" {
      builder = "paketobuildpacks/builder:base"
      buildpacks = ["gcr.io/paketo-buildpacks/ca-certificates", "gcr.io/paketo-buildpacks/syft", "gcr.io/paketo-buildpacks/procfile", "gcr.io/paketo-buildpacks/adoptium", "gcr.io/paketo-buildpacks/gradle", "gcr.io/paketo-buildpacks/executable-jar", "gcr.io/paketo-buildpacks/spring-boot"]
      process_type = "app"
      static_environment = {
        BP_JVM_TYPE = "JRE"
        BP_JVM_VERSION = "11"
        BP_GRADLE_BUILT_ARTIFACT = "app/build/distributions/app.zip"
      }
    }
  }
  deploy {
    use "docker" {
      service_port = 8080
    }
  }
}
waypoint.hcl

En la documentación de Waypoint están especificados los argumentos que soporta cada uno de los builders.

Para lanzar únicamente construcción se puede lanzar con el siguiente comando.

1
2
$ waypoint build

waypoint-build.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

» Building spring-injection-point...

» Performing operation locally
✓ Running build v3
Creating new buildpack-based image using builder: paketobuildpacks/builder:base
✓ Creating pack client
✓ Building image
 │ [exporter] Adding label 'io.buildpacks.build.metadata'
 │ [exporter] Adding label 'io.buildpacks.project.metadata'
 │ [exporter] Setting default process type 'app'
 │ [exporter] Saving spring-injection-point...
 │ [exporter] *** Images (029d19ed3f4b):
 │ [exporter]       spring-injection-point
 │ [exporter] Reusing cache layer 'paketo-buildpacks/syft:syft'
 │ [exporter] Reusing cache layer 'paketo-buildpacks/adoptium:jdk'
 │ [exporter] Adding cache layer 'paketo-buildpacks/gradle:application'
 │ [exporter] Adding cache layer 'paketo-buildpacks/gradle:cache'
✓ Injecting entrypoint binary to image

Generated new Docker image: spring-injection-point:latest
✓ Running push build v2

Created artifact v2

» Variables used:
  VARIABLE | VALUE | TYPE | SOURCE  
-----------+-------+------+---------

waypoint-build.out

En este ejemplo donde todo se muestra en local no hace falta especificar una stanza registry ya que Buildpacks de por sí ya añade al Docker local la imagen construida, haría falta en caso de querer enviar la imagen un un registro de imágenes y artefactos remoto.

La imagen construida no es más que una imagen de Docker normal que se lista con el comando de Docker.

1
2
$ docker images

docker-images.sh
1
2
3
REPOSITORY                                 TAG        IMAGE ID       CREATED          SIZE
spring-injection-point                     latest     8f069f971d7b   10 minutes ago   358MB

docker-images.out

Despliegue de la aplicación con Waypoint

En este ejemplo el despliegue consiste en ejecutar una instancia del contenedor con Docker en local, su stanza es muy sencilla en la que solo se especifica el puerto en el que arrancar el el contenedor aunque también a través de diferentes propiedades se podrían especificar argumentos distintos.

El comando que realiza el deploy es el siguiente. Y siguiendo la misma lógica hay un comando para el release si fuera necesario.

1
2
$ waypoint deploy
$ waypoint release
waypoint-deploy-release.sh

Es posible hacer la construcción y despliegue con un único comando.

1
2
$ waypoint up

waypoint-up.sh

El servicio se inicia en la máquina y puede ser visto a través de la consola de Waypoint o con los comandos de Docker ya que en esencia no es más que una instancia de contenedor.

1
2
$ docker ps

docker-ps.sh
1
2
CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS         PORTS                                         NAMES
ce8c73a2f468   spring-injection-point:latest   "/waypoint-entrypoin…"   8 seconds ago   Up 7 seconds   0.0.0.0:32768->8080/tcp, :::32768->8080/tcp   spring-injection-point-01GQ5SA9SQ9KZKWJMKSQ1PHAWJ
docker-ps.out

La aplicación y su endpoint web responden al realizar una petición.

1
2
$ curl http://localhost:32768/

curl.sh
1
2
Hello World!

curl.out

Interfaz web y de linea de comandos

La interfaz web de Waypoint accesible con un navegador ofrece información de los proyectos, builds, deployments y releases además de logs.

La linea de comandos también ofrece información acerca de la aplicación con los comandos de Waypoint sin utilizar la interfaz web. La línea de comandos soporta más operaciones como destruir los recursos de un proyecto o eliminar el proyecto completamente.

1
2
$ waypoint deployment list

waypoint-deployment-list.sh
1
2
3
4
5
6
7
» spring-injection-point
     | ID | PLATFORM |            DETAILS             |    STARTED     |   COMPLETED    |       HEALTH        
  🚀 |  1 | docker   | image:8f069f9                  | 33 minutes ago | 33 minutes ago | ✔ - 33 minutes ago  
     |    |          | languages:ca-certificates,      
     |    |          | syft, procfile, adoptium,       
     |    |          | gradle, executable-jar,         
     |    |          | spring-boo
waypoint-deployment-list.out

Interfaz web de Waypoint

Interfaz web de Waypoint

Builds Deployments Relases

Builds, deployments y releases de una aplicación en un proyecto

Desarrollo en local

Para desarrollar en local todo este proceso de Buildpacks y Waypoint no es necesario, en el caso de la aplicación de ejemplo al estar basada en Spring Boot y utilizar Gradle es posible iniciarla con un comando directamente sin necesidad de construir una imagen de contenedor ni iniciar un contenedor en local.

1
2
$ ./gradlew run

gradlew-run.sh
Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./gradlew run


Comparte el artículo: