Liferay Portal/DXP en Openshift

 




Cada vez es más habitual el despliegue de aplicaciones o microservicios en una infraestructura basada en contenedores, como Kubernetes u Openshift. Liferay Portal/DXP no se queda atrás en este aspecto y gracias a que es una plataforma totalmente agnóstica a la infraestructura subyacente, es posible su implementación en este tipo de infraestructuras. 

Liferay ofrece DXPCloud, una solución PaaS a medida para Liferay DXP/Commerce, multi-cloud, con la que los clientes pueden enfocar todo su esfuerzo, desde el minuto 1, en lo que realmente es importante para ellos: su propio negocio, despreocupándose de la infraestructura que lo mantiene estable y por tanto el mantenimiento de la misma. 

Aunque DXPCloud sea una solución entre las que poder elegir, en algunas situaciones puede plantearse si una infraestructura a medida directamente en Kubernetes u Openshift podría encajar mejor dados una serie de requerimientos.

Si finalmente la decisión es la de implementar y mantener la infraestructura por uno mismo, para ayudar a provisionar el despliegue de entornos en Kubernetes y Openshift, podemos utilizar HELM. Con la ayuda de HELM podremos agrupar todos los objetos de k8s/Openshift necesarios en una release, con la cual desplegar Liferay Portal/DXP/Commerce.

El propósito de este blog es compartir un HELM Chart con el cual poder llevar a cabo un despliegue de Liferay Portal 7.4 en Openshift, más concretamente en CodeReady Containers.

Los pre-requisitos para llevar a cabo un despliegue en Openshift en nuestra máquina son los siguientes:

  1. Instalar Docker en la máquina

  2. Instalar CodeReady Containers Openshift y asignarle los recursos suficientes en cuanto a CPU, Memoria y Disco. En este caso, desplegaremos un MySQL y Liferay Portal, pero si queremos desplegar Elasticsearch, un Webserver por delante de Liferay Portal, necesitaremos recursos para ello.
    Nota: Este chart se ha desarrollado usando las siguientes versiones en Code Ready Containers Openshift:
    Client Version: 4.4.3
    Server Version: 4.9.5
    Kubernetes Version: v1.22.0-rc.0+a44d0f0

 

Let’s go

 

  1. El foco lo pondremos en usar un HELM Chart para desplegar Liferay Portal, por lo que asumimos que tenemos una base de datos desplegada previamente en nuestro Openshift para poder utilizar una configuración de Liferay Portal en clúster.
    Podemos utilizar el siguiente manifesto yaml con el cual desplegar en nuestro Openshift una base de datos MySQL 5.7 con las configuración básica para Liferay Portal. Si también lo queremos, podremos utilizar otros HELM Charts para provisionar Postgres o MySQL (añadiendo la configuración necesaria a los values tanto en Liferay Portal como en la base de datos)
     

  2. Utilizaremos el siguiente Liferay Gradle Workspace con el cual inyectaremos configuración por entorno en tiempo de construcción de la imagen docker, así como un módulo de tipo portlet, a modo de prueba.


    La configuración que tenemos es la siguiente:

    OSGi: Configuración para permitir las redirecciones únicamente bajo los dominios conocidos. Tener en cuenta que esta configuración es nueva desde 7.4 en adelante.
    Anteriormente se realizaba por portal-ext.properties.

    JGroups: Configuración de JGroups utilizando DNS Ping y los DNS SRV creados en Openshift para el discovery de nodos.

    Dockerfile.ext: En él incluimos las siguientes instrucciones con las que poder permitir a los usuarios del grupo ROOT acceso a los directorios /mnt/liferay y /opt/liferay en la imagen Docker, con el fin de evitar problemas en el arranque por permisos(ver Soporte arbitrario de uids en Openshift)



    En el Workspace ejecutamos:

    1.  ./gradlew clean deploy
      Para construir nuestro Workspace

    2.  ./gradlew createDockerFile
      Para generar la parte necesaria para Docker y el Dockerfile en el directorio build/docker del Workspace.
      Si inspeccionamos el Dockerfile generado, podemos ver que se han añadido las líneas que habíamos añadido en nuestro Workspace en el fichero Dockerfile.ext:

    3. Construiremos la imagen Docker y tagearemos la versión 1.0.0:
      docker build ${LiferayWorkspace}/build/docker -t default-route-openshift-image-registry.apps-crc.testing/liferay/liferay-portal-7.4-ga4:1.0.0

    4. Hacemos login en Openshift como Developer para crear el proyecto:
      oc login -u developer -p pwd https://api.crc.testing:6443

    5. Creamos el proyecto liferay:
      oc new-project liferay

    6. Hacemos login en Openshift con OC como kubeadmin::
      oc login -u kubeadmin -p xxx https://api.crc.testing:6443

    7. Si no tenemos una base de datos actualmente, podemos crear un MySQL utilizando este manifesto yaml dentro del mismo proyecto:
      oc apply -f .//database.yaml 

    8. Hacemos login en Docker para acceder al Registry
      docker login -u `oc whoami` -p `oc whoami --show-token` default-route-openshift-image-registry.apps-crc.testing

    9. Pusheamos la imagen Docker creada en el paso 3.
      docker push default-route-openshift-image-registry.apps-crc.testing/liferay/liferay-portal-7.4-ga4:1.0.0



      En este último paso obtenemos el digest de la imagen en el registry y podemos copiarlo para hacer referencia a él en nuestro values del Chart o bien acceder a él desde Openshift consultando el objeto ImageStream creado para la imagen de Liferay Portal.
       
  3. Modificamos el values.yaml del Chart incluyendo el digest de la imagen pusheada al registry de nuestro Openshift:
  4. Estando logeados en Openshift, utilizamos HELM para aplicar el Chart:
    helm install liferay-chart . -f values.yaml

     
  5. Accediendo a la consola web de Openshift, podemos ver cómo nuestro Chart se ha aplicado, desplegando los recursos dentro del namespace “liferay”:

     

 

