#Despliegue

0 Seguidores · 40 Publicaciones

El despliegue del software se refiere a todas las actividades que conforman un sistema de software y están disponible para utilizarse. El proceso general de la implementación consiste en varias actividades relacionadas entre sí con posibles transiciones entre ellas. 

Artículo Derek Gervais · sep 15, 2025 3m read

¡Hola a todos! Tras incorporarme recientemente a InterSystems, me di cuenta de que, a pesar de tener una Community Edition totalmente gratuita y genial, no está muy claro cómo conseguirla. Decidí escribir una guía destacando todas las diferentes formas en que podéis acceder a la Community Edition de InterSystems IRIS:

Conseguir InterSystems IRIS Community Edition como contenedor

Trabajar con una instancia en contenedor de la Community Edition es el enfoque recomendado para quienes son nuevos en el desarrollo con InterSystems IRIS, y en mi opinión es el más sencillo. InterSystems IRIS Community Edition se puede encontrar en DockerHub; si tenéis una cuenta SSO de InterSystems, también podéis encontrarla en el InterSystems Container Registry.

En cualquiera de los casos, descargaréis la imagen que necesitéis usando la CLI de Docker:

docker pull intersystems/iris-community:latest-em
// or
docker pull containers.intersystems.com/intersystems/iris-community:latest-em

A continuación, tendréis que iniciar el contenedor: para poder interactuar con IRIS desde fuera del contenedor (por ejemplo, para usar el portal de administración) necesitaréis publicar algunos puertos. El siguiente comando ejecutará el contenedor de IRIS Community Edition con los puertos del superserver y del servidor web publicados; tened en cuenta que no podéis tener nada más en ejecución que dependa de los puertos 1972 o 52773.

docker run --name iris -d --publish 1972:1972 --publish 52773:52773 intersystems/iris-community:latest-em
0
0 27
Artículo Alberto Fuentes · mayo 28, 2025 4m read

Con el lanzamiento de InterSystems IRIS Cloud SQL, recibimos cada vez más preguntas sobre cómo establecer conexiones seguras mediante JDBC y otras tecnologías de drivers. Aunque contamos con una documentación resumida y detallada sobre las tecnologías de los drivers, nuestra documentación no describe herramientas cliente individuales, como nuestra favorita personal, DBeaver. En este artículo, describiremos los pasos para crear una conexión segura desde DBeaver a vuestra implementación de Cloud SQL.

0
0 30
Artículo Ariel Glikman · abr 21, 2025 4m read

Si echáis un vistazo al archivo values.yaml del Helm chart de IKO, encontraréis:

useIrisFsGroup:false

Vamos a desglosar qué es useIrisFsGroup y en qué situaciones puede ser útil activarlo.

FsGroup se refiere al file system group (grupo del sistema de archivos).

Por defecto, los volúmenes en Kubernetes son propiedad del usuario root, pero necesitamos que IRIS sea propietario de sus propios archivos (IRIS en contenedores se instala bajo el usuario irisowner). Para solucionar esto, utilizamos uno de estos dos métodos:

1) initContainers

0
0 42
Artículo Ariel Glikman · feb 4, 2025 3m read

Todos los pods reciben una asignación de Calidad de Servicio (QoS). Existen tres niveles de prioridad dentro de un nodo:

  1. Guaranteed: Alta prioridad
  2. Burstable: Prioridad media
  3. BestEffort: Baja prioridad

Es una forma de indicar al kubelet cuáles son vuestras prioridades en un nodo si es necesario recuperar recursos. Este fantástico GIF de Anvesh Muppeda lo explica.

0
0 71
Artículo Luis Angel Pérez Ramos · sep 16, 2024 1m read

Digamos que quiero desinstalar el IKO - todo lo que tengo que hacer es:

> helm uninstall intersystems

Lo que ocurre entre bastidores es que helm desinstalará lo que estaba instalado cuando ejecutó :

> helm install intersystems <relative/path/to/iris-operator>

En cierto sentido esto es simétrico a cuando ejecutamos install pero con una imagen diferente.

Verás que cuando lo instalas, sabe qué imagen utilizar:

operator:
  registry: containers.intersystems.com
  repository: intersystems/iris-operator-amd
  tag: 3.7.13.100

Para desinstalar la imagen a tener en cuenta es:

0
0 63
Artículo Alberto Fuentes · mayo 15, 2024 4m read

La documentación de IKO es robusta. Una única página web, que consta de unas 50 páginas reales de documentación. Para los principiantes eso puede ser un poco abrumador. Como dice el refrán: ¿cómo se come un elefante? Mordisco a mordisco. Empecemos con el primer bocado: Helm.

¿Qué es Helm?

Helm es a Kubernetes lo que el InterSystems Package Manager (IPM, antes ObjectScript Package Manager - ZPM) es a IRIS.

0
0 76
Artículo Alberto Fuentes · abr 24, 2024 4m read

¡Hola, amigos!

A menudo, cuando desarrollamos soluciones comerciales, existe la necesidad de desplegar soluciones sin código fuente, por ejemplo, para preservar la propiedad intelectual.

Una de las formas de conseguirlo es utilizar InterSystems Package Manager.

Aquí he pedido a Midjourney que pinte una propiedad intelectual de software:

¿Cómo se puede lograr esto con IPM?

De hecho, es muy sencillo; basta con añadir la cláusula Deploy="true" en el elemento Resource del manifiesto module.xml. Ver Documentación.

He decidido pasaros el ejemplo más simple posible para ilustrar cómo funciona y también para daros una plantilla de entorno de desarrollo que os permita empezar a construir y desplegar vuestros propios módulos sin código fuente. ¡Allá vamos!

0
0 138
Artículo Luis Angel Pérez Ramos · abr 2, 2024 8m read

En este artículo, cubriremos los siguientes temas:

  • ¿Qué es Kubernetes?
  • Componentes principales de Kubernetes (K8)


¿Qué es Kubernetes?

Kubernetes es un marco de orquestación de contenedores de código abierto desarrollado por Google. En esencia, controla la velocidad de los contenedores y ayuda a gestionar aplicaciones formadas de varios contenedores. Además, le permite operarlos en diferentes entornos, por ejemplo, máquinas físicas, máquinas virtuales, entornos de nube o incluso entornos de implementación híbridos.


¿Qué problemas soluciona?

0
0 131
Artículo Ricardo Paiva · nov 16, 2023 3m read

Preguntas frecuentes de InterSystems

Para rutinas (*.mac)

Se puede ocultar el código fuente exportando/importando solo el *.obj que se genera después de compilar el programa fuente.

El ejemplo de ejecución de comandos especifica EX1Sample.obj y EX2Sample.obj, que se generan al compilar EX1Sample.mac y EX2Sample.mac, como destinos de exportación y los exporta al segundo archivo de argumentos.

Después de pasarlo a otro namespace, se usa el archivo XML exportado para realizar la importación.

0
0 111
Anuncio Esther Sanchez · oct 31, 2023

¡Hola Comunidad!

Compartimos con vosotros un nuevo vídeo con subtítulos en español, que explica los pasos necesarios para actualizar InterSystems IRIS, InterSystems IRIS for Health o HealthShare Health Connect desde una versión que utiliza un servidor web privado de InterSystems a una versión que utiliza un servidor web estándar de la industria, independiente de la instancia.

El vídeo muestra el proceso usando InterSystems IRIS en un entorno Ubuntu. Se puede seguir el mismo proceso para los otros productos, y en cualquier sistema operativo basado en Linux o Unix.

En el ejemplo, se tienen tres instancias de InterSystems IRIS en funcionamiento: mirror1 y mirror2, que son dos instancias en réplica síncrona (failover o sync mirror) y 1 instancia de réplica asíncrona (async mirror).

¡Esperamos que os resulte útil!
 

Cómo migrar una configuración mirror fuera del Servidor Web Privado en Linux o Unix

0
1 81
Anuncio Esther Sanchez · oct 20, 2023

¡Hola Comunidad!

Compartimos con vosotros un nuevo vídeo con subtítulos en español, que explica los pasos necesarios para actualizar InterSystems IRIS, InterSystems IRIS for Health o HealthShare Health Connect desde una versión que utiliza un servidor web privado de InterSystems a una versión que utiliza un servidor web estándar de la industria, independiente de la instancia.

El vídeo muestra el proceso usando InterSystems IRIS en un entorno Ubuntu. Se puede seguir el mismo proceso para los otros productos, y en cualquier sistema operativo basado en Linux o Unix.

