Desplegando una aplicación spring boot y spring cloud a Kubernetes usando Azure Devops - Parte 3

  




Objetivo

El objetivo de este artículo no es explicarte como se construyo PiggyMetrics, sino, mostrarte la experiencia de desplegarlo en Azure Kubernetes Service (AKS) y luego automatizar el despliegue con Azure Devops

- Se creará un MongoDB y RabbitMQ en Azure.  Esta va a ser la parte 1.

- Se creará un Azure Kubernetes Service y Azure Container Registry. Se desplegará Piggymetrics a Azure Kubernetes Service y se verá cómo resolver problemas de los micro servicios en Azure Kubernetes Service. Esta va a ser la parte 2

- Se automatizará el despliegue a Azure Kubernetes Service usando Azure Devops. Es el contenido de este artículo y la parte final de esta saga. Esta es la parte 3


Automatizar y rapidamente desplegar los cambios a Azure Kubernetes Service - Azure Pipelines

Crear un Azure Pipelines CI/CD  que automaticamente construye el build y despliega este al AKS cuando hay un commit al repositorio.

Prerequisitos


Hay algunos prerequisitos para esta automatización:




El resultado es:







El resultado es:



  • Crear un Azure KeyVault y cargar los secretos que va a necesitar Piggymetrics (en su mayoría son los que van en el archivo setup-env-variables-azure.sh)





Hay 2 variables que si tienes que llenarlas de la siguiente manera:

AZURE-REGISTRY-USERNAME=00000000-0000-0000-0000-000000000000
AZURE-REGISTRY-PASSWORD=<Token obtained according to instrucciones in it url: https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication>
NOTA IMPORTANTE: Asegurate de que funcione, sino en el pipeline te va a fallar, ejemplo:

docker login -u 00000000-0000-0000-0000-000000000000 -p eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkpT.....AA acr061174.azurecr.io
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded



Asegurate luego que el service principal usado en el service connection tiene los permisos GET, LIST en el vault. Para eso usa este comando:


$KV_NAME = kv-java-demo
<clientId from the Azure SPN JSON> se obtiene del  Azure Resource Manager creado anteriormente.


Para ver el client id, vamos a dicho url.



Ya con esa información, ejecutamos dicho comando:

az keyvault set-policy -n $KV_NAME --secret-permissions get list --spn <clientId from the Azure SPN JSON>


Azure Pipelines







  • Observa el pipeline y mira lo que hace. Asegurate que todas las entradas, por defecto, sean las que ha usado en tu código. 
          El azure-pipelines.yml contiene los siguientes elementos claves:
          - El trigger al inicio indica que el pipeline se disparará, cuando se haga commits a la rama master.
          - Las variables son la parte parametrizable del template YAML. 
          - Los stages
                    * El stage Build, construye tu app
                    * El stage Deploy, despliega a AKS. Este stage hace referencia al entorno con Kubernetes resource. Asegurate de modificar el nombre del entorno con el que tu has creado.
          - La tarea AzureKeyVault es usada en ambos stages para obtener los secretos de Azure Key vault y establecer las variables. En el stage Deploy, estas variables son usadas para establecer los secretos en el pod. 
           - La tarea Kubernetes Manifest tiene los beneficios agregados para poder verificar la estabilidad de un objeto antes de marcarlo como una tarea exitosa/fallida, ejecutar sustitución de artefacto, agregar anotaciones relacionadas a la trazabilidad de los objetos deployados, simplificar la creación y referenciamiento de imagePullSecrets.
   
  • Después de ver lo que el pipeline hace, selecciona Save y Run, colocale un mensaje a tu commit, ya que el Azure Pipelines agregar el azure-pipelines.yml a tu repositorio. Despues de editar el mensaje, selecciona Save y Run para ver a tu pipeline en acción.
  • Mientras tu pipeline se ejecuta, observa tu build stage, y luego tu deployment stage, va de azul (en ejecución) a green (completado). Tu puedes seleccionar los stages y jobs para ver tu pipeline en acción.


  • Adicionalmente, puedes verificar los objetos kubernetes creados y ver la historia de despliegue navegando en el "Environment".