Analizando el Chart que acabamos de instalar

Como hemos podido comprobar, con HELM podremos manejar e instalar los objetos necesarios dentro de nuestro proyecto en Openshift, para desplegar Liferay Portal/DXP. Los recursos que estamos manejando en la Chart son los siguientes:

  • Deployment: Para crear los pods de Liferay Portal/DXP y su configuración necesaria en Kubernetes/Openshift

  • Configmap: Para crear los configMap para inyectar el fichero Portal-ext.properties y la configuración de Elasticsearch en tiempo de despliegue, lo cual permitirá su cambio en caliente en el entorno sin necesidad de generar una nueva release o imagen docker y volver a desplegar una release. Las propiedades del fichero Portal-ext.properties también pueden ser introducidas como variables de entorno en el Deployment, sobreescribiendo las del fichero.
    Podría ser necesario extender la configuración del Portal añadida como configMaps, dependiendo de las necesidades del proyecto en el que nos podamos encontrar.
    El resto de configuración es añadida en tiempo de construcción, como la configuración de cluster JGroups o la configuración OSGi, la cual se encuentra en el Liferay Gradle Workspace dentro del folder common:

    **Recordar que en tiempo de construcción se puede indicar la configuración de entorno a construir con el parámetro:
    ./gradlew createDockerFile -Pliferay.workspace.environment=dev
    Este parámetro hará que la imagen docker se construya con el valor dev en la variable de entorno LIFERAY_WORKSPACE_ENVIRONMENT, para que en el momento de arranque de Liferay Portal/DXP se arranque con la configuración correcta del entorno:



    No obstante, el deployment que estamos utilizando en la Chart, sobreescribe esta variable de entorno, incluyendo la variable manejada por los values de HELM, con lo que podremos construir con un valor pero finalmente será HELM el que indique los values y la configuración final a aplicar:




     

  • HorizontalPodAutoscaler: para habilitar el auto-escalado horizontal de los pods de Liferay Portal/DXP por consumo de recursos de CPU y Memoria de los contenedores que ejecuten Liferay Portal/DXP. Si quieres configurar el escalado horizontal por una métrica a medida, te sugiero que eches un vistazo a este otro blog.

  • Service: para exponer los pods de Liferay Portal/DXP como servicio.

  • Ingress: para enrutar y balancear las peticiones al servicio de Liferay Portal/DXP. Se configura un balanceo por algoritmo round-robin y una afinidad a los pods del Servicio de Liferay mediante una cookie denominada "lfrstickysessioncookie" con el fin de garantizar la sesión del cliente al pod en el que comenzó su sesión, evitando problemas de pérdida de sesión a los clientes finales en un entorno en cluster.

  • Persistent Volume Claim: para disponer del almacenamiento necesario para la gestión documental de Liferay Portal/DXP

  • Service Monitor: para permitir la exposición de métricas a través de un puerto y endpoint dentro del servicio de Liferay. Para llevarlo a cabo se necesitará exponer métricas al endpoint configurado. Si quieres implementarlo, te recomiendo seguir los pasos que comento en uno de mis blogs anteriores.

     

Disponemos de un fichero values por cada entorno donde podremos desplegar:

  1. Local o default/common values para todos los entornos: values.yaml

  2. Dev: values-dev.yaml

  3. Uat: values-uat.yaml

  4. Prod: values-prod.yaml

Por tanto, si quisiéramos desplegar en DEV, con HELM utilizaríamos el values.yaml junto con el values-dev.yaml para sobreescribir la configuración por defecto con la del entorno de dev:

helm install liferay-chart . -f values.yaml --values env/values-dev.yaml 



Ahora, si modificamos nuestro fichero hosts para apuntar nuestro localhost 127.0.0.1 a dev.liferay.openshift.com, podremos acceder a nuestro Liferay Portal y verlo en acción:



En el values del entorno de dev, activamos el auto escalado con un mínimo de réplicas de 1 y un máximo de 2:


También tendremos la configuración OSGi necesaria para conectar con un Elasticsearch remoto, mediante configMap (necesitaríamos adicionalmente desplegar Elasticsearch en Openshift y para ello también se puede utilizar la Chart de Elasticsearch)



Si aplicamos los values de UAT o PROD, podemos comprobar que los recursos para los contenedores de Liferay Portal/DXP son mayores, así como el número de réplicas:



helm install liferay-chart . -f values.yaml --values env/values-prod.yaml


Dado que el portal-ext.properties lo estamos inyectando en tiempo de despliegue mediante fichero configMap y será igual para todos los entornos, si incluimos uno desde el Workspace éste no aplicará.

Podemos modificar propiedades del portal-ext.properties por entorno utilizando las variables de entorno dentro de cada values del entorno:


 

Conclusión

Con HELM podremos disponer de un conjunto de objetos que definen los recursos necesarios para disponer de una infraestructura, en este caso, de Liferay Portal/DXP en Kubernetes/Openshift, denominado Chart. Nos permitirá la creación y mantenimiento de releases y versionado, con todo lo necesario para sus despliegues en el cluster. Es recomendable no olvidar que HELM es una utilidad más, al igual que lo es Terraform, Ansible, Spinnaker, etc. En un proyecto basado en una arquitectura de contenedores, necesitaremos de más herramientas que permitan dotar de cierto automatismo para la ejecución de pruebas, construcción de artefactos (jars, imágenes Docker, las propias Charts, etc), publicación de releases de los artefactos construidos, evaluación de quality gates, despliegues, etc.