Les Services Template de k0rdent

thumbernail Kubernetes

Comprendre les Service Templates dans k0rdent : Une Approche Technique

Dans l’univers de la gestion de clusters Kubernetes à grande échelle, k0rdent se distingue par sa capacité à orchestrer de multiples plans de contrôle via une approche déclarative et modulaire.

Parmi ses outils avancés, les service templates jouent un rôle crucial en permettant de déployer et de gérer des services de manière standardisée et réutilisable.

Cet article technique explore en profondeur ce que sont les service templates dans k0rdent, comment ils sont structurés et comment ils s’intègrent dans l’architecture globale de la plateforme.

Dans k0rdent, l'utilisation de flux constitue la clé de voûte de l'automatisation et de l'orchestration des déploiements Kubernetes.

La plateforme s'appuie sur un flux de travail déclaratif qui commence par la définition de la configuration du cluster via des fichiers YAML, garantissant une spécification précise de l'infrastructure souhaitée.

Le k0rdent Cluster Manager (kcm) prend ensuite le relais pour déployer automatiquement le cluster, en intégrant des outils comme FluxCD et Helm afin d'installer les composants nécessaires.

Par la suite, le k0rdent State Manager (ksm) configure les politiques de sécurité et déploie les services à travers des « ServiceTemplate », assurant ainsi une cohérence et une conformité optimales sur l'ensemble de l'environnement.

Ce modèle de flux interconnecté permet non seulement une gestion centralisée et transparente, mais aussi une synchronisation continue avec les dépôts Git, facilitant l'adaptation dynamique aux évolutions des environnements multi-cloud et hybrides.

Cette approche permet à k0rdent de simplifier la complexité inhérente à la gestion des clusters tout en offrant une solution robuste et scalable pour les équipes DevOps.

1. Contexte et Objectifs de k0rdent

k0rdent se présente comme un « super control plane » conçu pour centraliser la gestion de clusters Kubernetes, que ce soit sur le cloud, sur site ou dans des environnements hybrides.

Grâce à une architecture reposant sur des Custom Resource Definitions (CRD) et sur les principes de Kubernetes Cluster API (CAPI), k0rdent offre un moyen déclaratif de décrire et de gérer à la fois l’infrastructure des clusters et les services qui y sont déployés.

Dans ce cadre, les service templates apportent une abstraction qui permet de définir et de déployer des services de manière standardisée, tout en tirant parti de la puissance des Helm charts.

2. Qu’est-ce qu’un Service Template ?

Un service template dans k0rdent est un objet Kubernetes personnalisé qui encapsule la définition d’un service à déployer. Il s’appuie principalement sur un Helm chart afin d’automatiser l’installation, la configuration et la mise à jour des composants applicatifs ou de contrôle.

2.1 Structure Technique d’un Service Template Le service template est une Custom Resource défini en YAML et se présente sous la forme d’un objet de type ServiceTemplate .

Un exemple de definition de service template :

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplate
metadata:
  name: prometheus-27.3.1
  namespace: k0rdent-prometheus
spec:
  helm:
    chartSpec:
      chart: prometheus
      version: 27.3.1
      interval: 10m0s
      sourceRef:
        kind: HelmRepository
        name: k0rdent-prometheus

Avec une custom resource HelmRepository de flux:

apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: k0rdent-prometheus
  namespace: k0rdent-prometheus
  labels:
    k0rdent.mirantis.com/managed: "true"
spec:
  interval: 10m0s
  url: https://prometheus-community.github.io/helm-charts

Dans cet exemple, plusieurs points techniques sont à noter :

  • Helm Integration : La section helm.chartSpec définit le chart à utiliser, sa version ainsi que la fréquence de réconciliation (ici toutes les 10 minutes).

  • Source de Chart : La clé sourceRef référence un objet de type HelmRepository, garantissant que le chart est récupéré depuis une source centralisée et validée.

  • Déploiement déclaratif : En définissant l’état souhaité via un CRD, k0rdent s’assure que la configuration du service reste conforme, même en cas de dérive (drift).

Au niveau de la custom resource : HelmRepository

