À la découverte d'Openshift


Aloha, je vous propose une présentation générale d'Openshift via un cas d'usage avec une application Symfony 4.

Tout d'abord, on commence par les présentations ;

Je suis une plateforme en tant que service de la société Red Hat ¹ , ou bien encore, je suis une plateforme d'applications conteneurisées, open source, basée sur Kubernetes pour le développement et le déploiement des applications entreprises ².

Ce que je peux dire en quelques mots d'Openshift : 
  • C'est une PaaS : Plateform-as-a-service
  • Trois offres disponibles : Online (utilisée dans ce Post),  Online Dedicated et privée (hébergée chez vous)
  • Elle nous permet de construire, déployer et exécuter des applications dans des conteneurs
  • Sa configuration est basée sur un moteur de conteneurs Docker avec l'orchestrateur Kubernetes 
  • Nous offre une architecture orientée micro-services.

Parmi les services proposés par la plateforme : 
  • Conteneurisation (Source to images ³, Docker Repository, Image Stream)
  • Route & LoaderBalancer
  • Stockage distribué (Shared storage)
  • Gestion des ressources (Quota, Membership, ConfigMap, Secret,...)
  • Monitoring (Elasticsearch, Fluentd, Kibana) & Readiness / Liveness

Concrètement :

Ceci est un exemple simple d’application Web déployée dans un cluster Openshift.


Petit rappel : Un cluser Openshift est un ensemble de machines virtuelles ou physiques contenant des noeuds (un master au minimum), ils contiennent quand à eux des Pods qui sont le résultat du Run d'une image docker.


Le client (qui peut être un navigateur Web) demande une URL (une route externe au cluster) de l'application Web, le Router de la plateforme dispatchera cette requête vers le service concerné (cela peut être une ouverture du port 80 et association du port au Pod frontal).

Le Pod frontal pourra alors être considéré comme le contrôleur FontEnd de notre application, et qui fera appel à l'application métier déployée elle aussi dans un Pod en Backend et en communication  avec le Pod porteur de la base de données (via un service TCP sur 3306 par exemple pour une base de données MySQL).

Enfin, tous les Pods utilisent le système de stockage distribué et géré par la plateforme via des montages de système de fichiers virtuel.

Généralement, quand on dispose de plusieurs clusters, on définit un cluster Front (peut être derrière un Proxy) pour exposer les services vers l'extérieure du cluster et un autre cluster Back qui portera les applications métier ainsi que l'accès au données. Ces deux cluster auront des configurations et des exigences de sécurité différentes, ce qui nous permettra d'isoler et de protéger encore les données métiers.



Notre cas d'usage, l'application Symfony: 

C'est une application PHP Symfony 4 standard de démonstration avec un peu de modifications pour ajouter le support de Memcached par exemple et l'usage d'une base de données MySQL à la place de SQLLite. Elle est disponible ici (la branche "openshift"). 


On démarre !

Pour commencer, on a besoin d'une instance OpenShift, et là une simple inscription au programme de démo (Starter Pack), nous donne droit à 2Go de mémoire , 2Go de disk et 4 cœurs gratuitement pour 60 jours.  

Lors de la connexion à la console, on a un vue du catalogue d'images et de services proposés par la plateforme :

Vue Catalogue avec notre projet "MedInvention project"


On commencera donc par créer un projet (on a droit à un seul à la fois) et du point de vue d'Openshift, c'est un Namespace : avec ses propres règles de gestions des ressources, d'accès et une certaine isolation avec le reste des Namespace.

Pour notre exemple, on aurai besoin d'une instance d'Apache avec PHP 7, Opcache et Memcached installés. L'image de PHP proposée par la plateforme ne supporte pas Memcached c'est pour cette raison qu'on utilisera une image dédiée disponible sur DockerHub (Tag "openshift" et source disponible sur GitHub).

Toutefois, si on souhaite utiliser l'image proposée, on passe par le catalogue et on aura ceci