¡Esperamos que os resulte útil!
 

Cómo migrar una instancia fuera del Servidor Web Privado en Linux o Unix

0
0 88
Artículo Luis Angel Pérez Ramos · oct 11, 2023 12m read

¡Hola Comunidad!

Este es el tercer artículo de la serie sobre arranque de instancias de IRIS con Docker. En esta publicación nos centraremos en el Enterprise Caché Protocol (ECP) o Protocolo de Caché Empresarial.

De manera muy simplificada, ECP permite configurar algunas instancias de IRIS como servidores de aplicaciones y otras como servidores de datos. Encontraréis más información técnica detallada en la documentación oficial.

El objetivo de este artículo es describir:

  • Cómo escribir el script de arranque de un servidor de datos y de uno o más servidores de aplicaciones.
  • Cómo establecer una conexión cifrada entre estos nodos con Docker.

Para hacerlo, generalmente utilizamos algunas de las herramientas que ya hemos visto en artículos anteriores sobre web gateway y mirroring, que describen instrumentos como OpenSSL, envsubst y Config-API.

Requisitos

ECP no está disponible en la versión Community de IRIS. Por lo tanto, se requiere acceso al World Response Center (WRC) para descargar una licencia de contenedor y conectarse al registro de contenedores en containers.intersystems.com.

Preparando el sistema

El sistema debe compartir algunos archivos locales con los contenedores. Es necesario crear ciertos usuarios y grupos para evitar el error "access denied" (acceso denegado).

sudo useradd --uid 51773 --user-group irisowner
sudo useradd --uid 52773 --user-group irisuser
sudo groupmod --gid 51773 irisowner
sudo groupmod --gid 52773 irisuser

Si aún no tenéis la licencia "iris.key", podéis descargarla desde el WRC y añadirla a vuestro directorio principal.

Obtener el repositorio de muestra

Todos los archivos que se necesitan están disponibles en un repositorio público, excepto la licencia "iris.key", así que hay que comenzar clonándola:

git clone https://github.com/lscalese/ecp-with-docker.git
cd ecp-with-docker

Certificados SSL

Para encriptar las comunicaciones entre los servidores de aplicaciones y el servidor de datos, necesitamos certificados SSL. Un script listo para usar ("gen-certificates.sh") está disponible. Sin embargo, podéis modificarlo libremente para que los ajustes del certificado sean consistentes con vuestra ubicación, empresa, etc.

Ejecutad:

sh ./gen-certificates.sh

Los certificados generados ahora se encuentran en el directorio "./certificates".

ArchivoContenedorDescripción
./certificates/CA_Server.cerServidor de aplicaciones y servidor de datosCertificado del servidor de autoridad
./certificates/app_server.cerServidor de aplicacionesCertificado para la instancia del servidor de aplicaciones de IRIS
./certificates/app_server.keyServidor de aplicacionesClave privada correspondiente
./certificates/data_server.cerServidor de datosCertificado para la instancia del servidor de datos de IRIS
./certificates/data_server.keyServidor de datosClave privada correspondiente

Construcción de la imagen

En primer lugar, iniciad sesión en el registro de Docker de InterSystems. La imagen base se descargará del registro durante la ejecución del comando build:

docker login -u="YourWRCLogin" -p="YourICRToken" containers.intersystems.com

Si no conocéis vuestro token, iniciad sesión en https://containers.intersystems.com/ con vuestra cuenta del WRC.

Durante la ejecución del build, añadiremos algunas utilidades de software a la imagen base de IRIS:

  • gettext-base: nos permitirá sustituir variables de entorno en nuestros archivos de configuración utilizando el comando "envsubst".
  • iputils-arping: se requiere en caso de que queramos hacer un mirror del servidor de datos.
  • ZPM: administrador de paquetes de ObjectScript.

Dockerfile:

ARG IMAGE=containers.intersystems.com/intersystems/iris:2022.2.0.281.0

# Don't need to download the image from WRC. It will be pulled from ICR at build time.

FROM $IMAGE

USER root

# Install iputils-arping to have an arping command.  It's required to configure Virtual IP.
# Download the latest ZPM version (ZPM is included only with community edition).
RUN apt-get update && apt-get install iputils-arping gettext-base && \
   rm -rf /var/lib/apt/lists/*

USER ${ISC_PACKAGE_MGRUSER}

WORKDIR /home/irisowner/demo

RUN --mount=type=bind,src=.,dst=. \
   iris start IRIS && \
       iris session IRIS < iris.script && \
   iris stop IRIS quietly

No hay nada especial en este Dockerfile, excepto la última línea. Configura la instancia del servidor de datos de IRIS para aceptar hasta 3 servidores de aplicaciones. Tened en cuenta que esta configuración requiere reiniciar IRIS. Asignamos el valor de este parámetro durante la ejecución del comando build para evitar tener que reiniciar posteriormente.

Ejecutar el comando build:

docker-compose build –no-cache

Archivos de configuración

Para la configuración de las instancias de IRIS (servidores de aplicaciones y servidor de datos), utilizamos el formato JSON del archivo Config-API. Notaréis que estos archivos contienen variables de entorno "${variable_name}". Sus valores se definen en las secciones "environment" del archivo "docker-compose.yml" que veremos más adelante en este documento. Estas variables se sustituirán justo antes de cargar los archivos utilizando la utilidad "envsubst".

Servidor de datos

Para el servidor de datos, haremos lo siguiente:

  • Habilitar el servicio ECP y definir la lista de clientes autorizados (servidores de aplicaciones).
  • Crear la configuración "SSL %ECPServer" necesaria para encriptar las comunicaciones.
  • Crear una base de datos llamada "myappdata". Esta base de datos se utilizará como base de datos remota desde los servidores de aplicaciones.

(data-serer.json)[https://github.com/lscalese/ecp-with-docker/blob/master/config-files/data-server.json]

{
   "Security.Services" : {
       "%Service_ECP" : {
           "Enabled" : true,
           "ClientSystems":"${CLIENT_SYSTEMS}",
           "AutheEnabled":"1024"
       }
   },
   "Security.SSLConfigs": {
       "%ECPServer": {
           "CAFile": "${CA_ROOT}",
           "CertificateFile": "${CA_SERVER}",
           "Name": "%ECPServer",
           "PrivateKeyFile": "${CA_PRIVATE_KEY}",
           "Type": "1",
           "VerifyPeer": 3
       }
   },
   "Security.System": {
       "SSLECPServer":1
   },
   "SYS.Databases":{
       "/usr/irissys/mgr/myappdata/" : {}
   },
   "Databases":{
       "myappdata" : {
           "Directory" : "/usr/irissys/mgr/myappdata/"
       }
   }
}

Este archivo de configuración se carga al inicio del contenedor del servidor de datos mediante el script "init_datasrv.sh". Todos los servidores de aplicaciones conectados al servidor de datos deben ser confiables. Este script validará automáticamente todas las conexiones dentro de los 100 segundos para limitar las acciones manuales en el portal de administración. Por supuesto, esto se puede mejorar para aumentar la seguridad.

Servidor de aplicaciones

Para los servidores de aplicaciones, realizaremos lo siguiente:

  • Habilitar el servicio ECP.
  • Crear la configuración SSL "%ECPClient" requerida para el cifrado de la comunicación.
  • Configurar la información de conexión con el servidor de datos.
  • Crear la configuración de la base de datos remota "myappdata".
  • Crear un mapeo global "demo.*" en el namespace "USER" hacia la base de datos "myappdata". Esto nos permitirá probar el funcionamiento de ECP posteriormente.

app-server.json:

{
   "Security.Services" : {
       "%Service_ECP" : {
           "Enabled" : true
       }
   },
   "Security.SSLConfigs": {
       "%ECPClient": {
           "CAFile": "${CA_ROOT}",
           "CertificateFile": "${CA_CLIENT}",
           "Name": "%ECPClient",
           "PrivateKeyFile": "${CA_PRIVATE_KEY}",
           "Type": "0"
       }
   },
   "ECPServers" : {
       "${DATASERVER_NAME}" : {
           "Name" : "${DATASERVER_NAME}",
           "Address" : "${DATASERVER_IP}",
           "Port" : "${DATASERVER_PORT}",
           "SSLConfig" : "1"
       }
   },
   "Databases": {
       "myappdata" : {
           "Directory" : "/usr/irissys/mgr/myappdata/",
           "Name" : "${REMOTE_DB_NAME}",
           "Server" : "${DATASERVER_NAME}"
       }
   },
   "MapGlobals":{
       "USER": [{
           "Name" : "demo.*",
           "Database" : "myappdata"
       }]
   }
}

El archivo de configuración se carga al iniciar un contenedor del servidor de aplicaciones mediante el script "init_appsrv.sh".

Iniciar los contenedores

Ahora podemos iniciar los contenedores:

  • 2 servidores de aplicaciones.
  • 1 servidor de datos.

Para hacer esto, hay que ejecutar:

docker-compose up –scale ecp-demo-app-server=2

Podéis consultar el archivo docker-compose para obtener más detalles:

# Variables are defined in .env file
# to show the resolved docker-compose file, execute
# docker-compose config

version: '3.7'

services:
  ecp-demo-data-server:
   build: .
   image: ecp-demo
   container_name: ecp-demo-data-server
   hostname: data-server
   networks:
     app_net:
   environment:
     # List of allowed ECP clients (application server). 
     - CLIENT_SYSTEMS=ecp-with-docker_ecp-demo-app-server_1;ecp-with-docker_ecp-demo-app-server_2;ecp-with-docker_ecp-demo-app-server_3
     # Path authority server certificate
     - CA_ROOT=/certificates/CA_Server.cer
     # Path to data server certificate
     - CA_SERVER=/certificates/data_server.cer
     # Path to private key of the data server certificate
     - CA_PRIVATE_KEY=/certificates/data_server.key
     # Path to Config-API file to initiliaze this IRIS instance
     - IRIS_CONFIGAPI_FILE=/home/irisowner/demo/data-server.json
   ports:
     - "81:52773"
   volumes:
     # Post start script - data server initilization.
     - ./init_datasrv.sh:/home/irisowner/demo/init_datasrv.sh
     # Mount certificates (see gen-certificates.sh to generate certificates)
     - ./certificates/app_server.cer:/certificates/data_server.cer
     - ./certificates/app_server.key:/certificates/data_server.key
     - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
     # Mount config file
     - ./config-files/data-server.json:/home/irisowner/demo/data-server.json
     # IRIS License
     - ~/iris.key:/usr/irissys/mgr/iris.key
   command: -a /home/irisowner/demo/init_datasrv.sh


 ecp-demo-app-server:
   image: ecp-demo
   networks:
     app_net:
   environment:
     # Hostname or IP of the data server.
     - DATASERVER_IP=data-server
     - DATASERVER_NAME=data-server
     - DATASERVER_PORT=1972
     # Path authority server certificate
     - CA_ROOT=/certificates/CA_Server.cer
     - CA_CLIENT=/certificates/app_server.cer
     - CA_PRIVATE_KEY=/certificates/app_server.key
     - IRIS_CONFIGAPI_FILE=/home/irisowner/demo/app-server.json
   ports:
     - 52773
   volumes:
     # Post start script - application server initilization.
     - ./init_appsrv.sh:/home/irisowner/demo/init_appsrv.sh
     # Mount certificates
     - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
     # Path to private key of the data server certificate
     - ./certificates/app_server.cer:/certificates/app_server.cer
     # Path to private key of the data server certificate
     - ./certificates/app_server.key:/certificates/app_server.key
     # Path to Config-API file to initiliaze this IRIS instance
     - ./config-files/app-server.json:/home/irisowner/demo/app-server.json
     # IRIS License
     - ~/iris.key:/usr/irissys/mgr/iris.key
   command: -a /home/irisowner/demo/init_appsrv.sh
 networks:
 app_net:
   ipam:
     driver: default
     config:
       # APP_NET_SUBNET variable is defined in .env file
       - subnet: "${APP_NET_SUBNET}"

¡Vamos a probarlo!

Acceso al portal de administración del servidor de datos

Los contenedores se han iniciado. Vamos a verificar el estado desde el servidor de datos.
El puerto 52773 está mapeado al puerto local 81, por lo que se puede acceder a él con esta dirección http://localhost:81/csp/sys/utilhome.csp.

Iniciad sesión con el nombre de usuario y contraseña predeterminados, luego hay que ir a System -> Configuration -> ECP Params. Haced clic en "ECP Application Servers". Si todo funciona correctamente, deberíais ver 2 servidores de aplicaciones con el estado "Normal". La estructura del nombre del cliente es "data server name":"application server hostname":"IRIS instance name". En nuestro caso, no hemos configurado los nombres de los servidores de aplicaciones, por lo que se han generado automáticamente.

Lista de servidores de aplicaciones

Acceder al portal de administración del servidor de aplicaciones

Para conectarse al portal de administración de los servidores de aplicaciones, hay que obtener el número de puerto. Como utilizamos la opción "--scale", no pudimos establecer los puertos en el archivo docker-compose. Por lo tanto, hay que recuperarlos con el comando docker ps:

docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS                      PORTS                                                                                     NAMES
a1844f38939f   ecp-demo   "/tini -- /iris-main…"   25 minutes ago   Up 25 minutes (unhealthy)   1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:81->52773/tcp, :::81->52773/tcp         ecp-demo-data-server
4fa9623be1f8   ecp-demo   "/tini -- /iris-main…"   25 minutes ago   Up 25 minutes (unhealthy)   1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:49170->52773/tcp, :::49170->52773/tcp   ecp-with-docker_ecp-demo-app-server_1
ecff03aa62b6   ecp-demo   "/tini -- /iris-main…"   25 minutes ago   Up 25 minutes (unhealthy)   1972/tcp, 2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:49169->52773/tcp, :::49169->52773/tcp   ecp-with-docker_ecp-demo-app-server_2

En este ejemplo, los puertos son:

servidor de datos

Pruebas de lectura/escritura en la base de datos remota.

Vamos a realizar unas pruebas de lectura/escritura en el terminal. Abrid una terminal de IRIS en el primer servidor de aplicaciones:

docker exec -it ecp-with-docker_ecp-demo-app-server_1 iris session iris
Set ^demo.ecp=$zdt($h,3,1) _ “ write from the first application server.”

Ahora abrid una terminal en el segundo servidor de aplicaciones:

docker exec -it ecp-with-docker_ecp-demo-app-server_2 iris session iris
Set ^demo.ecp(2)=$zdt($h,3,1) _ " write from the second application server."
zwrite ^demo.ecp

Deberíais ver las respuestas de ambos servidores:

^demo.ecp(1)="2022-07-05 23:05:10 write from the first application server."
^demo.ecp(2)="2022-07-05 23:07:44 write from the second application server."

Finalmente, abrid una terminal de IRIS en el servidor de datos y realizad una lectura del global demo.ecp:

docker exec -it ecp-demo-data-server iris session iris
zwrite ^["^^/usr/irissys/mgr/myappdata/"]demo.ecp

^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(1)="2022-07-05 23:05:10 write from the first application server."
^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(2)="2022-07-05 23:07:44 write from the second application server."

Eso es todo por hoy. Espero que os haya gustado este artículo. No dudéis en dejar un comentario si tenéis alguna duda o consulta.

0
0 139
Artículo Kurro Lopez · feb 4, 2023 2m read

Por lo general, si desea implementar una solución, debe agregar los elementos, configurar sus tablas de búsqueda y la configuración predeterminada manualmente.
Está bien si tiene todos los permisos y privilegios para realizar estas acciones. Si desea implementar en el servidor de producción de un cliente y no tiene los permisos, debe indicar en un documento TODOS los pasos que debe realizar el administrador de implementación.

2
0 120
Artículo Joel Espinoza · nov 23, 2022 1m read

Hola!

Aquí les dejo un video que hice para mostrar cómo se configura la alta disponibilidad (mirroring) en IRIS en un ambiente docker, el video esta completamente en español y los archivos necesarios estarán en mi Github.

El video en YouTube en https://youtu.be/rBdiTxavWmU

https://github.com/I-am-seven/iris-mirroring-video

Espero les sea de Utilidad!

Joel

0
1 75
Artículo Javier Lorenzo Mesa · nov 23, 2022 2m read

Este artículo describe un diseño arquitectónico más flexible para DeepSee. Al igual que en el ejemplo anterior, esta implementación incluye bases de datos separadas para almacenar la memoria caché, la implementación y la configuración de DeepSee y la sincronización de los globals. Este ejemplo introduce una nueva base de datos para almacenar los índices de DeepSee. Redefiniremos los mapeos globales para que los índices de DeepSee no se mapeeen junto con las tablas de hechos y dimensiones.

0
1 145
Artículo Ariel Arias · nov 22, 2022 7m read

Disclosure Statement: Sugerencias para relalizar pruebas en ambientes usados para demostraciones o desarrollos, no en ambientes productivos.

Caso de uso: teniendo IAM, lo ejecutamos desde un archivo YML, y necesitamos que se conecte a una Instancia IRIS en seguida, pero IRIS tiene deshabilitado el usuario IAM y la aplicación IAM.

0
1 144
Artículo Nancy Martínez · jul 22, 2022 1m read

¡Hola desarrolladores!

Solo quiero compartir con vosotros mi conocimiento, es decir, experiencia en algo que os puede hacer ahorrar unas cuantas horas algún día. 

Si estás creando una REST API con IRIS que contiene más de un nivel de "/", por ejemplo: '/patients/all',  no te olvides de añadir el parámetro 'recurse=1' en tu script de despliegue en %Installer. Si no, todas las entradas de nivel secundario y de mayor profundidad no funcionarán. Y todas las entradas de nivel primario funcionarán.

/patients

- funcionará, pero

/patients/all

- no funcionará.  

Este es un ejemplo de sección CSPApplication que arregla el problema y que puede que quieras usar en tu clase %Installer:

    <CSPApplication Url="${CSPAPP}"
      Recurse="1"
      Directory="${CSPAPPDIR}"
      Grant="${RESOURCE},%SQL"
      AuthenticationMethods="96"
      />
0
0 156
Artículo Javier Lorenzo Mesa · jul 8, 2022 4m read

Este artículo describe un diseño arquitectónico de complejidad intermedia para DeepSee. Al igual que en el ejemplo anterior, esta implementación incluye bases de datos separadas para almacenar la información, la implementación y la configuración de DeepSee. También presenta dos nuevas bases de datos: la primera para almacenar los globals necesarios para la sincronización, la segunda para almacenar tablas de hechos e índices.

0
0 195
Artículo Ricardo Paiva · mayo 31, 2022 6m read

Hola desarrolladores,

En el artículo anterior, describimos cómo utilizar config-api para configurar IRIS.

Ahora, vamos a intentar combinar la biblioteca con el cliente ZPM.
El objetivo es cargar un documento de configuración durante zpm install en la configure phase.

Para realizar este ejercicio, hay un repositorio de plantillas disponible aquí (está basado en objectscript-docker-template).

Tratamos de:

  • Crear una base de datos MYAPPDATA.
  • Configurar el mapeo de Globals para dc.PackageSample.*.
  • Añadir un usuario llamado SQLUserRO con acceso a la función SQL de solo lectura.
  • Añadir una configuración SSL denominada SSLAppDefault.
  • Crear una aplicación REST /rest/myapp.

El archivo de configuración iris-config.json se encuentra en el subdirectorio config-api. Es una plantilla vacía que se puede completar con el siguiente contenido:

{
    "Security.Roles":{
        "MyRoleRO" : {
            "Descripion" : "SQL Read Only Role for dc_PackageSample schema.",
            "Resources" : "%Service_SQL:U",
            "GrantedRoles" : "%SQL"
        }
    },
    "Security.SQLPrivileges": [{
        "Grantee": "MyRoleRO",
        "PrivList" : "s",
        "SQLObject" : "1,dc_PackageSample.*"
    }],
    "Security.SQLAdminPrivilegeSet" : {
        "${namespace}": [

        ]
    },
    "Security.Users": {
        "${sqlusr}": {
            "Name":"${sqlusr}",
            "Password":"$usrpwd$",
            "AccountNeverExpires":true,
            "AutheEnabled":0,
            "ChangePassword":false,
            "Comment":"Demo SQLUserRO",
            "EmailAddress":"",
            "Enabled":true,
            "ExpirationDate":"",
            "FullName":"Demo SQLUserRO",
            "NameSpace":"${namespace}",
            "PasswordNeverExpires":false,
            "PhoneNumber":"",
            "PhoneProvider":"",
            "Roles":"MyRoleRO",
            "Routine":""
        }
    },
    "Security.SSLConfigs": {
        "SSLAppDefault":{}
    },
    "Security.Applications" : {
        "/rest/myapp": {
            "NameSpace" : "${namespace}",
            "Enabled" : 1,
            "DispatchClass" : "Your.Dispatch.class",
            "CSPZENEnabled" : 1,
            "AutheEnabled": 32
        }
    },
    "SYS.Databases":{
        "${mgrdir}myappdata" : {
            "ExpansionSize":64
        }
    },
    "Databases":{
        "MYAPPDATA" : {
            "Directory" : "${mgrdir}myappdata"
        }
    },
    "MapGlobals":{
        "${namespace}": [{
            "Name" : "dc.PackageSample.*",
            "Database" : "MYAPPDATA"
        }]
    },
    "Library.SQLConnection": {

    }
}

Puedes ver el uso de ${namespace}, ${mgrdir}. Se trata de variables predefinidas y se evaluarán en el tiempo de ejecución con el namespace actual y el directorio de IRIS mgr. Otras variables predefinidas son:

  • ${cspdir}: subdirectorio CSP en el directorio de instalación de IRIS.
  • ${bindir}: directorio bin $SYSTEM.Util.BinaryDirectory()
  • ${libdir}: subdirectorio LIB en el directorio de instalación de IRIS.
  • ${username}: nombre de usuario actual $USERNAME
  • ${roles}: funciones actuales otorgadas $ROLES

Además, utilizamos ${sqlusr}, no es una variable predefinida y debemos establecer el valor desde module.xml. Realmente no lo necesitamos, pero es solo para demostrar cómo los desarrolladores pueden definir y establecer variables desde modules.xml y transmitirlas al archivo de configuración.

Para ayudarte a crear tu propio archivo de configuración, una guía rápida ([cheat sheet config-api.md])(https://github.com/lscalese/objectscript-docker-template-with-config-api/blob/master/config-api.md) también está disponible en el repositorio de plantillas.

El archivo de configuración ya está listo, el siguiente paso es el archivo module.xml.

Tenemos que:

  • Añadir el módulo config-api como una dependencia.
  • Invocar un método para cargar nuestro archivo de configuración ./config-api/iris-config.json con el argumento ${sqlusr}.
<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25">
  <Document name="objectscript-template-with-config-api.ZPM">
    <Module>
      <Name>objectscript-template-with-config-api</Name>
      <Version>0.0.1</Version>
      <Packaging>module</Packaging>

      <FileCopy Name="config-api/" InstallDirectory="${libdir}config-api/"/>
      <Invoke Class="Api.Config.Services.Loader" Method="LoadFromInvoke">
        <Arg>${root}config-api/iris-config.json</Arg>
        <Arg>sqlusr</Arg>
        <Arg>SQLUserRO</Arg>
      </Invoke>

      <SourcesRoot>src</SourcesRoot>
      <Resource Name="dc.PackageSample.PKG"/>

      <Dependencies>
        <ModuleReference>
          <Name>config-api</Name>
          <Version>1.0.0</Version>
        </ModuleReference>
      </Dependencies>

    </Module>
  </Document>
</Export>

Echa un vistazo a la etiqueta Invoke:

<Invoke Class="Api.Config.Services.Loader" Method="LoadFromInvoke">
        <Arg>${root}config-api/iris-config.json</Arg> 
        <Arg>sqlusr</Arg>
        <Arg>SQLUserRO</Arg>
</Invoke>

El primer argumento es la ruta al archivo de configuración, ${root} contiene el directorio del módulo usado por zpm durante la implementación.
Después de eso, todos los demás argumentos deben emparejarse. En primer lugar, una cadena con el nombre de la variable seguido del valor relacionado.
En nuestro ejemplo sqlusr para la variable ${sqlusr} seguido del valor SQLUserRO.
Puedes pasar tantos argumentos emparejados como necesites.

Ten en cuenta que hay una etiqueta FileCopy: <FileCopy Name="config-api/" InstallDirectory="${libdir}config-api/"/> Esta etiqueta existe solo para forzar al zpm a empaquetar el archivo de configuración. Deberíamos agregar una etiqueta Invoke para eliminar el directorio que se va a limpiar, así:

<Invoke Class="%File" Method="RemoveDirectoryTree">
    <Arg>${libdir}config-api/</Arg>
</Invoke>

Module.xml está listo, es hora de probarlo. Compila e inicia el contenedor docker-compose up -d --build.
Deberías ver estos registros durante la fase de configuración:

[objectscript-template-with-config-api] Configure START
2021-04-08 19:24:43 Load from file /opt/irisbuild/config-api/iris-config.json ... 
2021-04-08 19:24:43 Start load configuration
2021-04-08 19:24:43 {
  "Security.Roles":{
    "MyRoleRO":{
      "Descripion":"SQL Read Only Role for dc_PackageSample schema.",
      "Resources":"%Service_SQL:U",
      "GrantedRoles":"%SQL"
    }
  },
  "Security.SQLPrivileges":[
    {
      "Grantee":"MyRoleRO",
      "PrivList":"s",
      "SQLObject":"1,dc_PackageSample.*"
    }
  ],
  "Security.SQLAdminPrivilegeSet":{
    "USER":[
    ]
  },
  "Security.Users":{
    "SQLUserRO":{
      "Name":"SQLUserRO",
      "Password":"$usrpwd$",
      "AccountNeverExpires":true,
      "AutheEnabled":0,
      "ChangePassword":false,
      "Comment":"Demo SQLUserRO",
      "EmailAddress":"",
      "Enabled":true,
      "ExpirationDate":"",
      "FullName":"Demo SQLUserRO",
      "NameSpace":"USER",
      "PasswordNeverExpires":false,
      "PhoneNumber":"",
      "PhoneProvider":"",
      "Roles":"MyRoleRO",
      "Routine":""
    }
  },
  "Security.SSLConfigs":{
    "SSLAppDefault":{
    }
  },
  "Security.Applications":{
    "/rest/myapp":{
      "NameSpace":"USER",
      "Enabled":1,
      "DispatchClass":"Your.Dispatch.class",
      "CSPZENEnabled":1,
      "AutheEnabled":32
    }
  },
  "SYS.Databases":{
    "/usr/irissys/mgr/myappdata":{
      "ExpansionSize":64
    }
  },
  "Databases":{
    "MYAPPDATA":{
      "Directory":"/usr/irissys/mgr/myappdata"
    }
  },
  "MapGlobals":{
    "USER":[
      {
        "Name":"dc.PackageSample.*",
        "Database":"MYAPPDATA"
      }
    ]
  },
  "Library.SQLConnection":{
  }
}
2021-04-08 19:24:43  * Security.Roles
2021-04-08 19:24:43    + Create MyRoleRO ... OK
2021-04-08 19:24:43  * Security.SQLPrivileges
2021-04-08 19:24:43    + Create {"Grantee":"MyRoleRO","PrivList":"s","SQLObject":"1,dc_PackageSample.*"} ... OK
2021-04-08 19:24:43  * Security.SQLAdminPrivilegeSet
2021-04-08 19:24:43  * Security.Users
2021-04-08 19:24:43    + Create SQLUserRO ... OK
2021-04-08 19:24:43  * Security.SSLConfigs
2021-04-08 19:24:43    + Create SSLAppDefault ... OK
2021-04-08 19:24:43  * Security.Applications
2021-04-08 19:24:43    + Create /api/config ... OK
2021-04-08 19:24:43  * SYS.Databases
2021-04-08 19:24:43    + Create /usr/irissys/mgr/myappdata ... OK
2021-04-08 19:24:43  * Databases
2021-04-08 19:24:43    + Create MYAPPDATA ... OK
2021-04-08 19:24:44  * MapGlobals
2021-04-08 19:24:44    + Create USER dc.PackageSample.* ... OK
2021-04-08 19:24:44  * Library.SQLConnection
[objectscript-template-with-config-api] Configure SUCCESS

Tu configuración se aplicó y el archivo de configuración se empaquetará cuando se publique. Puedes comprobarlo en el Portal de administración.

¡Gracias!

0
0 85
Artículo Ricardo Paiva · ene 14, 2022 6m read

Hola desarrolladores,

Escribir un script para el despliegue de una aplicación puede ser muy interesante para garantizar un despliegue rápido sin olvidarse de nada. config-api es una biblioteca para ayudar a los desarrolladores a escribir scripts de configuración basados en un documento JSON.

Características implementadas:

  • Establecer la configuración del sistema
  • Establecer la configuración de seguridad
  • Habilitar servicios
  • Configurar namespaces, bases de datos y mapeos
  • Exportar configuración existente
  • Todas las funciones están expuestas con una API RESTful

Esta biblioteca se centra en la configuración de IRIS para ayudar a la implementación de aplicaciones. Por lo tanto, config-api no importa/compila la función de código, considerando queesa debería ser la función del módulo de instalación de tu aplicación o el registro del cliente. config-api podría usarse con el cliente ZPM para configurar los ajustes de IRIS en la implementación del módulo; aprenderemos cómo combinar esta biblioteca con ZPM en otro artículo.

Instalación

zpm “install config-api”

Si no eres usuario de ZPM, descarga la última versión en formato XML con dependencias página de publicación importación y compilación.

Primer paso

Vamos a escribir un documento JSON de configuración simple, para establecer algunas configuraciones del sistema. En este primer documento:

  • Habilitamos journal freeze en caso de error.
  • Establecemos el tamaño límite de journal en 256 MB.
  • Establecemos SystemMode para desarrollo.
  • Aumentamos el locksiz.
  • Aumentamos el LockThreshold.
Set config = {
  "Journal": {                                /* Service class Api.Config.Journal */
       "FreezeOnError":1,
       "FileSizeLimit":256
   },
   "SQL": {                                    /* Service class Api.Config.SQL */
       "LockThreshold" : 2500
   },
   "config": {                                 /* Service class Api.Config.config */
       "locksiz" : 33554432
   },
   "Startup":{                                 /* Service class Api.Config.Startup */
       "SystemMode" : "DEVELOPMENT"
   }
}
Set sc = ##class(Api.Config.Services.Loader).Load(config)

Estructura del documento JSON de configuración

Las claves de primer nivel (Journal,SQL,config,Startup) están relacionadas con las clases en el namespace %SYS (usando una clase intermedia en el paquete Api.Config.Services). Significa que Journal admite todas las propiedades disponibles en Config.Journal, SQLtodas las propiedades en Config.SQL, etc...

Salida:

2021-03-31 18:31:54 Start load configuration
2021-03-31 18:31:54 {
  "Journal":{
    "FreezeOnError":1,
            "FileSizeLimit":256
  },
  "SQL":{
    "LockThreshold":2500
  },
  "config":{
    "locksiz":33554432
  },
  "Startup":{
    "SystemMode":"DEVELOPMENT"
  }
}
2021-03-31 18:31:54  * Journal
2021-03-31 18:31:54    + Update Journal ... OK
2021-03-31 18:31:54  * SQL
2021-03-31 18:31:54    + Update SQL ... OK
2021-03-31 18:31:54  * config
2021-03-31 18:31:54    + Update config ... OK
2021-03-31 18:31:54  * Startup
2021-03-31 18:31:54    + Update Startup ... OK

Truco: el método Load es compatible con un argumento de cadena, en este caso, la cadena debe ser un nombre de archivo para un documento de configuración JSON (también se permite objetos stream).

Crear un entorno de aplicación

En esta sección, escribimos un documento de configuración para crear:

  • Un namespace "MYAPP"
  • 4 bases de datos (MYAPPDATA, MYAPPCODE, MYAPPARCHIVE,MYAPPLOG)
  • 1 aplicación web CSP (/csp/zwebapp)
  • 1 aplicación web REST (/csp/zrestapp)
  • Configuración de mapeo de globals
Set config = {
    "Defaults":{
        "DBDIR" : "${MGRDIR}",
        "WEBAPPDIR" : "${CSPDIR}",
        "DBDATA" : "${DBDIR}myappdata/",
        "DBARCHIVE" : "${DBDIR}myapparchive/",
        "DBCODE" : "${DBDIR}myappcode/",
        "DBLOG" : "${DBDIR}myapplog/"
    },
    "SYS.Databases":{
        "${DBDATA}" : {"ExpansionSize":128},
        "${DBARCHIVE}" : {},
        "${DBCODE}" : {},
        "${DBLOG}" : {}
    },
    "Databases":{
        "MYAPPDATA" : {
            "Directory" : "${DBDATA}"
        },
        "MYAPPCODE" : {
            "Directory" : "${DBCODE}"
        },
        "MYAPPARCHIVE" : {
            "Directory" : "${DBARCHIVE}"
        },
        "MYAPPLOG" : {
            "Directory" : "${DBLOG}"
        }
    },
    "Namespaces":{
        "MYAPP": {
            "Globals":"MYAPPDATA",
            "Routines":"MYAPPCODE"
        }
    },
    "Security.Applications": {
        "/csp/zrestapp": {
            "DispatchClas" : "my.dispatch.class",
            "Namespace" : "MYAPP",
            "Enabled" : "1",
            "AuthEnabled": "64",
            "CookiePath" : "/csp/zrestapp/"
        },
        "/csp/zwebapp": {
            "Path": "${WEBAPPDIR}zwebapp/",
            "Namespace" : "MYAPP",
            "Enabled" : "1",
            "AuthEnabled": "64",
            "CookiePath" : "/csp/zwebapp/"
        }
    },
    "MapGlobals":{
        "MYAPP": [{
            "Name" : "Archive.Data",
            "Database" : "MYAPPARCHIVE"
        },{
            "Name" : "App.Log",
            "Database" : "MYAPPLOG"
        }]
    }
}
Set sc = ##class(Api.Config.Services.Loader).Load(config)

Salida:

2021-03-31 20:20:07 Start load configuration
2021-03-31 20:20:07 {
  "SYS.Databases":{
    "/usr/irissys/mgr/myappdata/":{
      "ExpansionSize":128
    },
    "/usr/irissys/mgr/myapparchive/":{
    },
    "/usr/irissys/mgr/myappcode/":{
    },
    "/usr/irissys/mgr/myapplog/":{
    }
  },
  "Databases":{
    "MYAPPDATA":{
      "Directory":"/usr/irissys/mgr/myappdata/"
    },
    "MYAPPCODE":{
      "Directory":"/usr/irissys/mgr/myappcode/"
    },
    "MYAPPARCHIVE":{
      "Directory":"/usr/irissys/mgr/myapparchive/"
    },
    "MYAPPLOG":{
      "Directory":"/usr/irissys/mgr/myapplog/"
    }
  },
  "Namespaces":{
    "MYAPP":{
      "Globals":"MYAPPDATA",
      "Routines":"MYAPPCODE"
    }
  },
  "Security.Applications":{
    "/csp/zrestapp":{
      "DispatchClas":"my.dispatch.class",
      "Namespace":"MYAPP",
      "Enabled":"1",
      "AuthEnabled":"64",
      "CookiePath":"/csp/zrestapp/"
    },
    "/csp/zwebapp":{
      "Path":"/usr/irissys/csp/zwebapp/",
      "Namespace":"MYAPP",
      "Enabled":"1",
      "AuthEnabled":"64",
      "CookiePath":"/csp/zwebapp/"
    }
  },
  "MapGlobals":{
    "MYAPP":[
      {
        "Name":"Archive.Data",
        "Database":"MYAPPARCHIVE"
      },
      {
        "Name":"App.Log",
        "Database":"MYAPPLOG"
      }
    ]
  }
}
2021-03-31 20:20:07  * SYS.Databases
2021-03-31 20:20:07    + Create /usr/irissys/mgr/myappdata/ ... OK
2021-03-31 20:20:07    + Create /usr/irissys/mgr/myapparchive/ ... OK
2021-03-31 20:20:07    + Create /usr/irissys/mgr/myappcode/ ... OK
2021-03-31 20:20:07    + Create /usr/irissys/mgr/myapplog/ ... OK
2021-03-31 20:20:07  * Databases
2021-03-31 20:20:07    + Create MYAPPDATA ... OK
2021-03-31 20:20:07    + Create MYAPPCODE ... OK
2021-03-31 20:20:07    + Create MYAPPARCHIVE ... OK
2021-03-31 20:20:07    + Create MYAPPLOG ... OK
2021-03-31 20:20:07  * Namespaces
2021-03-31 20:20:07    + Create MYAPP ... OK
2021-03-31 20:20:07  * Security.Applications
2021-03-31 20:20:07    + Create /csp/zrestapp ... OK
2021-03-31 20:20:07    + Create /csp/zwebapp ... OK
2021-03-31 20:20:07  * MapGlobals
2021-03-31 20:20:07    + Create MYAPP Archive.Data ... OK
2021-03-31 20:20:07    + Create MYAPP App.Log ... OK

¡Funciona! La configuración se cargó con éxito.

En el próximo artículo, aprenderemos a usar config-api con ZPM para implementar tu aplicación.

1
0 181
Artículo Ricardo Paiva · mayo 3, 2022 7m read

Todo el código fuente del artículo está disponible en: https://github.com/antonum/ha-iris-k8s 

En el artículo anterior, comentamos cómo configurar IRIS en el clúster k8s con alta disponibilidad, basado en el almacenamiento distribuido, en vez del mirroring tradicional. Como ejemplo, ese artículo utilizaba el clúster Azure AKS. En esta ocasión, seguiremos explorando las configuraciones de alta disponibilidad en los k8s. Esta vez, basado en Amazon EKS (servicio administrado para ejecutar Kubernetes en AWS) e incluiría una opción para hacer copias de seguridad y restauraciones de la base de datos, basado en Kubernetes Snapshot.

Instalación

Vamos a lo más importante. Primero: necesitas una cuenta de AWS, y las herramientas AWS CLI,kubectl y eksctl instaladas. Para crear el nuevo clúster, ejecuta el siguiente comando:

eksctl create cluster \
--name my-cluster \
--node-type m5.2xlarge \
--nodes 3 \
--node-volume-size 500 \
--region us-east-1

Este comando tarda unos 15 minutos, implementa el clúster EKS y lo convierte en un clúster predeterminado para tu herramienta kubectl. Puedes verificar la implementación ejecutando:

kubectl get nodes
NAME                                             STATUS   ROLES    AGE   VERSION
ip-192-168-19-7.ca-central-1.compute.internal    Ready    &lt;none>   18d   v1.18.9-eks-d1db3c
ip-192-168-37-96.ca-central-1.compute.internal   Ready    &lt;none>   18d   v1.18.9-eks-d1db3c
ip-192-168-76-18.ca-central-1.compute.internal   Ready    &lt;none>   18d   v1.18.9-eks-d1db3c

El siguiente paso es instalar el motor de almacenamiento distribuido Longhorn.

kubectl create namespace longhorn-system
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.1.0/deploy/iscsi/longhorn-iscsi-installation.yaml --namespace longhorn-system
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml --namespace longhorn-system

Y, por último, el propio IRIS:

kubectl apply -f https://github.com/antonum/ha-iris-k8s/raw/main/tldr.yaml

En este momento, tendrás un clúster EKS completamente funcional con el almacenamiento distribuido de Longhorn y la implementación de IRIS instaladas. Puedes volver al artículo anterior e intentar hacer todo tipo de daño en el clúster y la implementación de IRIS, solo para ver cómo el sistema se repara a sí mismo. Echa un vistazo a la sección "Simulación del error".

Bonus #1 IRIS en ARM

IRIS EKS y Longhorn son compatibles con la arquitectura ARM, por lo que podemos implementar la misma configuración utilizando instancias de AWS Graviton2, basadas en la arquitectura ARM.

Todo lo que necesitas es cambiar el tipo de instancia para los nodos EKS a la familia "m6g" y la imagen IRIS a la basada en ARM.

eksctl create cluster \
--name my-cluster-arm \
--node-type m6g.2xlarge \
--nodes 3 \
--node-volume-size 500 \
--region us-east-1

tldr.yaml

containers:
#- image: store/intersystems/iris-community:2020.4.0.524.0
- image: store/intersystems/irishealth-community-arm64:2020.4.0.524.0
name: iris

O simplemente utiliza:

kubectl apply -f https://github.com/antonum/ha-iris-k8s/raw/main/tldr-iris4h-arm.yaml

¡Eso es todo! Ya tienes el clúster IRIS Kubernetes, ejecutándose en la plataforma ARM.

Bonus #2 Copia de seguridad y restauración

Una parte de la arquitectura para nivel de producción que se suele pasar por alto es la capacidad de crear copias de seguridad de la base de datos y que las restaure y/o clone rápidamente cuando sea necesario.

En Kubernetes, la manera más habitual de hacerlo es utilizando Persistent Volumen Snapshots (Snapshots de volumen persistente).

En primer lugar, debes instalar todos los componentes de k8s requeridos:

#Install CSI Snapshotter and CRDs

kubectl apply -n kube-system -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -n kube-system -f https://github.com/kubernetes-csi/external-snapshotter/raw/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -n kube-system -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -n kube-system -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
kubectl apply -n kube-system -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml

A continuación, configura las credenciales del bucket S3 para Longhorn (consulta estas instrucciones):

#Longhorn backup target s3 bucket and credentials longhorn would use to access that bucket
#See https://longhorn.io/docs/1.1.0/snapshots-and-backups/backup-and-restore/set-backup-target/ for manual setup instructions
longhorn_s3_bucket=longhorn-backup-123xx #bucket name should be globally unique, unless you want to reuse existing backups and credentials
longhorn_s3_region=us-east-1
longhorn_aws_key=AKIAVHCUNTEXAMPLE
longhorn_aws_secret=g2q2+5DVXk5p3AHIB5m/Tk6U6dXrEXAMPLE

El siguiente comando tomará las variables de entorno del paso anterior y las utilizará para configurar la copia de seguridad de Longhorn

#configure Longhorn backup target and credentials

cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: longhorn.io/v1beta1
kind: Setting
metadata:
 name: backup-target
 namespace: longhorn-system
value: "s3://$longhorn_s3_bucket@$longhorn_s3_region/" # backup target here
---
apiVersion: v1
kind: Secret
metadata:
 name: "aws-secret"
 namespace: "longhorn-system"
 labels:
data:
 # echo -n '&lt;secret>' | base64
 AWS_ACCESS_KEY_ID: $(echo -n $longhorn_aws_key | base64)
 AWS_SECRET_ACCESS_KEY: $(echo -n $longhorn_aws_secret | base64)
---
apiVersion: longhorn.io/v1beta1
 kind: Setting
metadata:
 name: backup-target-credential-secret
 namespace: longhorn-system
value: "aws-secret" # backup secret name here
EOF

Puede parecer mucho, pero esencialmente le indica a Longhorn que utilice un bucket S3 específico con las credenciales precisas para almacenar el contenido de las copias de seguridad.

¡Eso es todo! Si ahora vas a la interfaz de usuario de Longhorn, podrás crear copias de seguridad, restaurarlas, etc.

Un recordatorio rápido sobre cómo conectarse a la interfaz de usuario de Longhorn:

kubectl get pods -n longhorn-system
# note the full pod name for 'longhorn-ui-...' pod
kubectl port-forward longhorn-ui-df95bdf85-469sz 9000:8000 -n longhorn-system

Esto reenviaría el tráfico desde la interfaz de usuario de Longhorn a tu http://localhost:9000 

Programación de la copia de seguridad/restauración

Hacer copias de seguridad y restauraciones a través de la interfaz de usuario de Longhorn podría ser un primer paso suficientemente bueno, pero vamos a ir un paso más allá y realizar copias de seguridad y restauraciones programáticamente, utilizando APIs de Snapshots k8s.

En primer lugar, el propio snapshot. iris-volume-snapshot.yaml

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: iris-longhorn-snapshot
spec:
  volumeSnapshotClassName: longhorn
  source:
    persistentVolumeClaimName: iris-pvc

Este snapshot de volumen se refiere al volumen de la fuente "iris-pvc" que usamos para nuestra implementación de IRIS. Así que con solo aplicar esto, el proceso para crear una copia de seguridad se iniciaría inmediatamente .

Es una buena idea ejecutar el Freeze/Thaw de IRIS Write Daemon antes o después del snapshot.

#Freeze Write Daemon
echo "Freezing IRIS Write Daemon"
kubectl exec -it -n $namespace $pod_name -- iris session iris -U%SYS "##Class(Backup.General).ExternalFreeze()"
status=$?
if [[ $status -eq 5 ]]; then
 echo "IRIS WD IS FROZEN, Performing backup"
 kubectl apply -f backup/iris-volume-snapshot.yaml -n $namespace
elif [[ $status -eq 3 ]]; then
 echo "IRIS WD FREEZE FAILED"
fi
#Thaw Write Daemon
kubectl exec -it -n $namespace $pod_name -- iris session iris -U%SYS "##Class(Backup.General).ExternalThaw()"

El proceso de restauración es bastante sencillo. Esencialmente se crea un nuevo PVC y se especifican los snapshots como la fuente.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: iris-pvc-restored
spec:
  storageClassName: longhorn
  dataSource:
    name: iris-longhorn-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

A continuación, solo hay que crear una nueva implementación, basada en este PVC. Comprueba este script de prueba en un repositorio de github que podría realizarse con la siguiente secuencia:

  • Crear una nueva implementación de IRIS
  • Añadir algunos datos a IRIS
  • Freeze Write Daemon, tome un snapshot, thaw Write Daemon
  • Crear un clon de implementación de IRIS, basado en el snapshot
  • Verificar que todos los datos todavía están allí

En este momento tendrá dos implementaciones idénticas de IRIS, una de las cuales es un clon hecho por medio de una copia de seguridad de la otra.

¡Espero que os resulte útil!

0
0 324
Artículo Eduardo Anglada · abr 5, 2022 5m read

Si estás implementando más de un entorno/región/nube/cliente, inevitablemente te encontrarás con el problema de la gestión de la configuración.

Aunque todas (o solo varias de) tus implementaciones pueden compartir el mismo código fuente, algunas partes, como la configuración (ajustes, contraseñas) son diferentes de una implementación a otra y se deben gestionar de alguna manera.

En este artículo, intentaré ofrecer varios consejos sobre ese tema. Y comentaré principalmente las implementaciones de los contenedores.

Unificación del código base

Antes de comenzar con la gestión de la configuración, hablemos de la unificación del código base. El problema es el siguiente: el código base debe pretender, por lo general, confluir en una sola versión. Por supuesto, en cualquier momento, tendrás varias versiones de tu código base: la versión DEV con todas las nuevas características, la versión TEST con un código de prueba adicional, la versión PROD, y así sucesivamente. Y eso está bien porque, en este ejemplo, los cambios se fusionan en una versión a lo largo del tiempo. Varias ramas de DEV se convierten en una rama de TEST y así sucesivamente.

El problema comienza cuando tenemos varias versiones en el paso final de nuestro pipeline de implementación. Por ejemplo, el cliente ABC pidió una característica particular XYZ, y ahora hay dos versiones del código base PROD - con la característica XYZ y sin ella. Esto es problemático ya que duplica inmediatamente nuestros tiempos de creación y el consumo de recursos. Claro, algunas veces no hay manera de hacerlo. Sin embargo, supongamos que tienes este tipo de divergencias persistentes en el código base. En ese caso, quizá merezca la pena investigar si se pueden agrupar en una sola versión; en este caso, la característica XYZ se activa o no cuando se inicia.

Dicho esto, vamos a la gestión de la configuración.

 

Gestión de la configuración

¿Qué queremos?

  • No almacenar todas las configuraciones posibles en un solo contenedor (es inseguro para uno, y aún debemos elegir de alguna manera qué configuración aplicar para otro)
  • No crear un contenedor en cada configuración (simplifica el pipeline de CD)

Necesitamos transferir la configuración (ajustes, información confidencial, ...) durante el arranque de InterSystems IRIS y asignarla a nuestra aplicación.

Transferencia de la configuración

Hay varias maneras de transferir la configuración al inicio.

Variables de entorno

Rápido y fácil. En caso de que quieras almacenar todo en una variable, utiliza JSON para realizar la serialización. Además, recuerda que Windows tiene un límite de 32K caracteres en las variables de entorno (megabytes en Linux). Para recuperar variables de entorno utiliza $SYSTEM.Util.GetEnviron("ENV_VAR_NAME"). La principal ventaja es la facilidad de implementación. Además, verifica tu herramienta CD - por lo general, tiene algún tipo de soporte para variables de entorno durante la ejecución del pipeline, algunas veces con soporte de la información confidencial para que sea más seguro.

Archivos montados

La configuración puede ser un archivo montado al inicio. La ventaja es que no tiene límites en la longitud. La desventaja es que no todas las ofertas de la nube son compatibles con los archivos montados, e incluso si lo hacen, la gestión de archivos puede ser más complicada que la gestión de las variables de entorno. Ten en cuenta que los archivos siempre se pueden recuperar de las capas antiguas de un contenedor, aunque se hayan eliminado en una capa posterior.

Combinación en CPF

La configuración del sistema se puede transferir mediante un Archivo Combinado de Configuración. Y es una funcionalidad integrada. Desventaja: El Archivo de Combinación CPF no se encarga de la configuración a nivel de la aplicación.

Docker/Información confidencial del CSP

Docker puede montar información confidencial como un archivo dentro de un contenedor. Las ofertas en la nube a menudo ofrecen una funcionalidad similar. Utilízalo en vez de los archivos sin formato para mejorar la seguridad.

Análisis de la configuración

Bien, ya transmitiste la configuración dentro de un contenedor. ¿Y ahora qué? ¿Cómo la analizamos?

Hay varias opciones:

%ZSTART

%ZSTART incluye tu código personalizado, que se ejecuta cuando se inicia el sistema. Por ejemplo:

SYSTEM
    try {
        new $namespace
        set $namespace = "USER"
        // apply configuration
        set $namespace = "%SYS"
    } catch ex {
        zn "%SYS"
        do ex.Log()
    }
    quit 1

Es importante tener en cuenta que %ZSTART se debe probar completamente, ya que InterSystems IRIS no se iniciará (o se comportará de forma errática) si la rutina %ZSTART devuelve un error.

Ahora ya estás preparado para aplicar tu configuración.

La forma de almacenar/aplicar la configuración a nivel de la aplicación depende, naturalmente, de la aplicación, pero La configuración predeterminada del sistema{.editor-rtfLink} está disponible si utilizas la interoperabilidad. Incluso si no utilizas las producciones de interoperabilidad, puedes utilizar la configuración predeterminada del sistema, ya que está disponible para todo el mundo (siempre y cuando la interoperabilidad esté activada en un namespace).

Para crear una nueva configuración, ejecuta:

Set setting = ##class(Ens.Config.DefaultSettings).%New()
Set setting.ProductionName = production
Set setting.ItemName = itemname
Set setting.HostClassName = hostclassname
Set setting.SettingName = settingname
Set setting.SettingValue = settingvalue
Set setting.Description = description
Set sc = setting.%Save()

Y para recuperar la configuración, llama a cualquiera:

set sc = ##class(Ens.Config.DefaultSettings).%GetSetting(production, itemname, hostclassname, "", settingname, .settingvalue)
set settingvalue = ##class(Ens.Director).GetProductionSettingValue(production, settingname, .sc)

Los hosts de interoperabilidad reciben su configuración automáticamente al iniciar el trabajo del host empresarial.

Resumen

Es fundamental que tu aplicación se pueda configurar cuando se implementa en más de un servidor. Puede ser bastante fácil en la primera parte del ciclo de desarrollo, pero se irá complicando a medida que la aplicación crezca. InterSystems IRIS ofrece varias herramientas que se pueden utilizar para configurar el estado de tu aplicación durante el arranque.

.

¿Cómo gestionas las implementaciones múltiples?

.
0
0 179
Artículo Eduardo Anglada · mar 23, 2022 2m read

¡Hola desarrolladores!

A veces necesitamos publicar la imagen Docker de la solución InterSystems IRIS en la que estamos trabajando. Existen diferentes posibilidades, por ejemplo:

  1. Usar la imagen en un cluster de Kubernetes.
  2. Que un compañero  ejecute la imagen desde un repositorio público sin tener que generarla.

La mejor solución es subir la imagen al Registro Hub de Docker o al Registro de Github.

En este breve artículo, propongo una forma de hacerlo automáticamente cada vez que subas (usando git push) cambios a tu repositorio GitHub.

0
0 120
Artículo Laura Blázquez García · feb 11, 2022 4m read

Hasta hace no mucho, todos los entornos con los que trabajábamos eran Ensemble 2017.2. Pero recientemente hemos migrado todos los entornos a la versión 2021.1 de IRIS for Health. Ha sido un camino complicado, pero tras analizarlo detenidamente, encontramos la forma de conseguirlo.

Contamos con un servidor de desarrollo y dos servidores en producción en mirroring, en modo Failover. Tenemos más de 40 Namespaces dando servicio, unos con integraciones HL7, otros con servicios Soap, servicios Rest, procesado de archivos... un poco de todo. Necesitábamos estar seguros de que la migración a IRIS no iba a suponer un problema y sobre todo, evitar a toda costa un corte de servicio. Así que lo primero que teníamos que hacer era establecer un plan.

0
0 225
Artículo Jose-Tomas Salvador · dic 29, 2021 1m read

Para aquellos a los que, en un momento dado, necesitan probar cómo va eso del ECP para escalabilidad horizontal (cómputo y/o concurrencia de usuarios y procesos), pero les da pereza o no tienen tiempo de montar el entorno, configurar los nodos, etc..., acabo de publicar en Open Exchange la aplicación/ejemplo OPNEx-ECP Deployment .

0
0 224
Artículo Alberto Fuentes · dic 24, 2021 4m read

¡Hola desarrolladores!

Como sabéis, es muy fácil publicar un paquete en el repositorio de la Comunidad de Desarrolladores

Pero, ¿cómo se puede probar antes de publicarlo? ¿Cómo se puede garantizar que todo lo que se introdujo en module.xml funciona correctamente?

¡Seguid leyendo las instrucciones que os detallo a continuación!

0
0 186
Artículo Alberto Fuentes · sep 20, 2021 2m read

¡Hola desarrolladores!

Otra forma de empezar a utilizar InterSystems Objectscript Package Manager es descargar las imágenes pre-construidas de InterSystems IRIS Community Edition o IRIS for Health Community Edition.

Estas imágenes de IRIS están desplegadas en DockerHub y puedes ejecutarlas directamente con este comando:

docker run --rm -p 52773:52773 --init --name my-iris -d intersystemsdc/iris-community:2021.1.0.215.0-zpm

A continuación, puedes lanzar una sesión de terminal de esta forma:

docker exec -it my-iris iris session IRIS

Y por último, instalar un módulo de zpm así:

USER>zpm

=============================================================================
|| Welcome to the Package Manager Shell (ZPM).                             ||
|| Enter q/quit to exit the shell. Enter ?/help to view available commands ||
=============================================================================
zpm:USER>install objectscript-math

[objectscript-math]	Reload START (/usr/irissys/mgr/.modules/USER/objectscript-math/0.0.5/)
[objectscript-math]	Reload SUCCESS
[objectscript-math]	Module object refreshed.
[objectscript-math]	Validate START
[objectscript-math]	Validate SUCCESS
[objectscript-math]	Compile START
[objectscript-math]	Compile SUCCESS
[objectscript-math]	Activate START
[objectscript-math]	Configure START
[objectscript-math]	Configure SUCCESS
[objectscript-math]	MakeDeployed START
[objectscript-math]	MakeDeployed SUCCESS
[objectscript-math]	Activate SUCCESS
zpm:USER>

Puedes utilizar los mismos comandos para IRIS For Health con el tag intersystemsdc/irishealth-community:2021.1.0.215.0-zpm

Estas imágenes se publican para IRIS Community Edition y para IRIS For Health Community Edition en repositorios de DockerHub.

Las etiquetas se actualizan con cada nueva distribución de IRIS.

Happy coding!

0
0 113
Artículo Pierre-Yves Duquesnoy · jun 8, 2021 2m read

¡Hola desarrolladores!

A menudo, tenemos que implementar algunos datos junto con código de aplicación.

Y para los desarrolladores de InterSystems IRIS, la pregunta podría ser: "¿Cómo puedo desplegar los datos que tengo en globals?"

InterSystems IRIS Globals Model QuickStart | InterSystems

En este artículo, os propongo uno de los métodos - desplegar los datos de los globals utilizando el ZPM package manager.

0
0 122
Artículo Eduardo Anglada · mayo 24, 2021 4m read

Qué te parece si te digo que muy pronto te podrás conectar a IRIS desde la aplicación escrita en Rust...

¿Qué es Rust?

Rust es un lenguaje de programación multiparadigma diseñado teniendo en cuenta el rendimiento, la seguridad y especialmente que la concurrencia sea segura. Rust es sintácticamente similar a C++, pero puede garantizar la seguridad de la memoria mediante el uso de un verificador de préstamos para validar las referencias. Rust logra la seguridad de la memoria sin emplear un recolector de basura, y el conteo de referencias es opcional. (c) Wikipedia

Es el lenguaje más valorado durante los últimos cinco años en la  encuesta de Stack Overflow 2020.

0
0 180