Vídeos


Este artículo si lo grabaremos en 2 partes:


Aquí la parte final:





Bueno, eso es todo, por ahora.

Enjoy!

Joe
Share:

Desplegando una aplicación spring boot y spring cloud a Kubernetes usando Azure Devops - Parte 2


 


Objetivo

El objetivo de este artículo no es explicarte como se construyo PiggyMetrics, sino, mostrarte la experiencia de desplegarlo en Azure Kubernetes Service (AKS) y luego automatizar el despliegue con Azure Devops

- Se creará un MongoDB y RabbitMQ en Azure.  Esta va a ser la parte 1.

- Se creará un Azure Kubernetes Service y Azure Container Registry. Se desplegará Piggymetrics a Azure Kubernetes Service y se verá cómo resolver problemas de los micro servicios en Azure Kubernetes Service. Esta va a ser la parte 2

- Se automatizará el despliegue a Azure Kubernetes Service usando Azure Devops. Esta es la parte 3.


Conectarse a su cuenta de Azure

El Azure CLI nos ayudará en esta tarea, con este simple comando y usando nuestro email y contraseña con la cual sacamos la cuenta.


az login


Deberías obtener información de los tenants donde tienes acceso.




Crear un Azure Container Registry y Azure Kubernetes Service

En la parte 1 ya dejamos listo el MongoDB y RabbitMQ. Ahora vamos a crear el Registro de Contenedores  (ACR) y el Kubernetes en Azure (AKS). El Azure Container Registry nos va a permitir guardar las imágenes de nuestros micro servicios y en el AKS vamos a desplegar los contenedores que se crean a partir de dichas imágenes. 


Crear un Azure Container Registry


Ingresa al directorio 'java-on-aks':

source .scripts/setup-env-variables-azure.sh

Crea un Azure Container Registry usando Azure CLI:


# Create a Resource Group, if you have not created one
az group create --name ${RESOURCE_GROUP} \
    --location ${REGION}
    
# Create Azure Container Registry
az acr create --name ${CONTAINER_REGISTRY} \
    --resource-group ${RESOURCE_GROUP} \
    --sku basic --location ${REGION}
    
# Log into Azure Container Registry
az acr login -n ${CONTAINER_REGISTRY}

El resultado es el siguiente:



Crear el Azure Kubernetes Service


Creamos una instancia de Azure Kubernetes Service y lo asociamos al Azure Container Registry creando en el paso anterior usando Azure CLI:

az aks create --name ${AKS_CLUSTER} \
    --resource-group ${RESOURCE_GROUP} \
    --location ${REGION} \
    --attach-acr ${CONTAINER_REGISTRY} \
    --node-vm-size Standard_DS3_v2 \
    --node-count 5

Obtener las credenciales de acceso a el cluster AKS:

az aks get-credentials --name ${AKS_CLUSTER} \
    --resource-group ${RESOURCE_GROUP}


Desplegar Piggymetrics a Azure Kubernetes Service


Construir las aplicaciones Java, las imágenes docker, y pushear las imágenes a Azure Container Registry usando Maven y Jib:

cd config
mvn compile jib:build \
    -Djib.container.environment=CONFIG_SERVICE_PASSWORD=${CONFIG_SERVICE_PASSWORD}

cd ../registry
mvn compile jib:build

cd ../gateway
mvn compile jib:build

cd ../auth-service
mvn compile jib:build

cd ../account-service
mvn compile jib:build \
    -Djib.container.environment=ACCOUNT_SERVICE_PASSWORD=${ACCOUNT_SERVICE_PASSWORD}

cd ../statistics-service
mvn compile jib:build \
    -Djib.container.environment=STATISTICS_SERVICE_PASSWORD=${STATISTICS_SERVICE_PASSWORD}

cd ../notification-service
mvn compile jib:build \
    -Djib.container.environment=NOTIFICATION_SERVICE_PASSWORD=${NOTIFICATION_SERVICE_PASSWORD}


