0 Abonnés · 13 Publications

Pratique d'ingénierie logicielle qui vise à unifier le développement (Dev) et l'exploitation (Ops) des logiciels.

Article Iryna Mykhailova · Juil 4, 2025 3m read

Une qualité de service (QoS) est attribuée à tous les pods. Trois niveaux de priorité sont attribués aux pods d'un nœud. Ces niveaux sont les suivants :

1) Garanti : Priorité élevée

2) Évolutif : Priorité moyenne

3) Meilleur effort : Priorité faible

Il s'agit d'indiquer au kubelet quelles sont vos priorités sur un nœud donné si des ressources doivent être récupérées. Ce superbe GIF d'Anvesh Muppeda ci-dessous l'explique.

Si des ressources doivent être libérées, les pods avec une QoS « Meilleur effort » seront d'abord évincés, puis ceux avec une QoS « Évolutif », et enfin ceux avec une QoS garantie. L'idée est qu'en évinçant les pods de priorité inférieure, nous récupérerons suffisamment de ressources sur le nœud pour éviter d'avoir à évincer les pods avec une QoS garantie.

0
0 30
Article Lorenzo Scalese · Mars 24, 2025 7m read

Je vais vous montrer comment vous pouvez installer très rapidement sur votre ordinateur un cluster de nœuds InterSystems IRIS en sharding. Dans cet article, mon objectif n'est pas de parler du sharding en détail, ni de définir une architecture de déploiement pour un cas réel, mais de vous montrer comment vous pouvez rapidement installer sur votre machine un cluster d'instances d'IRIS en sharding avec lequel vous pouvez jouer et faire des tests. Si vous souhaitez en savoir plus sur le sharding dans IRIS, vous pouvez consulter la documentation en cliquant ici: clicking here.  

Disons dès le départ que la technologie de sharding d'IRIS va nous permettre de faire deux choses:

  • Définir, charger et consulter des tables fragmentées ou des shards, dont les données seront réparties de manière transparente entre les nœuds du cluster
  • Définir  des tables fédérées, qui offrent une vue globale et composite des données appartenant à des tables différentes et qui, physiquement, sont stockées sur différents nœuds distribués

Donc, comme je l'ai dit, nous laissons le sujet du jeu avec des shards ou des tableaux fédérés pour d'autres articles, et nous nous concentrons maintenant sur l'étape précédente, c'est-à-dire sur la mise en place du cluster de nœuds en sharding.

Pour notre exemple, nous allons utiliser Docker Desktop (for Windows or MacOS) et nous appuyer sur la fonctionnalité d'IRIS: CPF Merge; ou fusion de fichier de configuration; qui nous permet d'utiliser un fichier texte brut dans lequel nous inclurons les sections et propriétés de configuration d'IRIS que nous voulons appliquer pour modifier la configuration actuelle de l'instance d'IRIS. Cette fichier se superpose au fichier  iris.cpf  qui définit la configuration par défaut de l'instance.

