Diffusion continue de votre solution InterSystems à l'aide de GitLab - Partie VII : CD utilisant des conteneurs
Dans cette série d'articles, j'aimerais présenter et discuter de plusieurs approches possibles pour le développement de logiciels avec les technologies d'InterSystems et GitLab. J'aborderai des sujets tels que:
- Git 101
- Flux Git (processus de développement)
- Installation de GitLab
- Flux de travail GitLab
- Diffusion continue
- Installation et configuration de GitLab
- GitLab CI/CD
- Pourquoi des conteneurs?
- Infrastructure de conteneurs
- CD utilisant des conteneurs
Dans le premier article, nous avons évoqué les notions de base de Git, les raisons pour lesquelles une compréhension approfondie des concepts de Git est importante pour le développement de logiciels modernes et la manière dont Git peut être utilisé pour développer des logiciels.
Dans le deuxième article, nous avons évoqué le flux de travail GitLab - un processus complet du cycle de vie du logiciel ainsi que Diffusion continue.
Dans le troisième article, nous avons évoqué l'installation et la configuration de GitLab et la connexion de vos environnements à GitLab
Dans le quatrième article, nous avons écrit une configuration de CD.
Dans le cinquième article, nous avons parlé des conteneurs et de la manière dont ils peuvent être utilisés (et pour quelles raisons).
Dans le sixème article nous abordons des principaux composants dont vous aurez besoin pour exécuter un pipeline de diffusion continue avec des conteneurs et de la façon dont ils fonctionnent tous ensemble.
Dans cet article, nous allons créer une configuration de diffusion continue décrite dans les articles précédents.
Flux de Travail
Dans notre Diffusion continue, nous allons:
- Introduire le code dans le référentiel GitLab
- Construire l' image docker
- Tester cette image
- Publier l'image dans notre registre docker
- Remplacer l'ancien conteneur par la nouvelle version à partir du registre
Ou en format graphique :

Commençons donc!
Build (csonstruction)
D'abord, nous devons construire notre image.
Notre code sera, comme d'habitude, stocké dans le référentiel, la configuration CD - dans gitlab-ci.yml mais en plus (pour renforcer la sécurité) nous stockerons plusieurs fichiers spécifiques au serveur sur un serveur build.
GitLab.xml
Contient le code d'accrochage du CD. Il a été développé dans l' article précédent et disponible sur GitHub. Il s'agit d'une petite bibliothèque permettant de télécharger du code, d'exécuter divers accrochages et de tester le code. Il est préférable d'utiliser les sous-modules git pour inclure ce projet ou quelque chose de similaire dans votre référentiel. Les sous-modules sont meilleurs car il est plus facile de les mettre à jour. Une autre solution est de baliser les versions sur GitLab et de les télécharger à l'aide de la commande ADD.
iris.key
Clé de licence. Elle peut également être téléchargée lors du conteneur build au lieu d'être stockée sur un serveur. Il n'est pas très sûr de la stocker dans le référentiel.
pwd.txt
Fichier contenant le mot de passe par défaut. Là encore, il n'est pas très sûr de le stocker dans le référentiel. De plus, si vous hébergez l'environnement de production (prod) sur un serveur séparé, il pourrait avoir un mot de passe par défaut différent.
load_ci.script
Script initial qui:
- Active l'authentification OS
- Télécharge le fichier GitLab.xml
- Initialise les paramètres de l'utilitaire GitLab
- Télécharge le code
set sc = ##Class(Security.System).Get("SYSTEM",.Properties)
write:('sc) $System.Status.GetErrorText(sc)
set AutheEnabled = Properties("AutheEnabled")
set AutheEnabled = $zb(+AutheEnabled,16,7)
set Properties("AutheEnabled") = AutheEnabled
set sc = ##Class(Security.System).Modify("SYSTEM",.Properties)
write:('sc) $System.Status.GetErrorText(sc)
zn "USER"
do ##class(%SYSTEM.OBJ).Load(##class(%File).ManagerDirectory() _ "GitLab.xml","cdk")
do ##class(isc.git.Settings).setSetting("hooks", "MyApp/Hooks/")
do ##class(isc.git.Settings).setSetting("tests", "MyApp/Tests/")
do ##class(isc.git.GitLab).load()
haltNotez que la première ligne est intentionnellement laissée vide.
Puisque certains paramètres peuvent être spécifiques au serveur, ils ne sont pas stockés dans le référentiel, mais plutôt à part. Si cet accrochage initial est toujours le même, vous pouvez simplement le stocker dans le référentiel.
gitlab-ci.yml
Passons maintenant à la configuration de la diffusion continue :
build image:
stage: build
tags:
- test
script:
- cp -r /InterSystems/mount ci
- cd ci
- echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt
- mv temp.txt load_ci.script
- cd ..
- docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.domain.com/test/docker:$CI_COMMIT_REF_NAME .Que se passe-t-il ici?
Tout d'abord, comme docker build ne peut accéder qu'aux sous-référentiel d'un référentiel de base build qui est dans notre cas la racine du référentiel, nous devons copier notre référentiel "secret" (celui qui contient GitLab.xml, iris.key, pwd.txt and load_ci.script) dans le référentiel cloné.
Ensuite, pour accéder au premier terminal, il faut avoir un utilisateur et un mot de passe, donc il faut les ajouter à load_ci.script (c'est à cela que sert la ligne vide au début de load_ci.script est pour btw).
Enfin, nous construisons l'image docker et la balisons de manière appropriée: docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
où $CI_COMMIT_REF_NAME est le nom de la branche courante. Notez que la première partie de la balise de l'image doit être nommée de la même manière que le nom du projet dans GitLab, de manière à ce qu'elle puisse être vue dans l'onglet Registre de GitLab (les instructions sur le balisage sont disponibles dans l'onglet Registre).
Dockerfile
La construction de l'image docker se fait en utilisant Dockerfile, la voici:
FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0 ENV SRC_DIR=/tmp/src ENV CI_DIR=$SRC_DIR/ci ENV CI_PROJECT_DIR=$SRC_DIR COPY ./ $SRC_DIR RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ \ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ \ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt \ && iris start $ISC_PACKAGE_INSTANCENAME \ && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script \ && iris stop $ISC_PACKAGE_INSTANCENAME quietly
Nous partons du conteneur iris de base.
Tout d'abord, nous copions notre référentiel (ainsi que le référentiel "secret") à l'intérieur du conteneur.
Ensuite, nous copions la clé de licence et le fichier GitLab.xml dans le référentiel mgr.
Ensuite, nous remplaçons le mot de passe par la valeur du fichier pwd.txt. Notez que le fichier pwd.txt est supprimé lors de cette opération.
Ensuite, l'instance est démarrée et le fichier load_ci.script est exécuté.
Finalement, l'instance iris est arrêtée.
Voici le journal de tâches ( incomplet, les journaux de téléchargement/compilation ont été ignorés) :
Running with gitlab-runner 10.6.0 (a3543a27) on docker 7b21e0c4 Using Shell executor... Running on docker... Fetching changes... Removing ci/ Removing temp.txt HEAD is now at 5ef9904 Build load_ci.script From http://gitlab.eduard.win/test/docker 5ef9904..9753a8d master -> origin/master Checking out 9753a8db as master... Skipping Git submodules setup $ cp -r /InterSystems/mount ci $ cd ci $ echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt $ mv temp.txt load_ci.script $ cd .. $ docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME . Sending build context to Docker daemon 401.4kB Step 1/6 : FROM docker.intersystems.com/intersystems/iris:2018.1.1.611.0 ---> cd2e53e7f850 Step 2/6 : ENV SRC_DIR=/tmp/src ---> Using cache ---> 68ba1cb00aff Step 3/6 : ENV CI_DIR=$SRC_DIR/ci ---> Using cache ---> 6784c34a9ee6 Step 4/6 : ENV CI_PROJECT_DIR=$SRC_DIR ---> Using cache ---> 3757fa88a28a Step 5/6 : COPY ./ $SRC_DIR ---> 5515e13741b0 Step 6/6 : RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt && iris start $ISC_PACKAGE_INSTANCENAME && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script && iris stop $ISC_PACKAGE_INSTANCENAME quietly ---> Running in 86526183cf7c . Waited 1 seconds for InterSystems IRIS to start This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement %SYS> 1 %SYS> Using 'iris.cpf' configuration file This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement 1 alert(s) during startup. See messages.log for details. Starting IRIS Node: 39702b122ab6, Instance: IRIS Username: Password: Load started on 04/06/2018 17:38:21 Loading file /usr/irissys/mgr/GitLab.xml as xml Load finished successfully. USER> USER> [2018-04-06 17:38:22.017] Running init hooks: before [2018-04-06 17:38:22.017] Importing hooks dir /tmp/src/MyApp/Hooks/ [2018-04-06 17:38:22.374] Executing hook class: MyApp.Hooks.Global [2018-04-06 17:38:22.375] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.375] Importing dir /tmp/src/ Loading file /tmp/src/MyApp/Tests/TestSuite.cls as udl Compilation started on 04/06/2018 17:38:22 with qualifiers 'c' Compilation finished successfully in 0.194s. Load finished successfully. [2018-04-06 17:38:22.876] Running init hooks: after [2018-04-06 17:38:22.878] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.921] Executing hook class: MyApp.Hooks.Global Removing intermediate container 39702b122ab6 ---> dea6b2123165 [Warning] One or more build-args [CI_PROJECT_DIR] were not consumed Successfully built dea6b2123165 Successfully tagged docker.domain.com/test/docker:master Job succeeded
Notez que j'utilise l' GitLab Shell au lieu d'exécuteur Docker. L'exécuteur Docker est utilisé lorsque vous avez besoin de quelque chose de l'intérieur de l'image, par exemple, vous créez une application Android dans un conteneur java et vous n'avez besoin que d'un apk. Dans notre cas, il nous faut un conteneur complet et pour cela nous avons besoin de l'exécuteur Shell. Nous exécutons donc des commandes Docker via l'exécuteur GitLab Shell.
Exécution
Nous avons notre image, maintenant nous allons l'exécuter. Dans le cas de branches de fonctionnalités, nous pouvons juste détruire l'ancien conteneur et démarrer le nouveau. Dans le cas de l'environnement, nous pouvons exécuter un conteneur temporaire et remplacer le conteneur de l'environnement en cas de réussite des tests (c'est un exercice que nous laissons au lecteur).
Voici le script.
destroy old:
stage: destroy
tags:
- test
script:
- docker stop iris-$CI_COMMIT_REF_NAME || true
- docker rm -f iris-$CI_COMMIT_REF_NAME || trueCe script détruit le conteneur en cours d'exécution et réussit toujours (par défaut, Docker échoue s'il essaie d'arrêter/supprimer un conteneur inexistant).
Ensuite, nous démarrons une nouvelle image et l'enregistrons en tant qu'environnement.Le conteneur Nginx effectue automatiquement le proxy des requêtes en utilisant la variable d'environnement VIRTUAL_HOST et expose une directive (pour savoir quel port sera utilisé pour le proxy).
run image:
stage: run
environment:
name: $CI_COMMIT_REF_NAME
url: http://$CI_COMMIT_REF_SLUG. docker.domain.com/index.html
tags:
- test
script:
- docker run -d
--expose 52773
--env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win
--name iris-$CI_COMMIT_REF_NAME
docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
--log $ISC_PACKAGE_INSTALLDIR/mgr/messages.logTests
Faisons quelques tests.
test image:
stage: test
tags:
- test
script:
- docker exec iris-$CI_COMMIT_REF_NAME irissession iris -U USER "##class(isc.git.GitLab).test()"Publication
Finalement, publions notre image dans le registre
publish image:
stage: publish
tags:
- test
script:
- docker login docker.domain.com -u dev -p 123
- docker push docker.domain.com/test/docker:$CI_COMMIT_REF_NAMEL'utilisateur et le mot de passe peuvent être transmis à l'aide des variables secrètes de GitLab.
Maintenant, nous pouvons voir l'image dans GitLab:

Les autres développeurs peuvent l'extraire du registre. Dans l'onglet "Environnements", tous nos environnements sont disponibles pour une navigation simple :

Conclusion
Dans cette série d'articles, j'ai abordé les approches générales de la diffusion continue. Il s'agit d'un sujet extrêmement vaste et cette série d'articles doit être considérée plutôt comme une collection de recettes que comme quelque chose de définitif. Si vous souhaitez automatiser la construction, les tests et la diffusion de votre application, la diffusion continue de manière générale et GitLab en particulier sont la manière de procéder. La Diffusion continue et les conteneurs vous permettent de personnaliser votre flux de travail en fonction de vos besoins.
Liens
Prochaine étape
C'est tout ! J'espère avoir couvert les bases de la diffusion continue et des conteneurs.
Il y a un tas de sujets dont je n'ai pas abordé (donc peut-être je ferai ça plus tard), en particulier sur les conteneurs:
- Les données peuvent être conservées en dehors du conteneur, voici la documentation à ce sujet
- Plateformes d'orchestration comme kubernetes
- Gestionnaire "InterSystems Cloud Manager"
- Gestion de l'environnement - création d'environnements temporaires pour les tests, suppression des environnements obsolètes après la fusion des branches fonctionnelles
- Docker compose pour les déploiements multi-conteneurs
- Réduction du poids de l'image docker et des délais de construction
- ...