Aller au contenu

Connecter un cluster Kubernetes

Un cluster Kubernetes entier peut constituer un seul serveur dans le portail. Vous installez deux composants dans le namespace scolah-system, chacun avec son propre chart Helm :

  • L’agent (scolah-agent) se connecte à la plateforme, télécharge et vérifie chaque bundle d’application, et note ce qui doit tourner sur le cluster. Il ne démarre lui-même aucune charge de travail.
  • L’opérateur (scolah-operator) fait le travail. Il vérifie de nouveau lui-même la signature de chaque bundle, puis crée les charges de travail, les volumes et les routes web de l’application.

Les deux partagent un volume, scolah-agent-bundles. L’agent y dépose les bundles vérifiés et l’opérateur les y lit. Un cluster exécute exactement un agent et un opérateur.

Vous devez être Administrateur de l’organisation pour enregistrer le serveur, et disposer de droits d’administration sur le cluster pour installer les charts.

Cluster

  • Kubernetes avec Helm 3 et kubectl. Nous testons sur Kubernetes 1.37. Les charts n’imposent pas de version minimale.
  • Une StorageClass par défaut. Les charts créent deux volumes : un volume de 10 Gio pour les bundles et un volume de 1 Gio pour l’identité de l’agent. Les applications créent leurs propres volumes pour leurs données. Aucun d’eux ne nomme de classe de stockage, c’est donc celle par défaut du cluster qui est utilisée.
  • Sur un cluster de plusieurs nœuds, le volume des bundles est ReadWriteOnce par défaut, donc l’agent et l’opérateur doivent tourner sur le même nœud. Pour qu’ils puissent tourner sur des nœuds différents, utilisez une classe de stockage qui prend en charge ReadWriteMany et ajoutez --set bundles.accessMode=ReadWriteMany --set bundles.storageClass=<class> à la commande d’installation de l’agent.

Trafic web

  • Un contrôleur Ingress, comme ingress-nginx, si les utilisateurs accèdent aux installations via un domaine. L’opérateur crée un Ingress pour chaque domaine. Vous n’en avez pas besoin pour connecter le cluster ni pour déployer des applications.
  • cert-manager et un ClusterIssuer si vous voulez Let’s Encrypt (HTTPS automatique) sur un cluster. L’opérateur ne demande pas de certificats lui-même. Il les demande à votre émetteur.

Si votre cluster utilise plutôt une Gateway (Gateway API de Kubernetes), les installations peuvent y rattacher leurs routes. Choisissez Terminé par votre Gateway (Gateway API Kubernetes) comme mode TLS du domaine (voir Domaines et HTTPS).

Réseau

  • HTTPS sortant depuis le pod de l’agent vers l’adresse de la plateforme indiquée dans la commande d’installation.
  • Accès sortant depuis les nœuds vers les registres de conteneurs d’où proviennent les images des applications. Le cluster télécharge les images sur chaque nœud, pas via l’agent.
  • Aucun port entrant pour connecter le cluster ou déployer des applications. Pour les domaines, votre contrôleur Ingress doit être joignable sur les ports 80 et 443.
  1. Allez dans Serveurs et cliquez sur Ajouter un serveur.

  2. Donnez-lui un Nom facile à reconnaître, comme cluster-nairobi.

  3. Choisissez Kubernetes comme Environnement. Il n’y a pas de système d’exploitation à choisir.

  4. Vérifiez les paramètres du cluster. Le portail les intègre à la commande d’installation :

    • Classe d’ingress : la classe de votre contrôleur Ingress. Par défaut nginx.
    • Namespace du contrôleur d’ingress : le namespace dans lequel tourne votre contrôleur Ingress. Par défaut ingress-nginx. Le namespace de chaque installation bloque le trafic provenant des autres namespaces, et ce paramètre laisse passer votre contrôleur Ingress.
    • Service du contrôleur d’ingress : le Service de votre contrôleur Ingress. Par défaut ingress-nginx-controller. L’agent remonte l’adresse de load balancer de ce Service comme adresse publique du cluster, pour vos domaines.
    • Adresse publique (facultatif) : l’IP ou le nom d’hôte où le contrôleur Ingress du cluster est joignable depuis l’extérieur, comme 203.0.113.10. Renseignez-la lorsque l’adresse du load balancer n’est pas celle qu’atteignent les utilisateurs, par exemple derrière un NAT. Elle remplace l’adresse détectée.
    • Émetteur de certificats (facultatif) : le ClusterIssuer cert-manager pour les domaines Let’s Encrypt (HTTPS automatique), comme letsencrypt. Sans émetteur, ces domaines n’obtiennent pas de route.

    Les noms peuvent contenir des lettres minuscules, des chiffres, - et ..

  5. Cliquez sur Créer.