Ce manifeste YAML définit une ressource de type HelmRepository qui fait partie du toolkit FluxCD, utilisé ici pour intégrer et gérer un dépôt de charts Helm dans un environnement GitOps consommé par k0rdent.

Voici une explication détaillée des différentes sections :

  • kind: HelmRepository Le type de ressource est un HelmRepository, ce qui signifie que Flux va interroger ce dépôt pour récupérer les charts Helm disponibles. Cela permet d’automatiser la mise à jour et le déploiement des applications via ces charts.

  • labels: Le label k0rdent.mirantis.com/managed: "true" peut être utilisé pour identifier que ce HelmRepository est géré ou supervisé par le système k0rdent. Cela facilite le filtrage et la gestion des ressources dans un environnement multi-clusters ou multi-projets.

  • interval: 10m0s Cela spécifie que Flux va vérifier le dépôt toutes les 10 minutes pour détecter d’éventuelles mises à jour des charts. Ce mécanisme de polling permet d’assurer que les dernières versions ou modifications sont prises en compte de manière automatique.

  • url: https://prometheus-community.github.io/helm-charts C’est l’URL du dépôt Helm hébergeant les charts de la communauté Prometheus. Ce dépôt contient une collection de charts pour déployer Prometheus, Grafana, Alertmanager et d’autres outils liés à la surveillance.

3. L’Extension avec le ServiceTemplateChain

Pour renforcer la gestion des versions et faciliter l’évolution des déploiements, k0rdent introduit le concept de ServiceTemplateChain.

Cet objet est également défini via une CRD et permet de lister ou de valider les templates pris en charge dans une chaîne de déploiement.

Un exemple simple de définition est le suivant

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplateChain
metadata:
  name: prometheus-27.3.1
  namespace: k0rdent-prometheus
spec:
  supportedTemplates:
  - name: prometheus-27.3.1
  - name: prometheus-26.5.1
    availableUpgrades:
        - name: prometheus-27.3.1

Le ServiceTemplateChain est une ressource personnalisée (CRD) utilisée par k0rdent pour définir quels templates de service sont autorisés dans un certain namespace et comment ils s’enchaînent pour gérer les mises à jour (upgrade paths) d’une application déployée. Autrement dit, il s’agit d’un mécanisme permettant de :

  • Déclarer les templates supportés

Dans le champ spec.supportedTemplates, on liste les noms des ServiceTemplates qui peuvent être utilisés pour déployer un service. Par exemple, dans l’exemple précédent, le template prometheus-27.3.1 est explicitement supporté.

  • Gérer les chemins de mise à jour Pour certains templates, il est possible de spécifier des upgrades. Ainsi, dans l’exemple, le template prometheus-26.5.1 dispose d’un chemin de mise à jour vers prometheus-27.3.1.

Cela permet à k0rdent de savoir qu’une version antérieure (ici la 26.5.1) peut être mise à jour vers la version 27.3.1.

4. Demo sur 2 clusters déployés sur azure

Nous allons réaliser une démonstration de la mise en œuvre des service templates en déployant deux clusters AKS à partir du template clustertemplate.k0rdent.mirantis.com/azure-aks-0-1-0.

Ce template permet de provisionner des clusters Azure Kubernetes Service (AKS) de manière déclarative et conforme aux bonnes pratiques de k0rdent.

Pour en savoir plus sur l’intégration de k0rdent avec Azure, vous pouvez consulter l’article dédié : k0rdent on Azure

Dans cette démonstration, nous allons :

  • Déployer le chart helm cert-manager sur tous les cluster à partir du catalogue d'application de k0rdent (https://catalog.k0rdent.io/) via MultiClusterService
  • Déployer buildkit-service uniquement sur le cluster de développemnt (aks-dev-001)

4.1 Pré-requis

Pour réaliser cette démonstration de service templates en déployant deux clusters AKS à partir du template clustertemplate.k0rdent.mirantis.com/azure-aks-0-1-0, voici les principaux prérequis à prévoir :

  • Accès à Azure