On peut utiliser l'application de démonstration CakePHP disponible sur GitHub ou bien consulter les détails de l'image en question (variables d’environnement et caractéristiques)

Vous devez spécifier la version de PHP et le Repository Git source de l'application PHP


Et si on souhaite utiliser notre image, on passe alors par "Add to Project" ensuite "Import YAML / JSON" :

Import d'un BuildConfig pour la construction de l'image Docker

On peut copier / coller ce contenu :
       
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  labels:
    app: webapp
  name: webapp
spec:
  output:
    to:
      kind: ImageStreamTag
      name: 'webapp:latest'
  source:
    git:
      ref: openshift
      uri: 'https://github.com/mmohamed/demo.git'
    type: Git
  strategy:
    sourceStrategy:
      from:
        kind: DockerImage
        name: 'medinvention/s2i-ubuntu-php72-apache24:openshift'
    type: Source

 

Ensuite on doit définir une route externe  pour notre application :

Dans le cas où on utilise une image du catalogue, cette route sera provisionnée automatiquement. Elle doit pointée vers le service webapp qui expose le port 8080 de notre Pod frontal


On peut aussi passer par "Add to Project" ensuite "Deploy image" (Sans les sources Git) on aura :

On voit qu'on aura droit à un DeployementConfig de cette image, que le port 8080 sera exposé via un service et que le conteneur de cette image sera accessible via le Hostname s2i-ubuntu-php72-apache2

/!\ Astuce : on peut utiliser l'image par défaut PHP pour initier le DeploymentConfig de type S2I avec notre Repository GitHub , ensuite modifier la configuration pour utiliser notre image spécifique sans à voir à définir un BuildConfig complet.





Donc, maintenant on a un Build et un DeploymentConfig fonctionnel, notre premier Build et notre premier Deploy sont terminés avec succès.  On a un Pod en Run et prêt à répondre aux requêtes.

On a ici une route externe (provisionnée automatiquement par OpenShif) pour accéder à notre Pod applicatif


Il reste alors le déploiement d'une image de base de données (on utilisera le catalogue pour MySQL), et une image MemCached server. On utilisera pour cette dernière un Template YAML, car elle n'existe pas par défaut dans le catalogue, avec la fonctionnalité d'import des définitions d’objets en YAML/JSON pour importer ce Template et l’appliquer.

On doit avoir maintenant un environnement complet :

Notre environnement  

On peut donc accéder à notre application via l'URL public

On peut naviguer dans l'application pour vérifier la connexion à la base de données et la communication avec le serveur Memcached


Un dernier outil nous manque pour faire du déploiement en continu ; là on peut utiliser Jenkins qui est proposé par la plateforme dans le catalogue.

Par défaut, Jenkins aura sa propre route public et un Job simple.

Il nous reste qu'a mettre à jour notre Job Jenkins pour déclencher un Build suivi d'un déploiement lorsqu'il détecte un changement dans les sources de notre application sur GitHub.

un Job pour déployer, mais plusieurs formant un Pipeline avec une phase de Build, Test et Deploy serais mieux bien sûre


On peut voir les Logs du Job :
Started by an SCM change

No credentials specified
 > git rev-parse --is-inside-work-tree # timeout=10
....
 > git rev-list --no-walk b9feb776306e16bcba20a6d371e9e83a838d1a2b # timeout=10

Starting "Scale OpenShift Deployment" with deployment config "memcached" from the project "demo-medinvention".
 Scaling to "0" replicas and verifying the replica count is reached ...
Operation will timeout after 180000 milliseconds

Exiting "Scale OpenShift Deployment" successfully, where the deployment "memcached-2" reached "0" replica(s).

Starting the "Trigger OpenShift Build" step with build config "webapp" from the project "demo-medinvention".
  Started build "webapp-9" and waiting for build completion ...
Operation will timeout after 900000 milliseconds
Pulling image "medinvention/s2i-ubuntu-php72-apache24:openshift" ...
Using medinvention/s2i-ubuntu-php72-apache24:openshift as the s2i builder image
---> Installing application source...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
....
Generating optimized autoload files
ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]