Ajouter un serveur, avec Kubernetes sélectionné
Ajouter un serveur, avec Kubernetes sélectionné

Le portail affiche un Jeton d’enrôlement et une Commande d’installation.

La commande d'installation pour un cluster Kubernetes
La commande d'installation pour un cluster Kubernetes

La commande d’installation installe les deux charts en une seule fois. Elle ressemble à ceci :

Terminal window
helm install scolah-agent oci://ghcr.io/engineeringpurple/charts/scolah-agent \
--namespace scolah-system --create-namespace \
--set platformUrl=https://… --set enrollToken=spa_… \
--set ingressService=ingress-nginx/ingress-nginx-controller \
&& helm install scolah-operator oci://ghcr.io/engineeringpurple/charts/scolah-operator \
--namespace scolah-system \
--set bundles.pvc=scolah-agent-bundles \
--set platformReleaseKey=… \
--set ingressClassName=nginx \
--set ingressControllerNamespace=ingress-nginx
  • La release de l’agent crée le namespace scolah-system, l’agent lui-même et le volume partagé scolah-agent-bundles. Le jeton n’est utilisé qu’une fois, lors de l’enrôlement de l’agent.
  • La release de l’opérateur va dans le même namespace. bundles.pvc lui indique le volume créé par la release de l’agent.
  • platformReleaseKey est la clé publique de signature de la plateforme. L’opérateur vérifie chaque bundle d’application avec cette clé avant de le déployer.
  • ingressService (sur l’agent) ainsi que ingressClassName et ingressControllerNamespace (sur l’opérateur) proviennent des paramètres de cluster que vous avez choisis. Une Adresse publique ajoute --set publicAddress=… à l’agent, et un Émetteur de certificats ajoute --set certManager.issuerRef.name=… à l’opérateur.

Si le cluster n’a pas encore cert-manager, ajoutez --set certManager.install=true à la partie opérateur pour l’installer avec l’opérateur. Vous devez tout de même créer le ClusterIssuer vous-même.

Pour modifier les paramètres du cluster plus tard, ouvrez le serveur et cliquez sur Régénérer le jeton : les mêmes paramètres s’affichent au-dessus d’une nouvelle commande.

En moins d’une minute, l’état du serveur dans le portail passe de En attente à Connecté, et la version de l’agent ainsi que les ressources du cluster apparaissent.

Un cluster Kubernetes connecté
Un cluster Kubernetes connecté

Sinon, vérifiez les pods et le journal de l’agent :

Terminal window
kubectl -n scolah-system get pods
kubectl -n scolah-system logs statefulset/scolah-agent

Un agent qui fonctionne journalise enrolled, puis agent ready. Au démarrage, l’opérateur journalise une ligne PREFLIGHT pour chaque point qu’il ne peut pas corriger lui-même, comme une clé de release manquante, l’absence de cert-manager ou l’absence d’identifiant de registre. Ces lignes ne l’empêchent pas de démarrer, mais elles vous indiquent ce qui échouera plus tard :

Terminal window
kubectl -n scolah-system logs deploy/scolah-operator | grep PREFLIGHT

L’agent conserve son identité sur son propre volume, il n’a donc plus besoin du jeton. Une mise à niveau avec helm upgrade n’en a pas besoin non plus.