Un compte Azure valide, avec un abonnement actif et suffisamment de quota pour créer deux clusters AKS. Des droits suffisants (Owner ou Contributor) pour provisionner des ressources dans l’abonnement cible.

  • Identifiants Azure

Une Azure Service Principal (SP) configurée avec les rôles adéquats pour déployer des clusters AKS. Les variables d’environnement généralement requises par le provider Azure (CAPI) : AZURE_SP_APP_ID (client ID de la SP) AZURE_SP_PASSWORD (secret de la SP) AZURE_SP_TENANT_ID (tenant ID Azure) AZURE_SUBSCRIPTION_ID (ID de l’abonnement) Ces identifiants seront ensuite stockés dans un objet Credential dans k0rdent, afin d’automatiser le déploiement.

Voir le point 2. de l'article k0rdent sur Azure

  • Management Cluster k0rdent

Un cluster de management Kubernetes (pouvant être un cluster local via kind, un cluster existant, etc.) sur lequel k0rdent est déjà installé et opérationnel. Le composant k0rdent Cluster Manager (KCM) doit y être déployé pour gérer la création et la mise à jour des clusters cibles.

Voir le point 1. de l'article k0rdent sur Azure

4.2 Création de 2 cluster AKS

  • Cluster n°1
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
  name: aks-dev-001
  namespace: kcm-system
spec:
  template: azure-aks-0-1-0
  credential: azure-aks-credential
  propagateCredentials: false
  config:
    clusterLabels:
      cluster_id: "dev001"
      environment: "dev"
      csp: "microsoft-azure"
    location: "northeurope"
    machinePools:
      system:
        count: 1
        vmSize: Standard_B2s_v2
      user:
        count: 1
        vmSize: Standard_B2s_v2
EOF
clusterdeployment.k0rdent.mirantis.com/aks-dev-001 created
  • Cluster n°2
kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
  name: aks-stg-001
  namespace: kcm-system
spec:
  template: azure-aks-0-1-0
  credential: azure-aks-credential
  propagateCredentials: false
  config:
    clusterLabels:
      cluster_id: "stg001"
      environment: "stg"
      csp: "microsoft-azure"
    location: "northeurope"
    machinePools:
      system:
        count: 1
        vmSize: Standard_B2s_v2
      user:
        count: 1
        vmSize: Standard_B2s_v2
EOF
kubectl get ClusterDeployment
NAME          READY   STATUS
aks-dev-001   True    ClusterDeployment is ready
aks-stg-001   True    ClusterDeployment is ready
kubectl get managedclusters
NAME          READY   SEVERITY   REASON      MESSAGE
aks-dev-001   True               Succeeded
aks-stg-001   True               Succeeded

4.3 Créer le HelmRepository pour buildkit-service

kubectl apply -f- <<EOF
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: buildkit-service
  namespace: kcm-system
  labels:
    k0rdent.mirantis.com/managed: "true"
spec:
  provider: generic
  type: default
  url: https://andrcuns.github.io/charts
  interval: 10m0s
EOF
  • Vérification
get helmrepositories
NAME               URL                                    AGE    READY   STATUS
buildkit-service   https://andrcuns.github.io/charts      28m    True    stored artifact: revision 'sha256:...95a9db4'
catalog-core       oci://ghcr.io/k0rdent/catalog/charts   7d4h
kcm-templates      oci://ghcr.io/k0rdent/kcm/charts       7d4h

4.4 Déploiement buildkit-service

4.4.1 Préparation du service template

L'objet ServiceTemplate qui référence le chart buildkit-service. Dans cet exemple, nous utilisons la version 0.9.0

kubectl apply -f- <<EOF

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplate
metadata:
  name: buildkit-service-0-9-0
  namespace: kcm-system
spec:
  helm:
    chartSpec:
      chart: buildkit-service
      version: 0.9.0
      interval: 10m0s
      sourceRef:
        kind: HelmRepository
        name: buildkit-service

4.4.2 Préparation du service template chain

L’objet ServiceTemplateChain permet de définir la ou les versions disponibles et, éventuellement, les chemins de mise à niveau. Dans cet exemple, nous définissons une chaîne simple contenant uniquement le template de buildkit-service créé :

kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplateChain
metadata:
  name: buildkit-service-chain
  namespace: kcm-system

spec:
  supportedTemplates:
    - name: buildkit-service-0-9-0
      # Vous pouvez ajouter ici d'autres templates et définir des availableUpgrades si vous prévoyez des mises à niveau
EOF
  • Vérifications
kubectl get ServiceTemplate buildkit-service-0-9-0 
NAME                      VALID
buildkit-service-0-9-0    true
kubectl get ServiceTemplateChain buildkit-service-ServiceTemplateChain
NAME                     AGE
buildkit-service-chain   7s

4.4.3 Déploiement sur le cluster de dev

kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
  name: aks-dev-001
  namespace: kcm-system
spec:
  template: azure-aks-0-1-0
  credential: azure-aks-credential
  propagateCredentials: false
  config:
    clusterLabels:
      cluster_id: "dev001"
      environment: "dev"
      csp: "microsoft-azure"
    location: "northeurope"
    machinePools:
      system:
        count: 1
        vmSize: Standard_B2s_v2
      user:
        count: 1
        vmSize: Standard_B2s_v2
  serviceSpec:
    services:
      - template: buildkit-service-0-9-0
        name: buildkit-service
        namespace: buildkit-service
    priority: 100
EOF
  • Vérifications

Namespace buildkit-service créé sur le cluster de dev

Application buildkit-service créé sur le cluster de dev

4.5 Déploiement de cert-manager via MultiClusterService

4.5.1 Rappel

kubectl get servicetemplate
NAME                      VALID
buildkit-service-0-9-0    true
cert-manager-1-16-2       true on va déployer ce chart
dex-0-19-1                true
external-secrets-0-11-0   true
ingress-nginx-4-11-0      true
ingress-nginx-4-11-3      true
kyverno-3-2-6             true
velero-8-1-0              true

4.5.2 Déployement du MultiClusterService

kubectl apply -f- <<EOF
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: MultiClusterService
metadata:
  name: global-cert-manager
spec:
  clusterSelector:
    matchLabels:
      csp: "microsoft-azure"
  serviceSpec:
    services:
      - name: cert-manager
        namespace: cert-manager
        template: cert-manager-1-16-2
        values: |
          installCRDs: true
    priority: 300 
EOF

Dans cet exemple, le champ clusterSelector sélectionne les clusters qui possèdent le label csp: microsoft-azure. Le serviceSpec définit le service à déployer en se référant au ServiceTemplate nommé cert-manager-1-16-2 (préalablement créé dans le namespace approprié). La priorité (ici à 300) permet de gérer les éventuels conflits en cas de déploiement de plusieurs sources sur le même cluster.

le bloc YAML défini dans values permet de configurer l'installation des CRD et l'image utilisée par cert-manager. Vous devez adapter ces valeurs à la structure attendue par le chart Helm que vous utilisez. Vous pouvez également utiliser le champ valuesFrom pour référencer un ConfigMap ou un Secret contenant vos valeurs.

kubectl get multiclusterservice global-cert-manager

NAME                  AGE
global-cert-manager   19s
  • Vérifications

4.6 Exemples d'utilisation avancées

4.6.1 Utilisation de valeurs externes via aluesFrom

Dans cet exemple, au lieu d’inscrire directement les paramètres dans le manifeste, on utilise valuesFrom pour récupérer les valeurs depuis un ConfigMap externe :

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: MultiClusterService
metadata:
  name: global-external-service
spec:
  clusterSelector:
    matchLabels:
      environment: production
  serviceSpec:
    services:
      - name: my-external-service
        namespace: external-namespace
        template: external-service-1-0-0
        valuesFrom:
          configMapKeyRef:
            name: external-service-values
            key: values.yaml
    priority: 300

Ce mécanisme est particulièrement utile lorsque la configuration varie selon l’environnement ou doit être centralisée dans un ConfigMap (ou Secret).

4.6.2 Gestion des mises à jour avec Service Template Chain

Cet exemple montre deux versions d’un service et leur chaîne d’upgrade. Le ServiceTemplateChain permet de définir un chemin de mise à niveau entre la version 1.0.0 et 1.1.0 du service :

# ServiceTemplate pour la version 1.0.0
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplate
metadata:
  name: my-service-1-0-0
  namespace: my-app-namespace
spec:
  helm:
    chartSpec:
      chart: my-service
      version: 1.0.0
      interval: 10m0s
      sourceRef:
        kind: HelmRepository
        name: my-charts
---
# ServiceTemplate pour la version 1.1.0
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplate
metadata:
  name: my-service-1-1-0
  namespace: my-app-namespace
spec:
  helm:
    chartSpec:
      chart: my-service
      version: 1.1.0
      interval: 10m0s
      sourceRef:
        kind: HelmRepository
        name: my-charts
---
# Chaîne d'upgrade entre les deux versions
apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ServiceTemplateChain
metadata:
  name: my-service-chain
  namespace: my-app-namespace
spec:
  supportedTemplates:
    - name: my-service-1-1-0
    - name: my-service-1-0-0
      availableUpgrades:
        - name: my-service-1-1-0

Ainsi, k0rdent saura qu’une mise à niveau de la version 1.0.0 vers 1.1.0 est disponible et pourra gérer ce processus de manière automatisée.

4.6.3 Insertion dynamique de valeurs via templating

La section values d'un ClusterDeployment injecte dynamiquement des informations spécifiques du cluster (récupérées via Sveltos) dans les valeurs du chart :

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: ClusterDeployment
metadata:
  name: advanced-cluster
  namespace: kcm-system
spec:
  config:
    clusterLabels:
      environment: production
  serviceSpec:
    services:
      - name: my-app
        namespace: my-app-namespace
        template: my-app-1-0-0
        values: |
          app:
            controlPlaneHost: {{ .Cluster.spec.controlPlaneEndpoint.host }}
            controlPlanePort: "{{ .Cluster.spec.controlPlaneEndpoint.port }}"
            replicaCount: 3

Ici, les variables {{ .Cluster.spec.controlPlaneEndpoint.host }} et {{ .Cluster.spec.controlPlaneEndpoint.port }} seront remplacées par les informations du point d’accès du cluster lors du déploiement du service.

Dans cet exemple, nous déployons un service ingress-nginx sur des clusters ciblés par le label app: web.

On utilise le templating pour injecter dynamiquement une valeur extraite d'une annotation du cluster (par exemple, une adresse IP externe) dans les valeurs du chart

apiVersion: k0rdent.mirantis.com/v1alpha1
kind: MultiClusterService
metadata:
  name: global-ingress-with-dynamic-values
spec:
  clusterSelector:
    matchLabels:
      app: web
  serviceSpec:
    services:
      - name: ingress-nginx
        namespace: ingress-nginx
        template: ingress-nginx-4-11-3
        values: |
          controller:
            replicaCount: 2
            service:
              externalTrafficPolicy: Local
              loadBalancerIP: {{ .Cluster.metadata.annotations.external-ip }}
    priority: 350

Ici, la syntaxe {{ .Cluster.metadata.annotations.external-ip }} permet de récupérer dynamiquement l’IP définie dans les annotations du cluster pour la passer au chart d’ingress-nginx

5 Conclusion

L'approche proposée par k0rdent, via l'utilisation des Services Template, Service Template Chain et MultiClusterService, offre une solution puissante pour simplifier la gestion des applications dans des environnements multi-clusters.

Ces outils permettent de définir des déploiements standardisés et versionnés à l'aide de charts Helm, tout en facilitant les mises à jour et l'extension des services sur l'ensemble des clusters ciblés.

En centralisant le contrôle et en automatisant le déploiement des services critiques, cette approche réduit non seulement le risque d'erreurs manuelles, mais améliore également l'agilité et la résilience de l'infrastructure Kubernetes.

Ainsi, en adoptant ces concepts, les équipes DevOps disposent d'un véritable levier pour optimiser la gestion et la scalabilité de leurs environnements complexes.

Découvrez les technologies d'alter way