Ce merge est automatiquement « activé » lors de l'ajout de la variable d'environnement: ISC_CPF_MERGE_FILE à laquelle  nous devons avoir attribué un chemin valide vers un fichier contenant les sections du fichier cpf que nous voulons modifier. Au démarrage, IRIS vérifie si on lui a demandé de faire une fusion (merge) (en gros, si cette variable d'environnement existe et pointe vers un fichier valide). Si c'est le cas, vous pouvez procéder à la fusion et démarrer.

Je ne fais pas plus de détours et je vous inclus le fichier docker-compose.yml qui fera la magie:

 
docker-compose.yml
services:
  # iris container
  irisnode1:
    init: true 
    hostname: irishost1
    image: shardnode:latest 
    container_name: irisnode1
    build: 
      context: ./cluster
      dockerfile: Dockerfile
    ports:
    - "9991:1972"
    environment: 
    - ISC_DATA_DIRECTORY=/durable/irishost1
    - ISC_CPF_MERGE_FILE=/iris-shared/merge_first_data-node.cpf
    command: 
       --check-caps false --ISCAgent false --key /iris-shared/iris.key -a /iris-shared/configure_first_data-node.sh
    volumes:
    - ./cluster/iris-instance:/iris-shared:delegated
    - ./DDBBs:/durable:delegated

irisnode2: init: true hostname: irishost2 image: shardnode:latest container_name: irisnode2 build: context: ./cluster dockerfile: Dockerfile ports: - "9992:1972" environment: - ISC_DATA_DIRECTORY=/durable/irishost2 - ISC_CPF_MERGE_FILE=/iris-shared/merge_data-node.cpf command: --check-caps false --ISCAgent false --key /iris-shared/iris.key -a /iris-shared/configure_data-node.sh volumes: - ./cluster/iris-instance:/iris-shared - ./DDBBs:/durable depends_on: irisnode1: condition: service_healthy

# conteneur de passerelle web webgateway: image: containers.intersystems.com/intersystems/webgateway:latest-em init: true container_name: webgateway hostname: webgateway ports: - 7772:80 - 7773:443 environment: - ISC_CSP_CONF_FILE=/webgateway-shared/CSP.conf - ISC_CSP_INI_FILE=/webgateway-shared/CSP.ini volumes: - ./webgateway/CSP.conf:/webgateway-shared/CSP.conf - ./webgateway/CSP.ini:/webgateway-shared/CSP.ini

Dans ce cas, nous créons 3 services:

  • irisnode1 - Premier nœud du cluster, qui a un rôle spécial, et c'est pourquoi nous l'appelons spécifiquement node1
  • irisnode2 - Nœud de données supplémentaire du cluster, dont le rôle est data (nous pouvons en avoir autant que nous le voulons)
  • webgateway - Serveur web préconfiguré pour accéder aux instances IRIS (Apache + Webgateway)

Pour créer l'image shardnode:latest, j'ai utilisé le dockerfile suivant:

 
Dockerfile
FROM containers.intersystems.com/intersystems/irishealth:2024.3#FROM containers.intersystems.com/intersystems/iris-community:latest-em#FROM containers.intersystems.com/intersystems/irishealth-arm64:2024.3USER root
WORKDIR /opt/irisapp
RUN chown -R irisowner:irisowner /opt/irisapp
USER irisowner
WORKDIR /opt/irisapp
COPY --chown=irisowner:irisowner src src
COPY --chown=irisowner:irisowner iris.script iris.script
RUN iris start IRIS \
    && iris session IRIS < iris.script \
    && iris stop IRIS quietly

 

Les fichiers utilisés pour effectuer la fusion (merge) pour nodo1 et d'autre cluster IRIS  data nodes sont les suivants:

 
merge_first_data-node.cpf
 
merge_data-node.cpf
# Noeud de données supplémentaires
# 2 GB 8k / 204 MB gmpheap / 64 nodos max
[config]
globals=0,0,2048,0,0,0
gmheap=204800
MaxServerConn=64
MaxServers=64
# Définition d'un nœud de données et son ajout au cluster. Création d'un point de terminaison REST de test (optionnel)
[Actions]
ConfigShardedCluster:ClusterURL=IRIS://irishost1:1972/IRISCLUSTER,Role=data
# CreateApplication:Name=/rest/testapp,MatchRoles=:%ALL,NameSpace=USER,DispatchClass=Test.RESTserver,AutheEnabled=64

 

On pourrait avoir plus de nœuds de type data dans le cluster en ajoutant simplement plus de services avec la même définition que l' irisnode2 (en changeant le nom bien sûr)

D'autre part, pour que l'acheminement fonctionne correctement sur notre serveur web et que nous puissions accéder aux portails d'administration de chacune des instances, nous devons modifier le paramètre CSPConfigName dans chacune d'entre elles, et nous le faisons avec les fichiers: configure_first_data-node.sh y configure_data-node.sh; qui sont identiques dans cet exemple, mais que j'ai laissés différents car, à un moment donné, nous pourrions vouloir effectuer des actions différentes au démarrage de chaque instance d'IRIS, selon qu'il s'agit du node1 ou d'un nœud de type data du cluster.

 
configure_data-node.sh

Je pense que c'est à peu près tout.

Les nœuds pourraient être définis à l'aide de l'API disponible dans la classe %SYSTEM.Cluster  mais la possibilité d'introduire des actions conjointement avec la fonctionnalité CPF Merge simplifie grandement la tâche. Je vous recommande de consulter ce lien, en particulier la section relative à la rubrique the section [Actions].

Pour construire les images et déployer le cluster, nous pourrions construire notre image sharnode:latest et lancer le docker-compose from depuis VS Code. Alternativement, nous pourrions le faire dans notre ligne de commande, à partir du dossier dans lequel nous avons le fichier: docker-compose.yml, en exécutant ces commandes:

docker compose build
docker compose up

Cela prendra un peu de temps la première fois car l'instance marquée comme node1 doit être instanciée avant que tout autre nœud de type data du cluster ne démarre pour la première fois. Mais tout devrait fonctionner et être prêt en une minute ou moins.

Si tout s'est bien passé, vous devriez pouvoir accéder aux portail de gestion de chaque instance avec les URL ci-dessous:

Portail de gestion du nœud de cluster 1 node1http://localhost:7772/irishost1/csp/sys/UtilHome.csp
Portail de gestion du nœud de données datahttp://localhost:7772/irishost2/csp/sys/UtilHome.csp
Accès à la passerelle WebGateway: http://localhost:7772/csp/bin/Systems/Module.cxw

Et voilà! À partir de là, la limite en termes de volume de stockage de bases de données et de taille de tables est déjà fixée par votre hardware. Vous auriez un cluster de nœuds IRIS prêt à définir des tables en sharding ou des tables fédérées.

J'espère que cela vous sera utile!! À bientôt... 

0
0 30
Article Iryna Mykhailova · Jan 13, 2025 1m read

Si vous souhaitez savoir quelle est la version exacte de votre image Docker (et depuis le dernier schéma de balisage d'image, vous ne pouvez pas simplement vous fier à la balise d'image ; et en supposant que vous ne souhaitiez pas l'exécuter réellement juste pour le savoir), vous pouvez exécuter cette commande docker :

0
0 73
Article Iryna Mykhailova · Sept 2, 2024 2m read

Disons que je veux désinstaller IKO - tout ce que j'ai à faire est :

> helm uninstall intersystems

Ce qui se passe dans les coulisses, c'est que helm désinstallera ce qui a été installé lorsque vous avez exécuté :

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

Dans un certain sens, c'est symétrique à ce que nous avons fait lorsque nous avons exécuté l'installation, mais avec une image différente.

Vous remarquerez que lorsque vous installez, il sait de quelle image il doit s'agir :

0
0 47
Article Sylvain Guilbaud · Jan 30, 2024 5m read

Qu'est-ce qu'une image Docker?

Dans ce deuxième article sur les principes fondamentaux des conteneurs, nous examinons ce que sont les images de conteneurs.

Une image Docker est simplement une représentation binaire d'un conteneur.

Un conteneur en cours d'exécution ou simplement un conteneur est l'état d'exécution de l'image du conteneur associée.

Pour plus d'information, n'hésitez pas à lire l'article qui explique ce qu'est un conteneur.

0
0 257
Article Pierre LaFay · Jan 7, 2024 3m read

Le sous-système Windows pour Linux (WSL) est une fonctionnalité de Windows qui vous permet d'exécuter un environnement Linux sur votre ordinateur Windows, sans avoir besoin d'une machine virtuelle distincte ni d'un double démarrage.

WSL est conçu pour offrir une expérience transparente et productive aux développeurs qui souhaitent utiliser à la fois Windows et Linux**.

0
0 104
Article Irène Mykhailova · Juin 28, 2023 7m read

Le code source de l'article est disponible à l'adresse suivante : https://github.com/antonum/ha-iris-k8s 

Dans l'article précédent, nous avons expliqué comment configurer IRIS sur un cluster k8s avec une haute disponibilité, basée sur le stockage distribué, au lieu de la mise en miroir traditionnelle. À titre d'exemple, cet article utilisait le cluster Azure AKS. Dans cet article, nous poursuivons l'exploration des configurations de haute disponibilité sur k8s. Cette fois, basée sur Amazon EKS (service Kubernetes géré par AWS) et incluant une option pour effectuer la sauvegarde et la restauration de la base de données, basée sur Kubernetes Snapshot.

Installation

Passons tout de suite au travail. Tout d'abord, vous devez disposer d'un compte AWS et des outils AWS CLI,kubectl et eksctl. Pour créer le nouveau cluster, exécutez la commande suivante :

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

Cette commande prend ~15 minutes, elle déploie le cluster EKS et en fait un cluster par défaut pour votre outil kubectl. Vous pouvez vérifier le déploiement en exécutant :

kubectl obtenir les noeuds
NOM                                              ÉTAT    RÔLES            AGE   VERSION
ip-192-168-19-7.ca-central-1.compute.internal    Prêt    &lt;néant>   18d   v1.18.9-eks-d1db3c
ip-192-168-37-96.ca-central-1.compute.internal   Prêt    &lt;néant>   18d   v1.18.9-eks-d1db3c
ip-192-168-76-18.ca-central-1.compute.internal   Prêt    &lt;néant>   18d   v1.18.9-eks-d1db3c

L'étape suivante consiste à installer le moteur de stockage distribué Longhorn.

kubectl créer l'espace de nom 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

Et enfin, l'IRIS lui-même :

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

À ce stade, vous aurez un cluster EKS entièrement fonctionnel avec le stockage distribué Longhorn et le déploiement IRIS installé. Vous pouvez revenir à l'article précédent et tenter de causer toutes sortes de dommages au cluster et au déploiement d'IRIS, juste pour voir comment le système se répare de lui-même. Consultez la section Simuler la défaillance section.

Bonus n° 1 IRIS en ARM

IRIS EKS et Longhorn sont tous deux compatibles avec l'architecture ARM. Nous pouvons donc déployer la même configuration en utilisant les instances AWS Graviton 2, basées sur l'architecture ARM.

Il suffit de changer le type d'instance pour les nœuds EKS en famille 'm6g' et l'image IRIS en ARM.

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

tldr.yaml

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

Ou utilisez simplement :

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

Et voilà ! Vous avez obtenu votre cluster IRIS Kubernetes, fonctionnant sur la plateforme ARM.

Bonus n°2 - Sauvegarde et restauration

Une partie souvent négligée de l'architecture niveau production est la capacité de créer des sauvegardes de votre base de données et de les restaurer rapidement et/ou de les cloner en cas de besoin.

Dans Kubernetes, la façon la plus courante de le faire est d'utiliser des instantanés de volumes persistants (Persistent Volume Snapshots).

Tout d'abord, vous devez installer tous les composants k8s requis :

#Installer CSI Snapshotter et 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

Ensuite, configurez les informations d'identification du seau S3 pour Longhorn (voir instructions détaillées):

#Le godet s3 cible de la sauvegarde Longhorn et les informations d'identification à utiliser par Longhorn pour accéder à ce godet.
#Voir https://longhorn.io/docs/1.1.0/snapshots-and-backups/backup-and-restore/set-backup-target/ pour les instructions d'installation manuelle
longhorn_s3_bucket=longhorn-backup-123xx #le nom du godet doit être unique au niveau global, à moins que vous ne souhaitiez réutiliser des sauvegardes et des informations d'identification existantes.
longhorn_s3_region=us-east-1
longhorn_aws_key=AKIAVHCUNTEXAMPLE
longhorn_aws_secret=g2q2+5DVXk5p3AHIB5m/Tk6U6dXrEXAMPLE

La commande suivante reprend les variables d'environnement de l'étape précédente et les utilise pour configurer la sauvegarde Longhorn.

#configurer la cible de sauvegarde Longhorn et les informations d'identification

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/" # la cible de sauvegarde ici
---
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" # nom secret de la sauvegarde ici
EOF

Cela peut sembler compliqué, mais cela indique en fait à Longhorn d'utiliser un godet S3 spécifique avec les informations d'identification spécifiées pour stocker le contenu des sauvegardes.

Voilà, c'est fait ! Si vous allez maintenant dans l'interface utilisateur de Longhorn, vous pourrez créer des sauvegardes, les restaurer, etc.

Voici un petit rappel sur la façon de se connecter à l'interface utilisateur Longhorn :

kubectl get pods -n longhorn-system
# noter le nom complet du pod pour le pod 'longhorn-ui-...'
kubectl port-forward longhorn-ui-df95bdf85-469sz 9000:8000 -n longhorn-system

Cela permettrait de transférer le trafic vers Longhorn UI sur votre site http://localhost:9000.

Sauvegarde/restauration programmatique

Effectuer une sauvegarde et une restauration via l'interface utilisateur Longhorn peut être une première étape suffisante - mais nous ferons un pas en avant et effectuerons la sauvegarde et la restauration de manière programmatique, en utilisant les API Snapshot de k8s.

Tout d'abord, l'instantané lui-même. iris-volume-snapshot.yaml

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: iris-longhorn-snapshot
spec:
  volumeSnapshotClassName: longhorn
  source:
    persistentVolumeClaimName: iris-pvc
Cet instantané de volume fait référence au volume source 'iris-pvc' que nous utilisons pour notre déploiement IRIS. Il suffit donc de l'appliquer pour lancer immédiatement le processus de sauvegarde.

C'est une bonne idée d'exécuter la fonction de Gel/Dégel du démon d'écriture d'IRIS avant/après l'instantané.
#Gel du démon d'écriture
echo "Gel du démon d'écriture d'IRIS"
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 EST CONGELÉ, exécution de la sauvegarde"
 kubectl apply -f backup/iris-volume-snapshot.yaml -n $namespace
elif [[ $status -eq 3 ]]; then
 echo "ÉCHEC DU GEL DE L'IRIS WD"
fi
#Dégel du démon d'écriture
kubectl exec -it -n $namespace $pod_name -- iris session iris -U%SYS "##Class(Backup.General).ExternalThaw()"

Le processus de restauration est assez simple. Il s'agit essentiellement de créer un nouveau PVC et de spécifier l'instantané comme source.

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

Il suffit ensuite de créer un nouveau déploiement, basé sur ce PVC. Regardez ce script de test dans un référentiel github qui se déroulerait de manière séquentielle :

  • Créer un nouveau déploiement d'IRIS
  • Ajouter des données à IRIS
  • Geler le démon d'écriture, prendre un instantané, dégeler le démon d'écriture
  • Créer un clone du déploiement d'IRIS, basé sur l'instantané.
  • Vérifier que toutes les données sont toujours présentes

À ce stade, vous aurez deux déploiements IRIS identiques, l'un étant un clone par sauvegarde de l'autre.

Profitez-vous-en bien !

0
0 133
Article Evgeny Shvarov · Fév 10, 2023 6m read

Salut les développeurs !

Voici encore un court message qui a pour but de simplifier la vie des développeurs. Nous allons maintenant vous expliquer comment faire en sorte que GitHub exécute des tests unitaires à chaque poussée vers le référentiel en ajoutant un seul fichier au référentiel. Gratuitement. Dans le nuage de Github. Ça a l'air génial, n'est-ce pas ?

C'est possible et très facile à faire. Le mérite revient à @Dmitry Maslennikov (et son référentiel), gestionnaire de paquets "ZPM Package Manager", et aux GitHub Actions.  Voyons comment tout cela fonctionne !

Quelque chose pour rien de Robert Sheckley - YouTube

Considérons d'abord un référentiel avec des tests, par exemple le modèle IRIS de base

Supposons également que vous chargez votre code de développement dans le docker IRIS à l'aide de ZPM. Si ce n'est pas le cas, regardez la video sur la façon de le faire. 

Dans ce référentiel particulier, il s'agit de la ligne suivante et avec la présence de module.xml:

zpm "load /home/irisowner/irisbuild/ -v":1:1

Ensuite, ajoutons un scénario de GitHub Actions qui permettra de construire l'image et d'exécuter les tests :

name: unittest

on:
  push:
    branches:
      - maître
      - principale
  pull_request:
    branches:
      - maître
      - principale
  version:
    types:
      - libéré

tâches:
  build:
    runs-on: ubuntu-latest
    étapes:
      - utilisations: actions/checkout@v2
      - nom: Build and Test
        utilisations: docker/build-push-action@v2
        avec:
          contexte: .
          push: faux
          charge: vrai
          balises: ${{ github.repository }}:${{ github.sha }}
          build-args: TESTS=1

Ce scénario construit une image docker en utilisant Dockerfile du référentiel à chaque push ou pull-request vers la branche master ou main.

Voici une ligne supplémentaire qui transfère la variable TESTS=1 au Dockerfile :

build-args: TESTS=1

Cet argument est évaué dans le Dockerfile et si TESTS=1, il exécute les tests du paquet zpm du référentiel :

    ([ $TESTS -eq 0 ] || iris session iris -U $NAMESPACE "##class(%ZPM.PackageManager).Shell("test $MODULE -v -only",1,1)") && \

Cette ligne vérifie le paramètre $TESTS et s'il n'est pas égal à 0, elle ouvre la session iris dans $NAMESPACE (IRISAPP dans ce cas) et exécute la commande ZPM :

test $MODULE -v -only

L'indicateur -only exécute uniquement le test sans charger le module (car il a été chargé auparavant dans le scénario de construction de docker).

Le nom du module est défini via $MODULE="dc-sample-template" dans ce cas :

ARG MODULE="dc-sample-template"

La commande va exécuter tous les unittests que nous avons mentionnés dans le module ZPM. Dans ce cas, nous le présentons avec cette ligne:

&lt;UnitTest Name="/tests" Package="dc.sample.unittests" Phase="test"/>

ce qui signifie que les tests unitaires sont situés dans le dossier /tests du référentiel et que la ressource est dc.sample.unittests paquet de classe qui a deux classes.

Ce scénario va construire l'image de votre dépôt sur le nuage GitHub et exécuter des tests pour chaque push ou pull request vers la branche maître !

Voyons comment cela fonctionne !

La méthode Test42 prévoit que la méthode dc.sample.ObjectScript).Test() renvoie 42.

Changeons la ligne en 43 et envoyons pull-request. Nous pouvons voir (dans la section Actions ) que la pull-request a initié l'action Github. En effet, la construction a échoué :

Et les détails de la phase indiquent que Test42() a échoué sur AssertEquals 42 =43 :

Github envoie également des notifications par courriel en cas d'échec des constructions CI.

Remarque : pour exécuter les tests localement, il suffit d'appeler :

USER>zpm test "module-name"

Et si nous remettons la valeur de la variable à 42, les tests seront OK !

Et s'il s'agit de Pull-Request, vous pouvez voir le résultat de l'IC dans la section spéciale de contrôle Checks:

Et voilà !

Pour résumer, faire fonctionner GitHub (gratuitement !) pour les constructions de dockers et les unittests des projets InterSystems IRIS sur les pushes ou les pull-requests nécessite un scénario CI Github Actions scenario, qui sera le même pour chaque projet, et trois lignes dans le Dockerfile :

Le nom ZPM $MODULE - ceci doit être mis à jour avec chaque projet,

Le paramètre $TEST,

et la ligne RUN TEST.

Et utilisez le gestionnaire ZPM Package Manager!

Les commentaires et les réactions sont les bienvenus, et bon codage !

L'image du titre est liée à l'histoire de l'un de mes auteurs de SF préférés, Robert Sheckley, ["Quelque chose pour rien"] (https://en.wikipedia.org/wiki/Something_for_Nothing_(book)) - la voici en [audio aussi] (https://www.youtube.com/watch?v=CL0GQTtx-5A), profitez-en !

0
0 73
Article Lorenzo Scalese · Juil 15, 2022 12m read

Salut la communauté,

Ceci est le troisième article de la série traitant sur l’initialisation d’instances IRIS avec Docker. Cette fois, on s’intéresse à Enterprise Cache Protocol (ECP).

De manière très simplifiée, ECP permet de configurer certaines instances IRIS avec le rôle de serveur d’applications et d’autres avec le rôle de serveur de données. Vous trouverez toutes les informations techniques détaillées dans la documentation officielle.

Le but de cet article est de décrire comment nous pouvons scripter l'initialisation d’un serveur de données, d’un ou plusieurs serveurs d’applications et d’établir une connexion cryptée entre ces nœuds avec Docker. Pour cela, nous utilisons certains outils déjà rencontrés dans les articles précédents traitant de la mise en miroir la webgateway tel que OpenSSL, envsubst et Config-API.

Prérequis

ECP n’est pas disponible dans la version IRIS Community. Il est donc nécessaire d’avoir un accès au World Response Center afin de pouvoir télécharger une licence “container” ainsi que pour se connecter au registry containers.intersystems.com.

Préparation du système

Le système doit partager certains fichiers locaux avec les containers. Il est donc nécessaire de créer certains utilisateurs et groupes afin d’éviter l’erreur “access denied”.

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

Si vous n’avez pas encore votre licence “iris.key”, téléchargez-là sur le WRC ensuite mettez-là dans votre répertoire home.

## Récupérer le repository d’exemple

Tous les fichiers dont vous avez besoin sont disponible sur un [repository public](https://github.com/lscalese/ecp-with-docker), commencez par le cloner:  

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

Certificats SSL

Afin de crypter les communications entre les serveurs d’applications et le serveur de données, nous avons besoin de certificats SSL. Le script “gen-certificates.sh” prêt à l’emploi est disponible, toutefois, n’hésitez pas à le modifier pour que les paramètres des certificats soient cohérents avec votre localisation, compagnie, etc…

Exécutez:

sh ./gen-certificates.sh

Les certificats générés sont dans le répertoire “./certificates”.

FichierContainerDescription
./certificates/CA_Server.cerServeur d’applications et serveur de donnéesAuthority server certificate
./certificates/app_server.cerServeur d’applicationsCertificat pour l’instance IRIS
./certificates/app_server.keyServeur d’applicationsClé privée associée
./certificates/data_server.cerServeur de donnéesCertificat pour l’instance IRIS
./certificates/data_server.keyServeur de donnéesClé privée associée

Construire l’image

Avant toute chose, loggez-vous au docker registry d’Intersystems. Lors de la construction, l’image de base sera téléchargée sur le registry:

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

Si vous ne connaissez pas votre token, vous pouvez le récupérer sur cette page https://containers.intersystems.com en vous connectant avec votre compte WRC.

Lors de cette construction, nous allons ajouter à l’image de base de IRIS quelques logiciels utilitaires:

  • gettext-base : qui permettra de substituer les variables d’environnements dans nos fichiers de configuration avec la commande “envsubst”.
  • iputils-arping : qui est requis dans le cas ou l’on souhaite mettre le serveur de données en miroir.
  • ZPM: gestionnaire de paquet 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

Il n’y a rien de particulier dans ce Dockerfile, excepté la dernière ligne. Celle-ci configure l’instance IRIS serveur de données pour accepter jusqu’à 3 serveurs d’applications. Attention, cette configuration nécessite un redémarrage de IRIS. Nous affectons la valeur de ce paramètre pendant la construction afin d’éviter de devoir scripter un redémarrage plus tard.

Démarrez la construction:

docker-compose build –no-cache

Les fichiers de configurations

Pour la configuration des instances IRIS (serveurs d’applications et serveur de données) nous utilisons des fichiers format JSON config-api. Vous remarquerez que ceux-ci contiennent des variables d’environnements “${variable_name}”. Leurs valeurs sont définies dans les sections “environment” du fichier docker-compose.yml que nous verrons plus tard dans ce document. Ces variables seront substituées juste avant le chargement des fichiers à l’aide de l’utilitaire “envsubst”.

Serveur de données

Pour le serveur de données, nous allons:

  • Activer le service ECP et définir la liste des clients autorisés (serveurs d’applications).
  • Créer la configuration “SSL %ECPServer” nécessaire pour le cryptage des communications.
  • Créer une base de données “myappdata”. Celle-ci sera utilisée comme base de données distante depuis les applications serveurs.

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/"
       }
   }
}

Ce fichier de configuration est chargé au démarrage du container serveur de données par le script “init_datasrv.sh”. Tous les serveurs d’applications qui se connectent au serveur de données doivent être approuvés, ce script validera automatiquement toutes les connexions dans un délai de 100 secondes afin de limiter les actions manuelles dans le portail d’administration. Bien sûr, cela peut être amélioré pour renforcer la sécurité.

Serveur d’applications

Pour les serveurs d’applications, nous allons:

  • Activer le service ECP.
  • Créer la configuration SSL “%ECPClient” nécessaire pour le cryptage des communications.
  • Configurer les informations de connexion au serveur de données.
  • Créer la configuration de la base de données distante “myapp”
  • Créer un mapping de globale “demo.*” dans le namespace “USER” a destination la base de données “myappdata”. Ceci nous permettra de tester le fonctionnement de ECP plus tard.

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"
       }]
   }
}

Le fichier de configuration est chargé au démarrage d’un container serveur d’applications par le script “init_appsrv.sh”.

Démarrer les containers

Nous pouvons maintenant démarrer les containers:

  • 2 serveurs d’applications.
  • 1 serveur de données.

Pour cela, exécutez:

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

Voir le fichier docker-compose pour les détails:

Docker-compose

# Les variables sont définies dans  le fichier .env file
# Pour afficher le fichier de configuration résolu, exécutez :
# 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:
     # Liste des serveurs d’applications autorisés. 
     - 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
     # Chemin vers le certificat du serveur d’autorité.
     - CA_ROOT=/certificates/CA_Server.cer
     # Chemin vers le certificat du serveur de données
     - CA_SERVER=/certificates/data_server.cer
     # Chemin vers la clé privée du certificat du serveur de données
     - CA_PRIVATE_KEY=/certificates/data_server.key
     # Chemin vers le fichier de Configuration Config-API utilisé pour configurer cette instance
     - IRIS_CONFIGAPI_FILE=/home/irisowner/demo/data-server.json
   ports:
     - "81:52773"
   volumes:
     # Post start script pour initialiser l’instance du serveur de données.
     - ./init_datasrv.sh:/home/irisowner/demo/init_datasrv.sh
     # Montage des certificats
     - ./certificates/app_server.cer:/certificates/data_server.cer
     - ./certificates/app_server.key:/certificates/data_server.key
     - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
     # Montage du fichier de configuration Config-API
     - ./config-files/data-server.json:/home/irisowner/demo/data-server.json
     # Montage du fichier de licence IRIS
     - ./iris.key:/dur/iris.key
   command: -a /home/irisowner/demo/init_appsrv.sh
 
 
 ecp-demo-app-server:
   image: ecp-demo
   networks:
     app_net:
   environment:
     # Nom d’hôte ou adresse ip du serveur de données.
     - DATASERVER_IP=data-server
     - DATASERVER_NAME=data-server
     - DATASERVER_PORT=1972
     # Chemin vers le certificat du serveur d’autorité.
     - CA_ROOT=/certificates/CA_Server.cer
     # Chemin vers le certificat du serveur d’applications.
     - CA_CLIENT=/certificates/app_server.cer
     # Chemin vers la clé privée du certificat du serveur d’applications.
     - CA_PRIVATE_KEY=/certificates/app_server.key
     - IRIS_CONFIGAPI_FILE=/home/irisowner/demo/app-server.json
   ports:
     - 52773
   volumes:
     # Post start script pour initialiser l’instance du serveur de données.
     - ./init_appsrv.sh:/home/irisowner/demo/init_appsrv.sh
     # Montage des certificats.
     - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
     - ./certificates/app_server.cer:/certificates/app_server.cer
     - ./certificates/app_server.key:/certificates/app_server.key
     # Montage du fichier de configuration Config-API.
     - ./config-files/app-server.json:/home/irisowner/demo/app-server.json
     # Montage du fichier de licence IRIS.
     - ./iris.key:/dur/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}"

Testons-le!

Accès au portail d’administration du serveur de données

Les containers sont démarrés, vérifions l’état à partir du serveur de données. Le port 52773 est mappé sur le port local 81, vous pouvez donc y accéder avec cette adresse http://localhost:81/csp/sys/utilhome.csp.

Connectez-vous avec le login\password par défaut ensuite allez dans Système -> Configuration -> Params ECP. Cliquez sur “Serveurs d’application ECP”. Si tout fonctionne bien, vous devriez voir 2 serveurs d’applications avec le statut “Normal”. La structure du nom du client est "data server name":"application server hostname":"IRIS instance name". Dans notre cas, nous n’avons pas paramétré les hostnames des serveurs d’applications, nous avons donc des hostnames auto-générés.

application server list

Accès au portail d’administration des serveurs d’applications

Pour vous connecter au portail d’administration des serveurs d’applications, vous devez d’abord récupérer le numéro de port. Etant donné que nous avons utilisé l’option “--scale”, nous n’avons pas pu fixer les ports dans le fichier docker-compose. Il faut donc les retrouver à l’aide de la commande “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

Dans cet exemple, les ports sont:

Test de lecture\écriture sur la base de données distante

Effectuons maintenant quelques tests de lecture\écriture en terminal.

Ouvrons un terminal IRIS sur le premier serveur d’applications:

docker exec -it ecp-with-docker_ecp-demo-app-server_1 iris session iris
Set ^demo.ecp=$zdt($h,3,1) _ “ écriture à partir du premier serveur d’applications”

Ouvrons maintenant un terminal sur le second serveur d’applications:

docker exec -it ecp-with-docker_ecp-demo-app-server_2 iris session iris
Set ^demo.ecp(2)=$zdt($h,3,1) _ " écriture à partir du second serveur d’applications."
zw ^demo.ecp

Vous devriez visualiser les écritures effectuées depuis les deux serveurs:

^demo.ecp(1)="2022-07-05 23:05:10 écriture à partir du premier serveur d’applications."
^demo.ecp(2)="2022-07-05 23:07:44 écriture à partir du second serveur d’applications."

Pour terminer, ouvrons un terminal IRIS sur le serveur de données et effectuons une lecture de la globale demo.ecp :

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

^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(1)="2022-07-05 23:05:10 écriture à partir du premier serveur d’applications."
^["^^/usr/irissys/mgr/myappdata/"]demo.ecp(2)="2022-07-05 23:07:44 écriture à partir du second serveur d’applications."

Voilà, c’est tout pour aujourd’hui, j’espère que cet article vous a plu. N’hésitez pas à laisser vos commentaires.

0
0 91
Article Lorenzo Scalese · Juil 13, 2022 9m read

Salut, communauté.

Dans cet article, nous allons configurer de manière programmatique la WebGateway Apache avec Docker en incluant :

  • Protocole HTTPS.
  • TLS\SSL pour sécuriser la communication entre la WebGateway et l'instance IRIS.

image

Nous utiliserons deux images : une pour la WebGateway et la seconde pour l'instance IRIS.

Tous les fichiers nécessaires sont disponibles dans ce repository GitHub.

Commençons par un clone git :

clone git https://github.com/lscalese/docker-webgateway-sample.git
cd docker-webgateway-sample

Préparation de votre système

Pour éviter les problèmes de permissions, votre système a besoin d'un utilisateur et d'un groupe :

  • www-data
  • irisowner

Il est nécessaire de partager les fichiers de certificats avec les conteneurs. S'ils n'existent pas sur votre système, exécutez simplement :

sudo useradd --uid 51773 --user-group irisowner
sudo groupmod --gid 51773 irisowner
sudo useradd –user-group www-data

Génération des certificats

Dans cet exemple, nous allons utiliser trois certificats :

  1. Utilisation du serveur web HTTPS.
  2. Cryptage TLS\SSL sur le client de la WebGateway.
  3. Cryptage TLS\SSL sur l'instance IRIS.

Un script prêt à l'emploi est disponible pour les générer.

Cependant, vous devez personnaliser l'objet du certificat ; il suffit pour cela de modifier le fichier gen-certificates.sh.

Voici la structure de l'argument subj d'OpenSSL :

  1. C : Code pays
  2. ST : État
  3. L : Localisation
  4. O : Organisation
  5. OU : Unité d'organisation
  6. CN : Nom commun (essentiellement le nom de domaine ou le nom d'hôte)

N'hésitez pas à modifier ces valeurs afin que ce soit cohérent avec votre localisation, organisation, etc...

# sudo est nécessaire pour chown, chgrp, chmod ...
sudo ./gen-certificates.sh

Si tout est ok, vous devriez voir deux nouveaux répertoires ./certificates/ et ~/webgateway-apache-certificates/ avec des certificats :

FichierConteneurDescription
./certificates/CA_Server.cerwebgateway,irisCertificat du serveur d'autorité
./certificates/iris_server.ceririsCertificat pour l'instance IRIS (utilisé pour le cryptage de la communication entre le miroir et la WebGateway)
./certificates/iris_server.keyirisClé privée associée
~/webgateway-apache-certificates/apache_webgateway.cerwebgatewayCertificat pour le serveur web apache
~/webgateway-apache-certificates/apache_webgateway.keywebgatewayClé privée associée
./certificates/webgateway_client.cerwebgatewayCertificat pour crypter la communication entre webgateway et IRIS
./certificates/webgateway_client.keywebgatewayClé privée associée

Gardez à l'esprit que ce sont des certificats auto-signés, les navigateurs web afficheront des alertes de sécurité. Évidemment, si vous avez un certificat délivré par une autorité certifiée, vous pouvez l'utiliser à la place d'un certificat auto-signé (en particulier pour le certificat du serveur Apache).

Fichiers de configuration de la WebGateway

Jetons un coup d'œil aux fichiers de configuration.

CSP.INI

Vous pouvez voir un fichier CSP.INI dans le répertoire webgateway-config-files.
Il sera inséré dans l'image, mais son contenu peut être modifié lors de l'exécution. Considérez ce fichier comme un modèle.

Dans cet exemple, les paramètres suivants seront remplacés au démarrage du conteneur :

  • Ip_Address
  • TCP_Port
  • System_Manager

Référez-vous à startUpScript.sh pour plus de détails. De façon générale, le remplacement est effectué avec la ligne d'instruction sed.

Ce fichier contient également la configuration SSL\TLS pour sécuriser la communication avec l'instance IRIS :

SSLCC_Certificate_File=/opt/webgateway/bin/webgateway_client.cer
SSLCC_Certificate_Key_File=/opt/webgateway/bin/webgateway_client.key
SSLCC_CA_Certificate_File=/opt/webgateway/bin/CA_Server.cer

Ces lignes sont importantes. Nous devons nous assurer que les fichiers de certificats seront disponibles pour le conteneur.
Nous ferons cela plus tard dans le fichier docker-compose avec un volume.

000-default.conf

Il s'agit d'un fichier de configuration d'Apache. Il permet l'utilisation du protocole HTTPS et redirige les appels HTTP vers HTTPS.
Les fichiers de certificat et de clé privée sont configurés dans ce fichier :

SSLCertificateFile /etc/apache2/certificate/apache_webgateway.cer
SSLCertificateKeyFile /etc/apache2/certificate/apache_webgateway.key

L'instance IRIS

Pour notre instance IRIS, nous ne configurons que le minimum requis pour permettre la communication SSL\TLS avec la WebGateway ; cela implique les éléments suivants :

  1. Configuration SSL de %SuperServer.
  2. Activation du paramètre de sécurité SSLSuperServer.
  3. Restriction de la liste des IPs qui peuvent utiliser le service Web Gateway.

Pour faciliter la configuration, on utilise config-api avec un simple fichier de configuration JSON.

{
   "Security.SSLConfigs": {
       "%SuperServer": {
           "CAFile": "/usr/irissys/mgr/CA_Server.cer",
           "CertificateFile": "/usr/irissys/mgr/iris_server.cer",
           "Name": "%SuperServer",
           "PrivateKeyFile": "/usr/irissys/mgr/iris_server.key",
           "Type": "1",
           "VerifyPeer": 3
       }
   },
   "Security.System": {
       "SSLSuperServer":1
   },
   "Security.Services": {
       "%Service_WebGateway": {
           "ClientSystems": "172.16.238.50;127.0.0.1;172.16.238.20"
       }
   }
}

Aucune action n'est nécessaire. La configuration sera automatiquement chargée au démarrage du conteneur.

Image tls-ssl-webgateway

dockerfile

ARG IMAGEWEBGTW=containers.intersystems.com/intersystems/webgateway:2021.1.0.215.0
FROM ${IMAGEWEBGTW}
ADD webgateway-config-files /webgateway-config-files
ADD buildWebGateway.sh /
ADD startUpScript.sh /
RUN chmod +x buildWebGateway.sh startUpScript.sh && /buildWebGateway.sh
ENTRYPOINT ["/startUpScript.sh"]

Par défaut, le point d'entrée est /startWebGateway, mais il faut effectuer quelques opérations avant de démarrer le serveur web. Rappelez-vous que notre fichier CSP.ini est un template, et que nous devons changer certains paramètres (IP, port, gestionnaire de système) au démarrage. startUpScript.sh va effectuer ces changements et ensuite exécuter le script de point d'entrée initial /startWebGateway.

Conteneurs de départ

docker-compose file

Avant de démarrer les conteneurs, le fichier docker-compose.yml doit être modifié ::

  • **SYSTEM_MANAGER** doit être défini avec l'IP autorisée à avoir un accès à Web Gateway Managementhttps://localhost/csp/bin/Systems/Module.cxw. En gros, c'est votre adresse IP (Cela peut être une liste séparée par des virgules).

  • **IRIS_WEBAPPS** doit être défini avec la liste de vos applications CSP. La liste est séparée par des espaces, par exemple : IRIS_WEBAPPS=/csp/sys /swagger-ui. Par défaut, seul /csp/sys est exposé.

  • Les ports 80 et 443 sont mappés. Adaptez-les à d'autres ports s'ils sont déjà utilisés sur votre système.

version: '3.6'
services:

 webgateway:
   image: tls-ssl-webgateway
   container_name: tls-ssl-webgateway
   networks:
     app_net:
       ipv4_address: 172.16.238.50
   ports:
     # modification du port local déjà utilisé sur votre système.
     - "80:80"
     - "443:443"
   environnement:
     - IRIS_HOST=172.16.238.20
     - IRIS_PORT=1972
     # Remplacement par la liste des adresses IP autorisées à ouvrir le gestionnaire du système CSP
     # https://localhost/csp/bin/Systems/Module.cxw
     # consultez le fichier .env pour définir les variables d'environnement.
     - "SYSTEM_MANAGER=${LOCAL_IP}"
     # la liste des applications web
     # /csp permet à la webgateway de rediriger toutes les requêtes commençant par /csp vers l'instance iris
     # Vous pouvez spécifier une liste séparée par un espace : "IRIS_WEBAPPS=/csp /api /isc /swagger-ui"
     - "IRIS_WEBAPPS=/csp/sys"
   volumes:
     # Montage des fichiers de certificats.
     - ./volume-apache/webgateway_client.cer:/opt/webgateway/bin/webgateway_client.cer
     - ./volume-apache/webgateway_client.key:/opt/webgateway/bin/webgateway_client.key
     - ./volume-apache/CA_Server.cer:/opt/webgateway/bin/CA_Server.cer
     - ./volume-apache/apache_webgateway.cer:/etc/apache2/certificate/apache_webgateway.cer
     - ./volume-apache/apache_webgateway.key:/etc/apache2/certificate/apache_webgateway.key
   hostname: webgateway
   command: ["--ssl"]

 iris:
   image: intersystemsdc/iris-community:latest
   container_name: tls-ssl-iris
   networks:
     app_net:
       ipv4_address: 172.16.238.20
   volumes:
     - ./iris-config-files:/opt/config-files
     # Mount certificates files.
     - ./volume-iris/CA_Server.cer:/usr/irissys/mgr/CA_Server.cer
     - ./volume-iris/iris_server.cer:/usr/irissys/mgr/iris_server.cer
     - ./volume-iris/iris_server.key:/usr/irissys/mgr/iris_server.key
   hostname: iris
   # Chargement du fichier de configuration IRIS ./iris-config-files/iris-config.json
   commande: ["-a","sh /opt/config-files/configureIris.sh"]

networks:
 app_net:
   ipam:
     driver: default
     config:
       - subnet: "172.16.238.0/24"

Construction et démarrage :


docker-compose up -d --build

Les conteneurs tls-ssl-iris et tls-ssl-webgateway doivent être démarrés.

Test de l'accès au Web

Page par défaut d'Apache

Ouvrez la page http://localhost. Vous serez automatiquement redirigé vers https://localhost.
Les navigateurs affichent des alertes de sécurité. C'est le comportement standard avec un certificat auto-signé, dans notre cas vous pouvez accepter le risque et continuer.

image

Page de gestion de la WebGateway

Ouvrez https://localhost/csp/bin/Systems/Module.cxw et testez la connexion du serveur. image

Portail de gestion

Ouvrez https://localhost/csp/sys/utilhome.csp

image

Parfait! Notre sample WebGateway fonctionne!

Miroir IRIS avec la WebGateway

Dans l'article précédent, nous avons construit un environnement miroir, mais la WebGateway était une pièce manquante. Maintenant, nous pouvons y remédier.
Un nouveau dépôt iris-miroring-with-webgateway est disponible incluant la WebGateway et quelques autres améliorations :

  1. Les certificats ne sont plus générés à la volée mais dans un processus séparé.
  2. Les adresses IP sont remplacées par des variables d'environnement dans les fichiers de configuration docker-compose et JSON. Les variables sont définies dans le fichier '.env'.
  3. Le repository peut être utilisé comme modèle.

Consultez le fichier du dépôt README.md pour exécuter un environnement comme celui-ci :

image

0
0 185
Article Lorenzo Scalese · Juil 11, 2022 13m read

Historique

VersionDateChangements
V12022-02-08Version initiale
V1.12022-04-06Génération de certificats avec le fichier sh au lieu de pki-script
Utilisation de variables d'environnement dans des fichiers de configuration

Salut, communauté,

Avez-vous déjà mis en place un environnement miroir ? Dispose-t-il d'un réseau privé, d'une adresse IP virtuelle et d'une configuration SSL ? Après avoir fait cela plusieurs fois, je me suis rendu compte que c'est long, et qu'il y a beaucoup d'actions manuelles nécessaires pour générer des certificats et configurer chaque instance IRIS. C'est une vraie casse-tête pour les personnes qui ont souvent à le faire.

Par exemple, une équipe d'assurance qualité peut avoir besoin de créer un nouvel environnement pour chaque nouvelle version d'application à tester. L'équipe de support peut avoir besoin de créer un environnement pour reproduire un problème complex.

Il faut absolument des outils pour les créer rapidement.

Dans cet article, nous allons créer un exemple pour configurer un miroir avec :

  • Arbitre.
  • Membre primaire.
  • Membre de secours en cas de panne.
  • Membre asynchrone de rapport en lecture-écriture.
  • Configuration SSL pour les transferts de journaux entre les nœuds.
  • Réseau privé pour le miroir.
  • Adresse IP virtuelle.
  • Une base de données en miroir.

schéma du réseau

À première vue, cela semble un peu complexe et nécessite beaucoup de code, mais ne vous inquiétez pas. Il existe des bibliothèques hébergées sur OpenExchange pour effectuer facilement la plupart des opérations.

L'objectif de cet article est de fournir un exemple de manière à l'adapter à vos besoins, mais il ne s'agit pas d'un guide des meilleures pratiques en matière de sécurité. Donc, créons notre sample.

Outils et bibliothèques

  • config-api: Cette bibliothèque sera utilisée pour configurer IRIS. Elle supporte la configuration du mirroring depuis la version 1.1.0. Nous ne donnerons pas une description détaillée de l'utilisation de cette bibliothèque. Un ensemble d'articles existe déjà. ici. En bref, config-api sera utilisé pour créer des fichiers de configuration (format JSON) et les charger facilement.

  • ZPM.

  • Docker.

  • OpenSSL.

Page Github

Vous pouvez trouver tous les fichiers de ressources nécessaires sur iris-mirroring-samples repository.

Préparation de votre système

Clonez le référentiel existant :

clone git https://github.com/lscalese/iris-mirroring-samples
cd iris-mirroring-samples

Si vous préférez créer un échantillon à partir de zéro, au lieu de cloner le référentiel, créez simplement un nouveau répertoire avec des sous-répertoires : backup, et config-files. Télécharger irissession.sh :

mkdir -p iris-mirroring-samples/backup iris-mirroring-samples/config-files
cd  iris-mirroring-samples
wget -O session.sh https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/session.sh

Pour éviter le problème "permission denied" plus tard, nous devons créer le groupe irisowner, l'utilisateur irisowner, et changer le groupe du répertoire backup en irisowner

sudo useradd --uid 51773 --user-group irisowner
sudo groupmod --gid 51773 irisowner
sudo chgrp irisowner ./backup

Ce répertoire sera utilisé comme volume pour partager une sauvegarde de la base de données après avoir configuré le premier membre miroir avec les autres nœuds.

Obtention d'une licence IRIS

La mise en miroir n'est pas disponible avec l'édition communautaire d'IRIS. Si vous ne disposez pas encore d'une licence conteneur IRIS valide, connectez-vous au Centre de réponse mondial Worldwide Response Center (WRC) avec vos informations d'identification. Cliquez sur "Actions" --> "Online distribtion" ("Actions" --> "Distribution en ligne"), puis sur le bouton "Evaluations" et sélectionnez "Evaluation License" ("Licence d'évaluation") ; remplissez le formulaire. Copiez votre fichier de licence iris.key dans ce répertoire.

Connexion au Registre des conteneurs d'Intersystems

Pour des raisons pratiques, nous utilisons le Registre des conteneurs d'Intersystems (Intersystems Containers Registry) (ICR) pour extraire les images docker. Si vous ne connaissez pas votre login/mot de passe docker, connectez-vous simplement à SSO.UI.User.ApplicationTokens.cls avec vos informations d'identification WRC, et vous pourrez récupérer votre Token ICR.

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

Création de la base de données myappdata et d'un mapping global

Nous ne créons pas vraiment la base de données myappdata maintenant mais préparons une configuration pour la créer au moment de la construction l'image. Pour cela, nous créons juste un simple fichier au format JSON ; La bibliothèque config-api sera utilisée pour le charger dans les instances IRIS.

Creation du ficher config-files/simple-config.json

{
   "Defaults":{
       "DBDATADIR" : "${MGRDIR}myappdata/",
       "DBDATANAME" : "MYAPPDATA"

   },
   "SYS.Databases":{
       "${DBDATADIR}" : {}
   },
   "Databases":{
       "${DBDATANAME}" : {
           "Directory" : "${DBDATADIR}"
       }
   },
   "MapGlobals":{
       "USER": [{
           "Name" : "demo.*",
           "Database" : "${DBDATANAME}"
       }]
   },
   "Security.Services" : {
       "%Service_Mirror" : {                      /* Activer le service miroir sur cette instance */
           "Enabled" : true
       }
   }
}

Ce fichier de configuration vous permet de créer une nouvelle base de données avec les paramètres par défaut et de faire un global mapping demo.* dans l'espace de noms USER.

Pour plus d'informations sur les capacités du fichier de configuration config-api, consultez l'article ou la page github

Dockerfile

Le Dockerfile est basé sur le modèle existant docker template, mais nous devons faire quelques changements pour créer un répertoire de travail, installer les outils pour utiliser l'IP virtuelle, installer ZPM, etc…

Notre image IRIS est la même pour chaque membre du miroir. Le miroir sera mis en place sur le conteneur en commençant par la configuration correcte selon son rôle (primary, backup, ou report async r\w). Voir les commentaires sur le Dockerfile ci-dessous :

ARG IMAGE=containers.intersystems.com/intersystems/iris:2021.1.0.215.0
# Il n'est pas nécessaire de télécharger l'image depuis WRC. Elle sera tirée de l'ICR au moment de la construction.

FROM $IMAGE

USER root

COPY session.sh /
COPY iris.key /usr/irissys/mgr/iris.key

# /opt/demo sera notre répertoire de travail utilisé pour stocker nos fichiers de configuration et autres fichiers d'installation.
# Installez iputils-arping pour avoir une commande arping.  Nécessaire pour configurer l'IP virtuelle.
# Téléchargez la dernière version de ZPM (ZPM est inclus uniquement dans l'édition communautaire).
RUN mkdir /opt/demo && \
    chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/demo && \
    chmod 666 /usr/irissys/mgr/iris.key && \
    apt-get update && apt-get install iputils-arping gettext-base && \
    wget -O /opt/demo/zpm.xml https://pm.community.intersystems.com/packages/zpm/latest/installer

USER ${ISC_PACKAGE_MGRUSER}

WORKDIR /opt/demo

# Définissez le rôle du miroir par défaut comme assistant.
# La valeur sera remplacée dans le fichier docker-compose au moment de l'exécution.
ARG IRIS_MIRROR_ROLE=master

# Copiez le contenu du répertoire config-files dans /opt/demo.
# Actuellement, nous n'avons créé qu'un simple-config pour configurer notre base de données et le mapping global.
# Plus tard dans cet article, nous ajouterons d'autres fichiers de configuration pour mettre en place le miroir.
ADD config-files .

SHELL [ "/session.sh" ]

# Installez ZPM
# Utilisez ZPM pour installer config-api
# Chargez le fichier simple-config.json avec config-api pour :
# - créer la base de données "myappdata",
# - ajouter un mapping global dans l'espace de nom "USER" pour la globale "demo.*" sur la base de données "myappdata".
# Fondamentalement, le point d'entrée pour installer votre application ObjectScript est ici.
# Pour cet exemple, nous allons charger simple-config.json pour créer une base de données simple et un mapping global.
RUN \
Do $SYSTEM.OBJ.Load("/opt/demo/zpm.xml", "ck") \
zpm "install config-api" \
Set sc = ##class(Api.Config.Services.Loader).Load("/opt/demo/simple-config.json")

# Copiez le script d'initialisation du miroir.
COPY init_mirror.sh /

Construction de l'image IRIS

Le Dockerfile est prêt ; nous pouvons construire l'image :

docker build --no-cache --tag mirror-demo:latest .

Cette image sera utilisée pour exécuter les nœuds primary, backup et de report async.

The .env file

Les fichiers de configuration JSON et docker-compose utilisent des variables d'environnement.
Leurs valeurs sont stockées dans un fichier nommé .env, pour ce sample notre fichier env est :

APP_NET_SUBNET=172.16.238.0/24
MIRROR_NET_SUBNET=172.16.220.0/24

IRIS_HOST=172.16.238.100
IRIS_PORT=1972
IRIS_VIRTUAL_IP=172.16.238.100

ARBITER_IP=172.16.238.10

MASTER_APP_NET_IP=172.16.238.20
MASTER_MIRROR_NET_IP=172.16.220.20

BACKUP_APP_NET_IP=172.16.238.30
BACKUP_MIRROR_NET_IP=172.16.220.30

REPORT_APP_NET_IP=172.16.238.40
REPORT_MIRROR_NET_IP=172.16.220.40

Préparation du fichier de configuration du premier membre du miroir

La bibliothèque config-api permet de configurer un miroir, nous devons donc créer un fichier de configuration dédié au premier membre du miroir : config-files/mirror-master.json

Pour plus de commodité, les commentaires sont situés directement dans le JSON. Vous pouvez télécharger le fichier [mirror-master.json sans commentaire ici] (https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/config-files/mirror-master.json).

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorMaster" : {
        "Demo" : {
            "Config" : {
                "Name" : "Demo",                                /* Le nom de notre miroir */
                "SystemName" : "master",                        /* Le nom de cette instance dans le miroir */
                "UseSSL" : true,                
                "ArbiterNode" : "${ARBITER_IP}|2188",           /* L'adresse IP et port du nœud arbitre */
                "VirtualAddress" : "${IRIS_VIRTUAL_IP}/24",     /* L'adresse IP virtuelle */
                "VirtualAddressInterface" : "eth0",             /* L'interface réseau utilisée pour l'adresse IP virtuelle. */
                "MirrorAddress": "${MASTER_MIRROR_NET_IP}",     /* L'adresse IP de ce noeud dans le réseau miroir privé */
                "AgentAddress": "${MASTER_APP_NET_IP}"          /* L'adresse IP de ce nœud (l'agent est installé sur la même machine) */
            },
            "Databases" : [{                                    /* La liste des bases de données à ajouter au miroir */
                "Directory" : "/usr/irissys/mgr/myappdata/",
                "MirrorDBName" : "MYAPPDATA"
            }],
            "SSLInfo" : {                                       /* SSL Configuration */
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/master_server.cer",
                "PrivateKeyFile" : "/certificates/master_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
}

Préparer le fichier de configuration du membre de basculement

Créer un fichier de configuration pour le membre backup (basculement) config-files/mirror-backup.json.

Le fichier est fort ressemblant au fichier de configuration du membre primary:

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorFailOver" : {
        "Demo" : {                                          /* Le miroir à rejoindre */
            "Config": {
                "Name" : "Demo",
                "SystemName" : "backup",                    /* Le nom de cette instance dans le miroir */
                "InstanceName" : "IRIS",                    /* Le nom de l'instance IRIS du premier membre du miroir */
                "AgentAddress" : "${MASTER_APP_NET_IP}",    /* L'adresse IP de l'agent du premier membre du miroir */
                "AgentPort" : "2188",
                "AsyncMember" : false,
                "AsyncMemberType" : ""
            },  
            "Databases" : [{                                /* DB dans le miroir */
                 "Directory" : "/usr/irissys/mgr/myappdata/"    
            }],
            "LocalInfo" : {
                "VirtualAddressInterface" : "eth0",         /* L'interface réseau utilisée pour l'adresse IP virtuelle */
                "MirrorAddress": "${BACKUP_MIRROR_NET_IP}"  /* L'adresse IP de ce noeud dans le réseau miroir privé */
            },
            "SSLInfo" : {
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/backup_server.cer",
                "PrivateKeyFile" : "/certificates/backup_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
}

Préparation du fichier de configuration des membres asynchrones en lecture-écriture

Il est assez similaire au fichier de configuration de basculement backup. Les différences sont les valeurs de AsyncMember, AsyncMemberType, et MirrorAddress. Créez le fichier ./config-files/mirror-report.json :

{
    "Security.Services" : {
        "%Service_Mirror" : {
            "Enabled" : true
        }
    },
    "SYS.MirrorFailOver" : {
        "Demo" : {
            "Config": {
                "Name" : "Demo",
                "SystemName" : "report",
                "InstanceName" : "IRIS",
                "AgentAddress" : "${MASTER_APP_NET_IP}",
                "AgentPort" : "2188",
                "AsyncMember" : true,
                "AsyncMemberType" : "rw"
            },
            "Databases" : [{
                 "Directory" : "/usr/irissys/mgr/myappdata/"
            }],
            "LocalInfo" : {
                "VirtualAddressInterface" : "eth0",
                "MirrorAddress": "${REPORT_MIRROR_NET_IP}"
            },
            "SSLInfo" : {
                "CAFile" : "/certificates/CA_Server.cer",
                "CertificateFile" : "/certificates/report_server.cer",
                "PrivateKeyFile" : "/certificates/report_server.key",
                "PrivateKeyPassword" : "",
                "PrivateKeyType" : "2"
            }
        }
    }
}

Génération des certificats et configuration des nœuds IRIS et

Tous les fichiers de configuration sont prêts !

Maintenant nous devons ajouter un script pour générer des certificats afin de sécuriser la communication entre chaque nœud. Un script prêt à l'emploi est disponible dans le repository gen-certificates.sh

# sudo est nécessaire en raison de l'utilisation de chown, chgrp chmod.
sudo ./gen-certificates.sh

Pour configurer chaque nœud, init_mirror.sh sera exécuté au démarrage des conteneurs. Il sera configuré plus tard dans docker-compose.yml dans la section commande command : ["-a", "/init_mirror.sh"] :

#!/bin/bash

# Base de données utilisée pour tester le miroir.
DATABASE=/usr/irissys/mgr/myappdata

# Répertoire contenant mes données d'application sauvegardées par l'assistant pour les restaurer sur les autres nœuds et en faire un miroir.
BACKUP_FOLDER=/opt/backup

# Fichier de configuration miroir au format json config-api pour le nœud d'assistant.
MASTER_CONFIG=/opt/demo/mirror-master.json

# Fichier de configuration miroir au format json config-api pour le nœud de sauvegarde.
BACKUP_CONFIG=/opt/demo/mirror-backup.json

# Fichier de configuration miroir au format json config-api pour le nœud asynchrone de rapport.
REPORT_CONFIG=/opt/demo/mirror-report.json

# Nom du miroir...
MIRROR_NAME=DEMO

# Liste des membres du miroir.
MIRROR_MEMBERS=BACKUP,REPORT

# Chargement de la configuration du miroir en utilisant config-api avec le fichier /opt/demo/simple-config.json.
# Démarrage d'une tâche Job pour accepter automatiquement d'autres membres nommés "backup" et "report" pour rejoindre le miroir (éviter la validation manuelle dans la gestion du portail).
master() {
rm -rf $BACKUP_FOLDER/IRIS.DAT
envsubst < ${MASTER_CONFIG} > ${MASTER_CONFIG}.resolved
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Set sc = ##class(Api.Config.Services.Loader).Load("${MASTER_CONFIG}.resolved")
Set ^log.mirrorconfig(\$i(^log.mirrorconfig)) = \$SYSTEM.Status.GetOneErrorText(sc)
Job ##class(Api.Config.Services.SYS.MirrorMaster).AuthorizeNewMembers("${MIRROR_MEMBERS}","${MIRROR_NAME}",600)
Hang 2
Halt
END
}

make_backup() {
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
md5sum ${DATABASE}/IRIS.DAT
cp ${DATABASE}/IRIS.DAT ${BACKUP_FOLDER}/IRIS.TMP
mv ${BACKUP_FOLDER}/IRIS.TMP ${BACKUP_FOLDER}/IRIS.DAT
chmod 777 ${BACKUP_FOLDER}/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}

# Restauration de la base de données miroir "myappdata".  Cette restauration est effectuée sur le noeud "backup" et "report".
restore_backup() {
sleep 5
while [ ! -f $BACKUP_FOLDER/IRIS.DAT ]; do sleep 1; done
sleep 2
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
cp $BACKUP_FOLDER/IRIS.DAT $DATABASE/IRIS.DAT
md5sum $DATABASE/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}

# Configuration du membre "backup"
#  - Chargement du fichier de configuration /opt/demo/mirror-backup.json si cette instance est le backup ou
#    /opt/demo/mirror-report.json si cette instance est le rapport (nœud miroir asynchrone R\W).
other_node() {
sleep 5
envsubst < $1 > $1.resolved
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Set sc = ##class(Api.Config.Services.Loader).Load("$1.resolved")
Halt
END
}

if [ "$IRIS_MIRROR_ROLE" == "master" ]
then
  master
  make_backup
elif [ "$IRIS_MIRROR_ROLE" == "backup" ]
then
  restore_backup
  other_node $BACKUP_CONFIG
else
  restore_backup
  other_node $REPORT_CONFIG
fi

exit 0

Fichier Docker-compose

Nous avons quatre conteneurs pour commencer. Un fichier Docker-compose est parfait pour orchestrer notre sample.

version: '3.7'

services:
  arbitre:
    image: containers.intersystems.com/intersystems/arbiter:2021.1.0.215.0
    init: true
    container_name: mirror-demo-arbiter
    commande:
      - /usr/local/etc/irissys/startISCAgent.sh 2188
    réseaux:
      app_net:
        ipv4_address: ${ARBITER_IP}
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "backup:${BACKUP_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN

  assistant:
    construction: .
    image: mirror-demo
    container_name: mirror-demo-master
    réseaux:
      app_net:
        ipv4_address: ${MASTER_APP_NET_IP}
      mirror_net:
        ipv4_address: ${MASTER_MIRROR_NET_IP}
    environnement:
      - IRIS_MIRROR_ROLE=master
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - MASTER_MIRROR_NET_IP=${MASTER_MIRROR_NET_IP}
      - ARBITER_IP=${ARBITER_IP}
      - IRIS_VIRTUAL_IP=${IRIS_VIRTUAL_IP}
    ports:
      - 81:52773
    volumes:
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Montage des certificats
      - ./certificates/master_server.cer:/certificates/master_server.cer
      - ./certificates/master_server.key:/certificates/master_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    nom de l'hôte: master
    extra_hosts:
      - "backup:${BACKUP_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    commande: ["-a", "/init_mirror.sh"]

  sauvegarde:
    image: mirror-demo
    container_name: mirror-demo-backup
    réseaux:
      app_net:
        ipv4_address: ${BACKUP_APP_NET_IP}
      mirror_net:
        ipv4_address: ${BACKUP_MIRROR_NET_IP}
    ports:
      - 82:52773
    environnement :
      - IRIS_MIRROR_ROLE=backup
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - BACKUP_MIRROR_NET_IP=${BACKUP_MIRROR_NET_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - BACKUP_APP_NET_IP=${BACKUP_APP_NET_IP}
    volumes:
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Montage des certificats
      - ./certificates/backup_server.cer:/certificates/backup_server.cer
      - ./certificates/backup_server.key:/certificates/backup_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    nom de l'hôte: backup
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "report:${REPORT_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    commande: ["-a", "/init_mirror.sh"]

  rapport :
    image: mirror-demo
    container_name: mirror-demo-report
    réseaux:
      app_net:
        ipv4_address: ${REPORT_APP_NET_IP}
      mirror_net:
        ipv4_address: ${REPORT_MIRROR_NET_IP}
    ports:
      - 83:52773
    environnement :
      - IRIS_MIRROR_ROLE=report
      - WEBGATEWAY_IP=${WEBGATEWAY_IP}
      - MASTER_APP_NET_IP=${MASTER_APP_NET_IP}
      - REPORT_MIRROR_NET_IP=${REPORT_MIRROR_NET_IP}
      - REPORT_APP_NET_IP=${REPORT_APP_NET_IP}
    volumes:
      - ./backup:/opt/backup
      - ./init_mirror.sh:/init_mirror.sh
      # Montage des certificats
      - ./certificates/report_server.cer:/certificates/report_server.cer
      - ./certificates/report_server.key:/certificates/report_server.key
      - ./certificates/CA_Server.cer:/certificates/CA_Server.cer
      #- ~/iris.key:/usr/irissys/mgr/iris.key
    nom de l'hôte: report
    extra_hosts:
      - "master:${MASTER_APP_NET_IP}"
      - "backup:${BACKUP_APP_NET_IP}"
    cap_add:
      - NET_ADMIN
    commande: ["-a", "/init_mirror.sh"]

réseaux:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "${APP_NET_SUBNET}"
  mirror_net:
    ipam:
      driver: default
      config:
        - subnet: "${MIRROR_NET_SUBNET}"

Le fichier docker-compose.yml contient beaucoup de variables d'environnement. Pour voir le fichier résolu, tapez dans le terminal :

docker-compose config

Exécuter des conteneurs

docker-compose up

Attendez que chaque instance ait un statut de miroir correct :

  • nœud primary avec le statut Primary.
  • nœud backup avec le statut Backup.
  • noeud report avec le statut Connected.

Enfin, vous devriez voir ces messages dans les journaux de docker :

mirror-demo-master | 01/09/22-11:02:08:227 (684) 1 [Utility.Event] Devient le serveur miroir primaire
...
mirror-demo-backup | 01/09/22-11:03:06:398 (801) 0 [Utility.Event] Trouver MASTER comme primaire, devenant sauvegarde
...
mirror-demo-report | 01/09/22-11:03:10:745 (736) 0 [Generic.Event] MirrorClient : Connecté au primaire : MASTER (ver 4)

Vous pouvez aussi vérifier l'état du miroir avec le portail http://localhost:81/csp/sys/utilhome.csp

État-miroir

Accès aux portails

Dans Docker-compose, nous mappons les ports 81, 82 et 83 pour avoir un accès à chaque portail de gestion. Il s'agit du login/mot de passe par défaut pour toutes les instances :

Test

Vérifiez le moniteur miroir (portail de gestion ; il s'agit de l'utilisateur et du mot de passe par défaut) : http://localhost:81/csp/sys/op/%25CSP.UI.Portal.Mirror.Monitor.zenMiroir-Moniteur

Vérifiez les paramètres du miroir : http://localhost:81/csp/sys/mgr/%25CSP.UI.Portal.Mirror.EditFailover.zen?$NAMESPACE=%25SYS

Miroir-Configuration

Nous pouvons démarrer un test en configurant simplement une globale commençant par demo. Rappelez-vous que nous avons configuré un mapping global demo.* sur l'espace de nom USER.

Ouvrez une session de terminal sur le serveur primaire :

docker exec -it mirror-demo-master irissession iris
Set ^demo.test = $zdt($h,3,1)

Vérifiez si les données sont disponibles sur le nœud de sauvegarde :

docker exec -it mirror-demo-backup irissession iris
Write ^demo.test

Vérifiez si les données sont disponibles sur le nœud de rapport ::

docker exec -it mirror-demo-report irissession iris
Write ^demo.test

Bien ! Nous avons un environnement miroir prêt, entièrement créé par programmation. Pour que ce soit un peu plus complet, il faudrait ajouter une passerelle web avec https et un cryptage entre la passerelle web et IRIS, mais nous allons laisser cela pour le prochain article.

Nous espérons que cet article vous sera utile si vous décidez de créer votre propre script

Source

Le contenu de cet article est inspiré par :

0
0 169
Article Lorenzo Scalese · Mars 18, 2022 6m read

Chers développeurs,

Écrire un script pour le déploiement d'une application peut être très intéressant pour assurer un déploiement rapide sans rien oublier. config-api est une bibliothèque pour aider les développeurs à écrire des scripts de configuration basés sur un document JSON.

Fonctions implémentées :

  • Définir les paramètres du système.
  • Définir les paramètres de sécurité.
  • Activer les services.
  • Configurer les espaces de noms, les bases de données, le mapping.
  • Exporter la configuration existante.
  • Toutes les fonctionnalités sont exposées avec une API RESTful.

Cette bibliothèque se concentre sur la configuration d'IRIS pour faciliter le déploiement des applications. Ainsi, config-api n'importe/ne compile pas de code, considérant que cela devrait être le rôle du module d'installation de votre application ou du registre du client. config-api pourrait être utilisé avec le client ZPM pour configurer les paramètres IRIS lors du déploiement du module, nous apprendrons comment combiner cette bibliothèque avec ZPM dans un autre article.

Installer

zpm “install config-api”

Si vous n'êtes pas un utilisateur de ZPM, téléchargez la dernière version au format XML avec les dépendances sur la page de publication, importez et compilez.

Première étape

Écrivons un simple document JSON de configuration pour définir quelques paramètres du système.
Dans ce premier document, nous :

  • Activons le gel du journal en cas d'erreur.
  • Définissons la taille limite du journal à 256 Mo.
  • Définissons SystemMode sur développement.
  • Augmentons le locksiz.
  • Augmentons le 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)

structure du document JSON de configuration

Les clés de premier niveau (Journal, SQL ,config, Startup) sont liées aux classes de l'espace de noms %SYS (en utilisant une classe intermédiaire du paquet Api.Config.Services). Cela signifie que Journal prend en charge toutes les propriétés disponibles dans Config.Journal, SQL, toutes les propriétés dans Config.SQL, etc...

Sortie :

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

Astuce : la méthode Load est compatible avec un argument de type chaîne, dans ce cas, la chaîne doit être un nom de fichier vers un document de configuration JSON (l'objet stream est également autorisé).

Créer un environnement d'application

Dans cette section, nous écrivons un document de configuration pour créer :

  • Un espace de nom « MYAPP ».
  • 4 bases de données (MYAPPDATA, MYAPPCODE, MYAPPARCHIVE,MYAPPLOG)
  • 1 application Web CSP (/csp/zwebapp).
  • 1 application Web REST (/csp/zrestapp).
  • Configuration du mappage des globales.
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)

Sortie :

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

Ça marche ! La configuration est correctement chargée.

Dans le prochain article, nous apprendrons comment utiliser config-api avec ZPM pour déployer votre application.

L'application est présentée pour le concours, votez pour elle si vous l'aimez ;-) .

Merci de votre lecture.

0
0 93