Créez des installations sur le cluster de la même manière que sur un serveur Docker : choisissez le cluster dans la liste Serveur de l’assistant. Pour chaque installation, le cluster reçoit :

  • Un namespace nommé d’après l’application et le début de l’identifiant de l’installation, comme sample-nginx-21333d29. Tout ce que l’installation exécute s’y trouve.

  • Une ressource Installation, nommée d’après l’identifiant de l’installation. Elle montre ce que fait l’opérateur :

    Terminal window
    kubectl get installations
  • Un Secret <app>-env contenant les paramètres et les mots de passe de l’application. Seul l’agent peut déchiffrer ce qu’envoie la plateforme, c’est donc lui qui écrit ce Secret.

  • Des NetworkPolicies qui bloquent le trafic provenant des autres namespaces, sauf celui de votre contrôleur Ingress.

  • Pour les applications qui utilisent les images privées de Scolah (Scolah Compass, OpenEWS), un pull secret scolah-registry-auth contenant l’identifiant de registre de votre organisation. L’agent l’écrit et les pods l’utilisent automatiquement, vous n’avez donc pas à configurer vous-même d’identifiant de registre sur le cluster.

  • Lorsque l’installation est protégée par la reprise après sinistre, un pull secret scolah-dr-agent-pull : une copie des imagePullSecrets définis dans le chart de l’agent, pour que les pods de reprise puissent télécharger l’image de l’agent depuis un registre privé. Voir Registres privés sur un cluster.

  • Les charges de travail, services et volumes propres à l’application.

Une installation tournant sur un cluster Kubernetes
Une installation tournant sur un cluster Kubernetes

Une installation sur un cluster n’a aucune adresse tant que vous n’ajoutez pas de domaine. Sur un serveur Docker, le portail affiche l’adresse IP du serveur et un port. Un cluster n’a ni l’un ni l’autre, la zone Accès et domaines reste donc vide.

Les connexions fonctionnent aussi sur un cluster. Les deux installations doivent se trouver sur le même cluster.

Ajoutez un domaine depuis l’onglet Domaines de l’installation, comme décrit dans Domaines et HTTPS. Une fois le domaine vérifié, l’opérateur crée un Ingress nommé scolah-route-<site> dans le namespace de l’installation, et le supprime lorsque vous supprimez le domaine.

Le DNS des domaines d’un cluster pointe vers l’endroit où votre contrôleur Ingress est joignable depuis l’extérieur. L’agent remonte cette adresse au portail :

  • Si vous avez défini une Adresse publique (publicAddress sur la release Helm de l’agent), c’est cette adresse qui est utilisée.
  • Sinon, l’agent lit l’IP externe ou le nom d’hôte du Service LoadBalancer de votre contrôleur Ingress.

Le portail vous indique ensuite quel enregistrement créer : un enregistrement A lorsque l’adresse est une IP, ou un CNAME lorsqu’il s’agit d’un nom d’hôte (comme c’est souvent le cas des load balancers cloud). Un Sous-domaine Scolah crée cet enregistrement pour vous.

Si le cluster n’a pas encore d’adresse publique, par exemple parce que son contrôleur Ingress n’est pas exposé via un load balancer, l’onglet Domaines l’indique, et vous ne pouvez pas ajouter de sous-domaine Scolah tant qu’il n’en a pas. Exposez le contrôleur Ingress via un Service LoadBalancer, ou définissez publicAddress sur la release Helm de l’agent.

Mode TLS Sur un cluster
Let’s Encrypt (HTTPS automatique) cert-manager obtient le certificat auprès de l’émetteur défini dans certManager.issuerRef.name.
Apporter votre propre certificat Cliquez sur Ajouter un certificat à côté du domaine et collez le certificat et la clé. L’agent les stocke dans un Secret scolah-tls-<site>. Le domaine n’a pas de route tant que le certificat n’est pas présent.
Sans TLS (derrière un proxy externe) Le site est servi en HTTP simple.
Terminé par votre Gateway (Gateway API Kubernetes) Uniquement sur les clusters. La route se rattache à une Gateway que vous exploitez déjà, qui termine le HTTPS. Vous pouvez indiquer le namespace, le nom et le listener de la Gateway ; laissez-les vides pour utiliser la Gateway par défaut de l’opérateur. Faites pointer le nom d’hôte vers l’adresse externe de votre Gateway.

