Ejecutando, depurando y desplegando microservicios con “Tye”. De paso, un vistazo a LENS

En este post vamos a ver de una manera simple y directa el uso de Project Tye y cómo desplegar aplicaciones .NET Core / .NET 5 en Kubernetes en general y, en AKS en particular. Gracias a Tye, a partir de ahora, este tipo de despliegues va a ser mucho más sencillo. ¿Te atreves?

Ademas, veremos que es Kubernetes LENS y como este permite la integración con Prometheus en un solo click.

En definitiva, todo lo que necesitamos para ejecutar, depurar, desplegar y gestionar nuestra aplicación en un cluster de Kubernetes, y, por si fuera poco, todo ello en unos unos pocos minutos, 😉

¿Que es Tye?

Tye (o Project Tye), es una herramienta de desarrollo que facilita el desarrollo, los tests y la implementación de microservicios y aplicaciones distribuidas. Incluye un orquestador local para facilitar el desarrollo de microservicios y la capacidad de implementar microservicios en Kubernetes con una configuración mínima y de manera muy sencilla.

Tye no solo permite el despliegue de aplicaciones dotnet, si bien para proyectos .NET (ficheros .csproj), lo facilita MUY ENORMEMENTE. ¡De entrada, te olvidas de los “.dockerfile”, Tye los genera automáticamente por ti!.

Para más detalle, podemos echar un ojo aquí, al repositorio de Github de Tye.

Podríamos decir también que es equivalente a Docker Compose, pero presenta justo las diferencias que lo hacen mucho mas sencillo e indicado especialmente para proyectos .NET Core / Net5. Por ejemplo, los servicios no tienen porque ser únicamente contenedores, pueden ser también “ejecutables” (en este caso con algunas configuraciones para la comunicación) y, por supuesto directamente, proyectos .NET (.csproj).

Si te interesa saber más sobre la comunicación entre ejecutables y/o conteneros, Eduard Tomás (@eiximenis) detalla mucho mucho más este tema en este post.

En la pasada #dotNETConf, vimos la siguiente tabla que resume a modo de Cheat Sheet los comandos de Tye y una comparativa con otras herramientas. Creo que de un vistazo puede aclarar muchas dudas sobre lo que es Tye y hasta dónde puede llegar.

Imagen

Instalar Tye

Esta instalación es sencilla, basta únicamente con utilizar “dotnet tool install -g” tal y como se muestra a continuación, indicando la versión ya que en estos momentos no existe aún una versión release.

dotnet tool install -g Microsoft.Tye --version "0.5.0-*" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json

Desarrollar/trabajar con un ejemplo

mkdir microservices
cd microservices

dotnet new razor -n frontend
dotnet new webapi -n backend
dotnet new sln
dotnet sln add frontend backend // (*) Añadir código para acceder desde el frontend al backend y uso de Redis Cache
tye init

(*) Puedes añadir manualmente este código o utilizar directamente el que puedes encontrar en este repo de Git.

El comando anterior tye init crea un fichero “tye.yml” tal y como se muestra a continuación:

name: microservices
services:
- name: frontend
  project: frontend/frontend.csproj
  replicas: 1  
- name: backend
  project: backend/backend.csproj
  replicas: 1
- name: redis
  image: redis
  bindings:
  - port: 6379
    connectionString: "${host}:${port}"

Como podremos observar en el código, para la comunicación entre frontend y backend no se especifica la ruta base, ni mucho menos se utiliza hardcode, en su lugar, se especifica el nombre del backend y el Service Discovery de Tye se encarga del resto. Para usarlo, bastará con añadir a nuestro proyecto la referencia al paquete nuget: “Microsoft.Tye.Extensions.Configuration“. ¡Si quieres profundizar sobre ello, visita este link!.

Ejecución en local