Jib está configurado para crear una distribución lista para producción. Por ejemplo:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.8.0</version>
    <configuration>
        <from>
            <!-- production-ready distribution of Java -->
            <image>mcr.microsoft.com/java/jre-headless:8u232-zulu-alpine</image>
        </from>
        <to>
            <image>${CONTAINER_REGISTRY}.azurecr.io/${parent.artifactId}-${project.name}</image>
        </to>
        <container>
            <jvmFlags>
                <jvmFlag>-Xms2048m</jvmFlag>
                <jvmFlag>-Xmx2048m</jvmFlag>
            </jvmFlags>
            <ports>
                <port>${CONFIG_PORT}</port>
            </ports>
            <labels>
                <key1>${project.version}</key1>
            </labels>
        </container>
    </configuration>
</plugin>

Preparar los archivos manifiesto para Kubernetes


Se prepara los manifiestos de Kubernetes usando el script provisto:

# cd to kubernetes folder
cd ../kubernetes
source ../.scripts/prepare-kubernetes-manifest-files.sh
NOTA: Yo he modificado los scripts para soportar Kubernetes 1.16.x, el proyecto original no lo hace y no va a funcionar todo lo que viene a continuación. 

Crear los Secretos en Kubernetes


Tu puedes crear Secretos para desplegar los micro servicios en Kubernetes:

kubectl apply -f deploy/0-secrets.yaml

# you can view Secrets in Kubernetes using:
kubectl get secret piggymetrics -o yaml

Desplegar Spring Cloud Config Server


Tu puedes desplegar el Spring Cloud Config Server a Kubernetes:

kubectl apply -f deploy/1-config.yaml

Desplegar Spring Cloud Service Registry


Tu puedes desplegar el Spring Cloud Service Registry a Kubernetes:

kubectl apply -f deploy/2-registry.yaml

Se puede validar que un Spring Cloud Config Server esta arriba y corriendo invocando su REST API.

Para saber en que IP público se esta ejecutando el Spring Cloud Config Server y Spring Cloud Service Registry usando kubectl:



Y ya con eso podemos testear todas las configuraciones usadas por los proyectos:


open http://<EXTERNAL-IP-of-config>:8888/gateway/profile
open http://<EXTERNAL-IP-of-config>:8888/account-service/profile
open http://<EXTERNAL-IP-of-config>:8888/statistics-service/profile
open http://<EXTERNAL-IP-of-config>:8888/notification-service/profile
...
open http://<EXTERNAL-IP-of-config>:8888/notification-service/profile/development
...



Se puede validar que un Spring Cloud Service Registry esta listo, abriendo el Service Registry Dashboard:



Desplegar Spring Cloud Gateway


Tu puedes desplegar el Spring Cloud Gateway a Kubernetes:

kubectl apply -f deploy/3-gateway.yaml

Desplegar los 4 Spring Cloud micro servicios


Tu puedes desplegar los spring cloud micro servicios a Kubernetes:

kubectl apply -f deploy/4-auth-service.yaml
kubectl apply -f deploy/5-account-service.yaml
kubectl apply -f deploy/6-statistics-service.yaml
kubectl apply -f deploy/7-notification-service.yaml

Tu puedes validar que los micro servicios están ejecutandose:




Abre el PiggyMetrics publicado en Kubernetes


Abre el landing page de Piggymetrics usando el IP externo del gateway:















Monitorear los micro servicios en Azure Kubernetes Service

Con el soporte fuera de la caja para agregar logs, métricas, y trazas de aplicaciones distribuidas que brinda Azure Monitor, tu puedes fácilmente visualizar como tus aplicaciones se ejecutan, detectar y diagnosticar issues en tus micro servicios y dependencias, revisar a profundidad la data que tiene problemas y tener un mejor entendimiento de que están haciendo los usuarios en tus aplicaciones. 


Revisar los logs de los micro servicios en cloud


Podemos ver los logs de cada micro servicio usando el comando kubectl:

# Stream logs from Spring Cloud Config Server
kubectl logs -f --timestamps=true -l app=config

# Stream logs from Spring Cloud Service Registry
kubectl logs -f --timestamps=true -l app=registry

# Stream logs from Spring Cloud Gateway
kubectl logs -f --timestamps=true -l app=gateway

# Stream logs from Spring Cloud micro service apps
kubectl logs -f --timestamps=true -l app=auth-service
kubectl logs -f --timestamps=true -l app=account-service
kubectl logs -f --timestamps=true -l app=statistics-service
kubectl logs -f --timestamps=true -l app=notification-service

Usar los logs agregados y métricas en Azure Log Analytics


Podemos agregar los logs en Azure Log Analytics y recuperar ellos usando consultas Kusto. Hay que crear en este punto un Analytics Workspace en Azure. 

1. Vamos a crear un Log Analytics workspace

2.  Configuramos los datos y creamos el ALAW.

3. El resultado es el siguiente:


4. Ahora vamos a nuestro Kubernetes y asociamos este ALAW.  Damos clic en Enable.



Luego de ello , aplica el scope al AKS:






O usando Kusto query para ver los logs de cada micro servicio:







//Logs for Spring Cloud Gateway
let ContainerIdList = KubePodInventory
| where ContainerName contains 'auth-service'
| where ClusterId  contains "aks-workshop-demo"
| distinct ContainerID;
ContainerLog
| where ContainerID in (ContainerIdList)
| where LogEntry !contains "AI:" 
| project LogEntrySource, LogEntry, TimeGenerated, Computer, Image, Name, ContainerID
| order by TimeGenerated desc
| render table


Espero les sirva para ver información de los micro servicios.


Video

He grabado también este vídeo para que puedas seguir el artículo sin problemas.






Enjoy!

Joe






Share:

Desplegando una aplicación spring boot y spring cloud a Kubernetes usando Azure Devops - Parte 1

 





Introducción

Cuando empecé a experimentar con Spring Boot y Spring Cloud, encontré este gran proyecto en Github denominado PiggyMetrics

Si bien usa algunos proyectos que desde ya desde la versión Greenwich de Spring Cloud se recomienda reemplazarlos:

- Hystrix por Resilience4j

- Hystrix Dashboard y Turbine por Micrometer y el sistema de monitoreo

- Zuul por Spring Cloud Gateway


Te muestra como implementar tus micro servicios, el uso de Eureka, Config ServerRibbon, Hystrix, Feign y el uso del stack ELK y tracing distribuido con Spring Cloud Sleuth para ver las trazas en Zipkin. En resumen tiene de todo. Te invito a probar dicho proyecto usando el url de GitHub que te menciono líneas arriba y experimentar con dicha solución. 

Todo el trabajo estará documentado en https://github.com/joedayz/java-on-aks que ha sido actualizado por mi persona para usar Kubernetes 1.16.x.

Objetivo

El objetivo de este artículo no es explicarte como se construyo PiggyMetrics, sino, mostrarte la experiencia de desplegarlo en Azure Kubernetes Service (AKS) y luego automatizar el despliegue con Azure Devops

- Se creará un MongoDB y RabbitMQ en Azure.  Esta va a ser la parte 1.

- Se creará un Azure Kubernetes Service y Azure Container Registry, se desplegará Piggymetrics a Azure Kubernetes Service y se verá cómo resolver problemas de los micro servicios en Azure Kubernetes Service. Esta es la parte 2

- Se automatizará el despliegue a Azure Kubernetes Service usando Azure Devops. Esta es la parte 3


Prerequisitos

Para que puedas desplegar esta aplicación Java al cloud, necesitas una subscripción en Azure, sino la tienes, puedes activar una subscribiendote a MSDN o sacandote una cuenta gratuita en Azure

Luego en tu maquina necesitas:

- Azure Cli

- Java 8

- Maven 3

- Git y cuenta en Github

- ACR Docker Credential Helper

- Docker

- Kubectl