Chaque domaine de l’onglet Domaines affiche Routé une fois que le cluster le sert, ou Non routé avec la raison, par exemple un certificat ou un émetteur manquant. L’état se met à jour sans nouvelle application : l’opérateur revérifie un domaine dès que son Secret de certificat est ajouté ou supprimé, ou que sa route est modifiée ou supprimée, et l’agent signale le changement lors de sa prochaine interrogation, généralement en moins de 30 secondes. Cela nécessite la dernière version de l’agent. Les agents plus anciens ne mettent l’état à jour qu’à chaque application de l’installation.

Supprimez une installation dans le portail avec Supprimer, comme d’habitude. Sur un cluster, l’opérateur retire les charges de travail puis supprime le namespace de l’installation, y compris ses volumes et ses données. Il supprime ensuite la ressource Installation.

Ne supprimez pas une Installation avec kubectl. La plateforme fait foi : l’agent la réécrit et l’opérateur redémarre l’application sur ses volumes conservés.

  1. Supprimez toutes les installations du cluster dans le portail. Le portail ne supprime pas un serveur qui a encore des installations.

  2. Ouvrez le serveur et cliquez sur Supprimer.

  3. Désinstallez les deux charts :

    Terminal window
    helm uninstall scolah-operator --namespace scolah-system
    helm uninstall scolah-agent --namespace scolah-system

Helm laisse deux choses derrière lui : les définitions de ressources Installation et Link, et le volume d’identité de l’agent (state-scolah-agent-0). Supprimez-les vous-même si vous ne reconnecterez pas le cluster.

Un cluster peut participer à la reprise après sinistre des deux côtés. Ses installations peuvent être protégées et, une fois marqué éligible à la reprise, il peut héberger des copies de secours, pour des installations sur un serveur Docker ou sur un autre cluster. Dès qu’un cluster est concerné, il vous faut un magasin d’artefacts que les deux serveurs peuvent joindre. Voir Clusters Kubernetes pour le fonctionnement des sauvegardes, des tests, du basculement et du retour au principal sur un cluster.

Au niveau Continu, un cluster peut être le serveur principal ou le serveur de reprise pour des bases de données PostgreSQL et MariaDB, associé à un serveur Docker ou à un autre cluster. Des deux côtés, il a besoin de l’agent 0.0.2 ou plus récent, d’une StorageClass par défaut, et de l’image de l’agent lui-même téléchargeable : si elle est dans un registre privé, définissez imagePullSecrets dans le chart de l’agent, et l’agent les copie dans le namespace de chaque installation pour les pods de reprise. Comme serveur principal, il a aussi besoin de place pour le volume de l’expéditeur ; pour PostgreSQL, d’un compte de base de données superutilisateur, et l’agent ajoute une ligne marquée à pg_hba.conf sans redémarrer la base de données ; pour MariaDB, de la journalisation binaire au format par ligne et des droits de réplication, sans aucune modification de la base de données. Les deux côtés doivent avoir la même architecture de processeur : sur un cluster principal, la plateforme vérifie le nœud où tourne chaque base de données, tandis que sur un cluster de reprise qui mélange les architectures, elle ne peut pas connaître à l’avance le nœud de la base de secours ; fixez donc la base de secours sur l’architecture du serveur principal. Comme serveur de reprise, une base de secours PostgreSQL a besoin de ses données sur un volume qui n’est pas ReadWriteOncePod et est brièvement arrêtée pendant son amorçage à partir d’une base, tandis qu’une base de secours MariaDB reste en marche tout du long. Voir Niveau Continu avec un serveur principal sur un cluster et Niveau Continu avec le serveur de reprise sur un cluster pour les listes complètes.