Ejecutar tye run desde línea de comandos y navegar a la url del Dasboard de tye tal y se observa en el detalle de ejecución (http://127.0.0.1:8000, para este caso en particular).

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-7.png
La imagen tiene un atributo ALT vacío; su nombre de archivo es image-9.png

Importante: Tanto el puerto del Dashboard como el del resto de servicios/proyectos, cambiará de manera dinámica, por lo que es importante tenerlo en cuenta.

Por detrás, Tye, usa Docker y genera las imágenes y contenedores necesarios para ello. Podemos comprobarlo si ejecutamos desde línea de comandos “docker ps“, tal y como muestra la siguiente salida.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-20.png

Despliegue en AKS

En primer lugar y previo a ejecutar el despliegue, es importante asegurar que:

  • Existe un Cluster de AKS. ¡Para este ejemplo, he utlizado la última versión 1.19.3 (aun en preview).!
  • Realizar el login en el Cluster de AKS y obtener las credeciales para su acceso
az login --tenant <TENANT-ID>
az account set -s <SUBSCRIPTION-ID>
az aks get-credentials --resource-group <RESOURCE_GROUP_NAME> --name <AKS_CLUSTER_NAME>
  • Permitir a AKS el acceso a Azure Container Registry. Para ello, ejecutar la siguiente instrucción una vez que haya sido creado el Cluster de AKS.
az aks update -n <AKS_NAME> -g <RESOURCE_GROUP_NAME> --attach-acr <AZURE_CONTAINER_REGISTRY_NAME>
  • Ejecutar desde línea de comandos: “tye deploy -y” e indicar el Container Registry cuando se requiera. De igual forma, indicar la cadena de conexión de Redis Cache, la cual quedará almacenada como un secreto en AKS.

Acceso a la Información de AKS (“Dashboard”)

Para la visualización, consulta de log y gestión de nuestro Cluster AKS, disponemos de varias herramientas, que revisamos a continuación:

La versión 1.19.3 de AKS ya no permite lanzar el Dasboard desde linea de comando con el CLI “AZ”. Ha quedado deprecado y, en su lugar, es el Portal de Azure quien nos presenta esta información. Eso si, por el momento en modo “Preview”.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-12.png

Por otro lado, y además de “kubectl” (como es de sobra conocida), contamos con la extension para VSCode, “Kubernetes“, tal y como muestra la siguente imagen, y que también, es conocida.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-10.png

Disponemos además, de otra herramienta, que me ha enamorado y que he descubierto recientemente, gracias a “@JGallardoRama”. Se trata de “LENS“, un IDE tanto para Windows como para MAC y Linux, que gestiona diferentes Cluster de Kubernetes (Minikute, AKS, EKS, GKE, etc.) así como la integración con Helm y otros orquestadores. Es más, permite, con un simple click (opción de menú: “File – Cluster Settings – Features (Metrics) – Install), la integración con Prometheus, instalándolo automáticamente en el Cluster de Kubernetes.

LENS: World’s most popular Kubernetes IDE provides a simplified, consistent entry point for developers, testers, integrators, and DevOps, to ship code faster at scale. Lens is the only IDE you’ll ever need to take control of your Kubernetes clusters. It is a standalone application for MacOS, Windows and Linux operating systems. Lens is an open source project and free!

En la siguiente imagen podemos ver una imagen de LENS, y en concreto, la opción de “Overview” del Cluster. Vemos también acceso directo a los Pods, Deployments, etc. y la posibilidad de realizar acciones, como eliminar, editar y escalar. ¡En mi opinión, creo que no tardará en disponer de la realización de todas estas acciones de manera masiva, lo que la hará mucho mas y útil 🙂!

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-14.png

En esta otra, podemos ver la integración con Prometheus.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-15.png

Incluyendo un Ingress

Si añadimos al final del fichero “tye.yaml” el siguiente código, dotaremos a nuestra aplicación/sistema de un ingress.

ingress:
  - name: ingress
    bindings:
      - port: 8080
    rules:
      - path: /
        service: frontend

Si ejecutamos nuevamente “tye deploy -i” y navegamos a la IP externa/publica proporcionada por AKS, comprobamos que nuestra aplicación se ejecuta correctamente, en el puerto 80.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-17.png

Depuración

  • Ejecutar “tye run –debug
  • Atachar el proceso correspondiente al proyecto de frontend o backend desde Visual Studio Code o Visual Studio.
La imagen tiene un atributo ALT vacío; su nombre de archivo es image-18.png

Pero, ¿Qué ocurre al depurar si tenemos 3 réplicas? Tendremos que depurar cada una de ellas de manera independiente, o bien, abrir tantas instancias de Visual Studio Code o Visual Studio como replicas existan.

La imagen tiene un atributo ALT vacío; su nombre de archivo es image-19.png

Espero que sea de utilidad y ayude a perder un poco el miedo para crear y probar arquitecturas e infraestructuras basadas en Kubernetes.

Referencias:

From GitHub to Azure App Service through Jenkins pipelines

Desde mi punto de vista Azure DevOps es quizas una de las mejores herramientas como orquestadora de Pipelines para DevOps, al menos con la que me siento más cómodo trabajando y para mi, la mas fácil. Si bien, hoy vamos a ver como trabajar con Jenkins para conseguir el mismo objetivo que ya vimos en el post anterior (con Azure DevOps) y para la aplicación MyBudget.

Configuración

Aunque podemos descargar e instalalar localmente Jenkins, vamos a optar por una instalación en Azure.

  • Crear un nuevo recurso (Create a resource)
  • Seleccionar Jenkins
  • Pulsar el boton de crear y completar los pasos indicados hasta finalmente pulsar “OK”.

Creación de un nuevo recurso “Jenkins” en Azure

  • Una vez creado el servidor Jenkins, tendremos acceso a la VM. Por defecto el protocolo de acceso es HTTP, por lo que no podremos acceder directamente a traves navegador a la url “xxx.cloudapp.azure.com“. Por tanto, tendremos que hacerlo via localhost mediante ssh de la forma: ssh -L 127.0.0.1:8080:localhost:8080 username@xxxwesteurope.cloudapp.azure.com, tal y como muestra la siguiente imagen:

  • En estos momentos ya podremos acceder al portal de jenkins vía http://localhost:8080, si bien para poder compilar la aplicación MyBudget, necesitaremos instalar el SDK de NetCore para Linux (Ubuntu) utilizando para ello las siguentes instrucciones.

Para conocer la distribución de linux para la que actualizar el SDK, podemos ejecutar el comando “cat /proc/version” desde la consola Cloud Shell.

wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.2

  • Adicionalmente y para que Jenkins pueda acceder y desplegar en Azure App Service, necesitamos dos plugins que podemos instalar desde el menú: Manage Jenkin – Manage Plugins:
    • Azure Credentials
    • Azure App Service Plugin

Pipeline

Ahora que ya tenemos todo configurado, crearemos el Pipeline, cuyo objetivo es compilar y ejecutar los tests unitarios de forma automática (CI – Continuous Integration) tras cada push/merge en la rama “master”, para a continuación, disparar el proceso de CD (Continuous Deployment) para el despliegue a DEV de manera automática y a Producción, previa aprobación. Supondremos que nuestros dos Azure App Services (para DEV y PROD) han sido creados previamente.

En primer lugar creamos una nueva credencial para el acceso a Azure (gracias al plugin “Azure Credential”):

  • Desde el terminal Cloud Shell de Azure, ejecutar las siguientes dos instrucciones:
    • az account set –subscription “<AZURE SUBSCRIPTION NAME>”
    • az ad sp create-for-rbac –name “MyBadget” –password <PASSWORD

  • Con el resultado de dichos comandos completar la siguiente información para añadir así la nueva credencial de tipo “Microsoft Azure Service Principal“, donde:
    • Client ID, se corresponde con el appId.
    • Client Secret, con el password.
    • Tenat ID, con el tenant y,
    • Subscription ID, con la subscripción de Azure, que también podemos obtener con la instrucción “az account show“.
  • Pulsar en “Verify Service Principal” para asegurar que la credencial es correcta.
  • Pusar en “OK”.

Las dos intrucciones anteriores registran una nueva aplicación (“MyBadget”) en el Directorio Activo de Azure. Navegando a ella, podemos ver también los valores de los parámetros antes introducidos.

  • Crear un nuevo Pipiline con el nombre “MyBudget-CI-CD”.
  • Parametrizar el proyecto marcando el check “This project is parameterized” y crear los siguientes parámetros:
    • RESORCE_GROUP, con el valor correspondiente al nombre del Resource Group de azure donde se encontraran los Azure App Services destino del despliegue: mybudget.
    • APP_NAME_DEV con el valor “mybudgetdev” y, APP_NAME_PROD con el valor “mybudgetprod“. Donde ambos parámetros se corresponden con el nombre del Azure App Service y que a su vez forma parte de la url: https://<APP_NAME_DEV|APP_NAME_PROD>.azurewebsites.net.
    • AZURE_CREDENTIAL_ID, del tipo “Microsoft Azure Service Principal” y requediro y selecciónar la credencial previamente creada: “Azure-Enterprise-MyBudget“.
  • Marcar el check “Github hook trigger for GITScm polling”.
  • Crear el script para la Pipeline (Declarativo).

pipeline {
    agent any
    stages {
        stage('Checkout git repo (DEV)') {
            steps {
                git branch: 'master', url: params.GIT_REPO
            }
        }
        
        stage('Build and Publish') {
            steps {
                sh(script: "dotnet publish MyBudget.sln -c Release", returnStdout: true)
            }
        }
        
        stage('Deploy to Azure (DEV)') {
            steps {
                azureWebAppPublish azureCredentialsId: params.AZURE_CREDENTIAL_ID, 
                resourceGroup: params.RESOURCE_GROUP, 
                appName: params.APP_NAME_DEV, 
                sourceDirectory: "MyBudget/bin/Release/netcoreapp2.2/publish/"
            }
        }
        
        stage('Deploy to Azure (PROD)') {  
            steps {
                input 'Do you approve deployment to PRO?'
                
                azureWebAppPublish azureCredentialsId: params.AZURE_CREDENTIAL_ID, 
                resourceGroup: params.RESOURCE_GROUP, 
                appName: params.APP_NAME_PROD, 
                sourceDirectory: "MyBudget/bin/Release/netcoreapp2.2/publish/"
            }
        }        
    }
}

Aunque hemos optado para este post la opción “inline” para la creación de la Pipeline, la recomendación es usar un fichero “jenkinsfile” dado que el repositorio de código fuente jugará un papel importante en el mismo al igual que para el resto de código de nuestra aplicación.

Continuous Integration/Delivery

Para configurar la Integración continua (CI) en Jenkins, y así poder disparar el Pipeline automáticamente, es necesario incluir un Webhook en el repositorio de github, a traves de la opción: “Settings – Webhooks” y añadiendo el sufijo “/github-webhook” a la url de Jenkins:

Finalmente si hacemos un cambio en el código y un push a “master”, el Pipeline se activará debido al Webhook en Github y el proceso de CI/CD dará comienzo.

En el ejemplo, para el despliegue a “PROD” se ha incluido la aprobación, al igual que en el post anterior con Azure DevOps.

Happy DevOps
Juanlu

Nota: No olvidemos apagar la VM cuando no la usemos para ahorra créditos de Azure.

Referencias:

Logging/Traces in NetCore projects with Serilog

imageBuenas,

Como en cualquier desarrollo, un buen sistema de Logging o Trazas para diagnósticos y detección de problemas, es una buena práctica que va a salvarnos de un aprieto más de una vez. En La mayoría de los casos, creamos un ApplicationBlock, un Helper, o similar para trabajar con un sistema de estas características, cuyo objetivo es escribir trazas en un repositorio: Consola, fichero y/o base de datos entre otros, con la intención de poder consultarlo a posteriori, ante cualquier problema, que como sabemos, siempre recurrimos a el en entornos Productivos.

Con NetCore, podemos hacer lo mismo como no podía ser de otra manera, si bien, una peculiaridad y gran ventaja, es la posibilidad de usar el Interfaz ILogger (Microsoft.Extensions.Logging), tanto en nuestro controladores como en nuestros servicios o cualquier clase, mediante Injección de dependencias, lo que nos permitirá codificar sin pensar el framework o factoría encargada de escribir trazas en un repositorio: consola, fichero, base de datos, etc.

Existen muchos frameworks, que nos permiten llevar a cabo esta tarea de manera muy facil: Serilog, NLog y Log4Net, entre otros. ¡Atrás quedo Enterprise Libray  ! Cada uno tiene sus particularidades, si bien, Serilog, es considerado como uno de los mejores, además, cuenta con un elevado número de extensiones para el guardo de trazas en diferentes repositorios: consola, fichero, RollingFile, base de datos, Azure ApplicationInsight, Azure App Service, etc., lo que lo hacen aun más potente.

Por tanto, veamos como trabajar con Serilog:

Por ejemplo, podríamos tener el siguiente código en nuestro Controller:

Donde “_logger”, dejará dos trazas en nuestro/s repositorio/s.  Podríamos codificar de esta misma forma todas aquellas de nuestras clases: Servicios, Repositories, etc., sin preocupación adicional, por el momento.

A continuación, en el fichero Program.cs, incluiremos la siguiente configuración:

Como buena práctica, dejaremos en manos del fichero “appSettings.json”, la configuración de el/los repositorio/s.

Otra ventaja de Serilog, como puede verse en el código anterior, es la capacidad de ejecución en modo “asíncrono”. Es decir, la escritura de trazas en un hilo adicional para no afectar a la ejecución normal del programa.

ver-github

Y ahora, veamos todo esto en ejecución:

Referencias:

Un saludo & Happy Logging
Juanlu