Executing script security-checker security:check [OK]
---> Clear cache/logs and fixing permissions...

Pushing image docker-registry.default.svc:5000/demo-medinvention/webapp:latest ...
Pushed 0/17 layers, 0% complete
....
Pushed 17/17 layers, 100% complete
Push successful


Exiting "Trigger OpenShift Build" successfully; build "webapp-9" has completed with status:  [Complete].

Starting "Trigger OpenShift Deployment" with deployment config "webapp" from the project "demo-medinvention".
Operation will timeout after 600000 milliseconds

Exiting "Trigger OpenShift Deployment" successfully; deployment "webapp-13" has completed with status:  [Complete].

Starting "Tag OpenShift Image" with the source [image stream:tag] "webapp:latest" from the project "demo-medinvention" and destination stream(s) "webapp" with tag(s) "prod" from the project "demo-medinvention".

Exiting "Tag OpenShift Image" successfully.

Starting "Verify OpenShift Deployment" with deployment config "webapp" from the project "demo-medinvention".
  Waiting on the latest deployment for "webapp" to complete ...
Operation will timeout after 180000 milliseconds


Exiting "Verify OpenShift Deployment" successfully; deployment "webapp-13" has completed with status:  [Complete].

Starting "Scale OpenShift Deployment" with deployment config "memcached" from the project "demo-medinvention".
 Scaling to "1" replicas and verifying the replica count is reached ...
Operation will timeout after 180000 milliseconds


Exiting "Scale OpenShift Deployment" successfully, where the deployment "memcached-2" reached "1" replica(s).
Finished: SUCCESS


Au final,


La cible

On dispose maintenant d'un environnement complet avec une intégration et un déploiement en continu.
On peut distinguer deux Pipelines :

  • Le premier est celui de notre image Docker de Base (S2I) ; comme j'ai configuré un Auto-Build dans DockerHub (1), ce dernier surveille en permanence le Repository de l'image dans GitHub et dés qu'il y a un changement, un Build est lancé dans DockerHub et l'image est mise à jour. De cette manière, à chaque nouveau Build de notre projet dans Openshit, la nouvelle image sera utilisée (2).
  •  Le deuxième Pipeline est celui de notre application ; c'est notre Job Jenkins qui sera le chef d’orchestre, car dés qu'il détecte un changement dans le Repository des sources de notre application de démo (5), il lancera un nouveau Build en commençant par un "Scale down" du Memcache DeployConfig (car on manque de CPU dans les ressources), suivi d'un "Build webapp", puis d'un déploiement "Deploy webapp". Ensuite on Tag l'image résultante du Build (dans le Registry d'Openshift) avant de vérifier le déploiement. Enfin, on termine notre Job par un "Scale Up" du Memcache DeployConfig.


Le fonctionnement de notre environnement reste simple ; à l'arrivé d'une requête HTTP du client (3), elle sera dispatchée par le Router vers le service Web et donc vers le Pod applicatif via le port 8080 (4) . L'application aura besoin de communiquer avec le serveur Memcache (6)  et devra passer par les services, de même pour communiquer avec le Pod de la base de données (7).



Voilà c'est un environnement qu'on peut utiliser parfaitement pour développer et expérimenter Openshift librement.
Personnellement, je suis tombé sous le charme de cette solution et cette compilation magnifique d'outils. J'espère que vous commencez à adorer Openshift.

NOTA : Ce billet est le fruit de mon expérience avec Openshift et de ma propre compréhension. Si vous remarquez des oublis ou bien des erreurs n’hésitez surtout pas à me le signaler via un gentil commentaire. 



¹ : La définition Wikipédia - ² : La définition RedHat :"Red Hat OpenShift is an open source container application platform based on the Kubernetes container orchestrator for enterprise application development and deployment" - ³ : Je ferai un autre Post pour les S2I


Commentaires

Posts les plus consultés de ce blog

My Openshift

Qui est là ? c'est moi ...