- Helm

- dos2unix


Inicia - clonando el repositorio

Hay que clonar el repositorio y cambiar a dicho directorio:


git clone https://github.com/joedayz/java-on-aks.git
cd java-on-aks


Crear MongoDB y RabbitMQ

Hay que crear el MongoDB y RabbitMQ en Azure y capturar las coordenadas y credenciales para luego publicarlas en setup-env-variables-azure.sh.


Preparando el entorno de desarrollo


Realiza una copia del script template para crear tu script de configuración de entorno de desarrollo:

cp .scripts/setup-env-variables-azure-template.sh .scripts/setup-env-variables-azure.sh

Prepara el entorno de desarrollo colocando tus propios valores en las siguientes variables de entorno de dicho archivo setup-env-variables-azure.sh, por ejemplo:

# ====== Piggy Metrics Azure Coordinates =====
export RESOURCE_GROUP=rg-workshop-demo
export REGION=westus2
export AKS_CLUSTER=aks-workshop-demo
export CONTAINER_REGISTRY=acr061174

## ===== Mongo DB
export MONGODB_DATABASE=mongodb-workshop-demo
export MONGODB_USER=cosmosdb-user

## ===== Rabbit MQ
export RABBITMQ_RESOURCE_GROUP=rg-workshop-demo
export RABBITMQ_VM_NAME=rabbitmq-vm-workshop-demo
export RABBITMQ_ADMIN_USERNAME=rabbitmq-admin


Luego exporta estas variables de entorno desde el directorio 'java-on-aks':

pwd 
/Users/josediaz/Downloads/java-on-aks

source .scripts/setup-env-variables-azure.sh



Crear MongoDB


Crear una instancia de MongoDB:

# Change directory
cd java-on-aks

# Login into Azure
az login

# Create a Resource Group
az group create --name ${RESOURCE_GROUP} \
    --location ${REGION}

# Create a Cosmos DB account
az cosmosdb create --kind MongoDB \
    --resource-group ${RESOURCE_GROUP} \
    --name ${MONGODB_USER}

Cortar y pegar el resource 'id' de la respuesta de Azure CLI en setup-env-variables-azure.sh, por ejemplo:

"id": "/subscriptions/7c947db2-4b57-48ef-a998-d0f495f492fc/resourceGroups/rg-workshop-demo/providers/Microsoft.DocumentDB/databaseAccounts/cosmosdb-user"

export MONGODB_RESOURCE_ID="/subscriptions/7c947db2-4b57-48ef-a998-d0f495f492fc/resourceGroups/rg-workshop-demo/providers/Microsoft.DocumentDB/databaseAccounts/cosmosdb-user"


Luego, es necesario obtener los connections strings y usar el primary connection string como MONGODB_URI en el archivo setup-env-variables-azure.sh.

# Get Cosmos DB connection strings  
az cosmosdb list-connection-strings --resource-group ${RESOURCE_GROUP} \
    --name ${MONGODB_USER} 

Lo copiamos al archivo así:

export MONGODB_URI="mongodb://cosmosdb-user:6Qxfc85NOBVtAbKzKzotTu7pVuG2PTMuCc5m5pcFcsStD3Y5FEqvRlmMkr3cAnjC2EsHzxV5nQBlLPI3x0N0TQ==@cosmosdb-user.documents.azure.com:10255/?ssl=true&replicaSet=globaldb"


Conectarse a MongoDB


Te recomiendo Robo 3T que es gratuito. 

1. Connection


2. Authentication


3. SSH. Lo dejamos tal cual
4. SSL 


5. Advanced. Lo dejamos tal cual.

6. Probamos la conexión y listo.




Crear RabbitMQ


Crear una instancia de RabbitMQ certificado por Bitnami para el Microsoft Azure, ir a https://portal.azure.com/#blade/Microsoft_Azure_Marketplace/MarketplaceOffersBlade/selectedMenuItemId/home/searchQuery/rabbitmq e iniciar:


Llena el formulario y usa los valores de RABBITMQ_RESOURCE_GROUP, RABBITMQ_VM_NAME y RABBITMQ_VM_ADMIN_USERNAME, y escoge SSH. Selecciona 'Standard DS3 v2' como el tamaño: 

Acepta los valores por defecto en las siguientes pantallas, pero, no olvides descargar el archivo .pem para poder luego conectarnos a este RabbitMQ desde nuestra máquina local. 

El resultado final debe ser así:




Abre el cliente RabbitMQ y puertos de administración:

# https://docs.bitnami.com/azure/infrastructure/rabbitmq/get-started/understand-default-config/
az vm open-port --port 5672 --name ${RABBITMQ_VM_NAME} \
    --resource-group ${RABBITMQ_RESOURCE_GROUP}
az vm open-port --port 15672 --name ${RABBITMQ_VM_NAME} \
    --resource-group ${RABBITMQ_RESOURCE_GROUP} --priority 1100


En la imagen anterior puedes copiar el Public IP address de la maquina virtual Linux donde se esta ejecutando RabbitMQ y configurar la variable de entorno RABBITMQ_HOST en el archivo setup-env-variables-azure.sh:

## ===== Rabbit MQ
export RABBITMQ_HOST=52.183.30.245
export RABBITMQ_PORT=5672


Luego probamos que podemos conectarnos a dicha maquina vía ssh de la siguiente manera:

1. Desde el directorio 'java-on-aks':

# Open an SSH connection, say
# First, export the environment variables
source .scripts/setup-env-variables-azure.sh

2. Desde el directorio donde descargaste el archivo .pem:

chmod 400 rabbitmq-vm-workshop-demo_key.pem

3.  Nos conectamos ahora al servidor con este comando:

ssh -i rabbitmq-vm-workshop-demo_key.pem rabbitmq-admin@${RABBITMQ_HOST}

El resultado es el siguiente:



4. Ahora procedemos a darnos permiso para conectarnos desde nuestra maquina local:

# https://docs.bitnami.com/azure/infrastructure/rabbitmq/administration/control-services/
sudo /opt/bitnami/ctlscript.sh status

# Stop RabbitMQ
sudo /opt/bitnami/ctlscript.sh stop

# Edit RabbitMQ configurtion file
# https://docs.bitnami.com/azure/infrastructure/rabbitmq/administration/connect-remotely/
# https://github.com/rabbitmq/rabbitmq-server/blob/master/docs/rabbitmq.config.example
sudo nano /opt/bitnami/rabbitmq/etc/rabbitmq/rabbitmq.config

# Particularly, change line 4 from
    {tcp_listeners, [{"127.0.0.1", 5672}, {"::1", 5672}]},
# TO
    {tcp_listeners, [{"0.0.0.0", 5672}, {"::1", 5672}]},

# Start RabbitMQ
sudo /opt/bitnami/ctlscript.sh start


El resultado debe quedar así:



5. Luego, debemos obtener las credenciales administrativas RabbitMQ con este comando:

cat ./bitnami_credentials


Copia las credenciales y cierra la conexión SSH y colocalas en el archivo .scripts/setup-env-variables-azure.sh y exportarlas en variables de entorno:

# Rabbit MQ
export RABBITMQ_USERNAME=user
export RABBITMQ_PASSWORD=xxxxxxxxxxxx

# export them
source .scripts/setup-env-variables-azure.sh

Luego de todo esto, ya podrías abrir la consola administrativa en este URL:




Variables de entorno para el ambiente de desarrollo


Hasta este punto, deberíamos tener las siguientes variables en .scripts/setup-env-variables-azure.sh y exportarlas en el ambiente de desarrollo:





Y bueno esta es la parte 1. En los sucesivo iremos agregando las otras partes para que lo puedan practicar.  Lo haremos en partes porque el proceso es largo y mejor ir paso a paso para hacerlo mas didáctico.

Vídeo paso a paso


Y por supuesto, hay un video para apoyarte a seguir los pasos de este primer artículo.





Enjoy!

Joe




Share: