Artículo
· 11 oct, 2023 Lectura de 12 min

ECP con Docker

¡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".

Archivo Contenedor Descripción
./certificates/CA_Server.cer Servidor de aplicaciones y servidor de datos Certificado del servidor de autoridad
./certificates/app_server.cer Servidor de aplicaciones Certificado para la instancia del servidor de aplicaciones de IRIS
./certificates/app_server.key Servidor de aplicaciones Clave privada correspondiente
./certificates/data_server.cer Servidor de datos Certificado para la instancia del servidor de datos de IRIS
./certificates/data_server.key Servidor de datos Clave 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/dat...

{
   "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.

Comentarios (0)1
Inicie sesión o regístrese para continuar