Créer une usine à clusters kubernetes - partie 2

thumbernail kubernetes

1. principe

Retour à la partie partie 1

Nous allons donc utiliser plusieurs composants

  • Helm
  • ArgoCD
  • des Applications argoCD
  • des Application Set argoCD
  • des kustomizations

Pour les charts Helm :

  • Création d'un chart helm qui nous permettra de déployer les CR Cluster et VCluster de manière dynamique.

Pour ArgoCD : - Création d'une Application qui va déployer un ApplicationSet - Création d'un ApplicationtSet (Application template d'argoCD) qui nous permettra de déployer les clusters à partir de fichiers de paramètres stockés dans un repository git.

2. Comment industrialiser tout ca ?

2.1 Préparation d'un chart helm

2.1.1 Création d'un chart helm

Nous allons utiliser Helm :

Nous allons créer un chart avec la commande create

 helm create usine-k8s
Creating usine-k8s

Cette commande va créer un chart helm qui s'appelle usine-k8s qui permet de déployer une application simple. Nous n'allons pas garder les fichiers templates et utiliser nos propres templates.

La structure du répertoire est:

 tree .
.
└── usine-k8s
├──Chart.yaml
├──charts
├──templates
│  ├──NOTES.txt
│  ├──_helpers.tpl
│  ├──deployment.yaml
│  ├──hpa.yaml
│  ├──ingress.yaml
│  ├──service.yaml
│  ├──serviceaccount.yaml
│  └──tests
│  └──test-connection.yaml
└──values.yaml

5 directories, 10 files
  • Chart.yaml : Le fichier contient la description du chart
  • charts : Les répertoires peuvent contenir d'autres charts (sous-chart).
  • templates/:le répertoire est utilisé pour placer les fichiers templates. Lorsque helm est exécuté, il construira à partir de tous les fichiers yaml de ce - répertoire les manifestes qui seront déployés (templating)
  • tests: permet de tester le chart avec un manifeste que sera exécuté via la command `helm test``
  • values.yaml : Ce fichier contient les valeurs par défaut du chart

2.1.2 Ménage

Nous allons supprimer tout ce qui ne va pas nous servir.

rm -rf usine-k8s/templates/*

 tree .
.
└── usine-k8s
├──Chart.yaml
├──charts
├──templates
└──values.yaml

2.1.3 Création des templates de ressources Cluster et VCluster

Ce que nous allons mettre comme variables

  • nom du cluster --> cluster_name --> {{ .Values.cluster_name }}
  • le fqdn du cluster dans les valeur du syncer --> {{ .Values.cluster_fqdn }}
  • la version de kubernetes que nous voulons {{ .Values.k8s_version }}
cat << EOF > usine-k8s/templates/cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: {{ .Values.cluster_name }}
spec:
  controlPlaneRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
    kind: VCluster
    name: {{ .Values.cluster_name }}
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
    kind: VCluster
    name: {{ .Values.cluster_name }}
EOF

cat << EOF > usine-k8s/templates/vcluster.yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: VCluster
metadata:
  name: {{ .Values.cluster_name }}
spec:
  controlPlaneEndpoint:
    host: ""
    port: 0
  helmRelease:
   chart:
    name: vcluster-k8s
    repo: https://charts.loft.sh
    version: 0.13.0
    values: |
      syncer:
        extraArgs:
        - --tls-san={{ .Values.cluster_fqdn }}
        - --out-kube-config-server=https://{{ .Values.cluster_fqdn }}
      ingress:
        enabled: true
        pathType: ImplementationSpecific
        ingressClassName: nginx
        host: {{ .Values.cluster_fqdn }}
        annotations:
          nginx.ingress.kubernetes.io/backend-protocol: HTTPS
          nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
          nginx.ingress.kubernetes.io/ssl-redirect: 'true'
          cert-manager.io/cluster-issuer: letsencrypt
  kubernetesVersion: {{ .Values.k8s_version }}
EOF

2.1.3 fichier de values

Editez le fichier values.yaml Supprimeztoutesleslignesetajoutez

# Default values for usine-k8s.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

cluster_name: cluster-name
cluster_fqdn: cluster-name.vclusters.caas.fr
k8s_version: 1.27.6

2.1.4 Test de génération

Nous allons utiliser la commande helm template pour générer les manifestes qui seront appliqués.

helm template usine-k8s usine-k8s

Vous devriez avoir ce résultat :

---
# Source: usine-k8s/templates/cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: cluster-name
spec:
  controlPlaneRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
    kind: VCluster
    name: cluster-name
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
    kind: VCluster
    name: cluster-name
---
# Source: usine-k8s/templates/vcluster.yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: VCluster
metadata:
  name: cluster-name
spec:
  controlPlaneEndpoint:
    host: ""
    port: 0
helmRelease:
  chart:
  name: vcluster-k8s
  repo: https://charts.loft.sh
  version: 0.13.0
  values: |
    syncer:
      extraArgs:
      - --tls-san=cluster-name.vclusters.caas.fr
      - --out-kube-config-server=https://cluster-name.vclusters.caas.fr
    ingress:
      enabled: true
      pathType: ImplementationSpecific
      ingressClassName: nginx
      host: cluster-name.vclusters.caas.fr
      annotations:
        nginx.ingress.kubernetes.io/backend-protocol: HTTPS
        nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
        nginx.ingress.kubernetes.io/ssl-redirect: 'true'
        cert-manager.io/cluster-issuer: letsencrypt
kubernetesVersion: 1.27.6

Vous pouvez aussi faire ce test et vérifier que les valeurs sont bien modifiées

helm template usine-k8s usine-k8s --set cluster_name=test-k8s

Notre template est pret!

2.2 Répositories git

Nous allons créer 2 repos

  • Un pour notre chart helm et l'applicationset (Pour simplifier, nous déploierons dans argocd le chart à l'aide des fichiers du chart d'un repo et non un chart au format oci dans une registry)
  • Un pour gérer les clusters que l'on veut déployer ou supprimer; Ca sera en fait des fichiers contenenant nos trois variables. celles-ci seront utilsées pour créer les clusters

Pour le chart (dans le répertoire usine-k8s)

git init
git add.
git commit -m "init"
git branch -M main
git remote add origin https://github.com/herveleclerc/usine-k8s.git
git push -u origin main

Vous trouverez les repo d'exemple ici:

2.3 ArgoCD

2.3.1 Installation

Suivez le tuto disponible ici : getting Started Si vous n'avez pas argoCD de déployé

2.3.2 Déclaration des repos dans argoCD

Déclarez les repos qu'on va utiliser dans les settings. (j'utilise dans le cadre de ce billet le projet default)

2.3.4 Paramètres des clusters

Dans le repo usine-k8s-params

Créez une arborescence de ce type

 tree -d .
.
└── infrastructure
└──clusters
└──cluster-dev0

Dans le répertoire cluster-dev0

créer un fichier params.yaml

avec ce contenu :

cluster_name: cluster-dev0
cluster_fqdn: cluster-dev0.vclusters.caas.fr
k8s_version: 1.27.6

Vous devriez avoir une arborescence équivalente à :

 tree .
.
└── infrastructure
└──clusters
└──cluster-dev0
└──params.yaml

Lorsque vous souhaitez ajouter un cluster il suffira de créer un nouveau répertoire avec un fichier params.yaml et de le posser sur le repo git

2.3.4 Création des ressources argocd

Dans le repo usine-k8s

Créer 3 répertoires

  • applications
  • applicationsets
 tree -d . -L 1
.
├── applications
├── applicationsets
└── chart

2.3.4.1Répertoire chart

Note: Vous devrez adapter les url de votre repo

Dans le répertoire chart mettez votre chart helm précédemment créé

2.3.4.1 Répertoire applications

Mettre les fichiers suivants :

cat << EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- usine-k8s-root-application.yaml
EOF

et

cat << EOF > usine-k8s-root-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: usine-k8s-root
  namespace: argocd
spec:
  destination:
    name: ''
    namespace: argocd
    server: 'https://kubernetes.default.svc'
  source:
    path: applicationsets
    repoURL: 'https://github.com/herveleclerc/usine-k8s.git'
    targetRevision: HEAD
  sources: []
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
EOF

On va déployer une application qui va déployer et maintenir un applicationSet qui déploiera les clusters

On utilise kustomize par commodité

2.3.4.1 Répertoire applicationsets

Mettre le fichier suivant :

cat << EOF > usine-k8s-application-set.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: usine-k8s
spec:
  goTemplate: true
  generators:
  - git:
      repoURL: https://github.com/herveleclerc/usine-k8s-params.git
      revision: HEAD
      files:
      - path: "infrastructure/clusters/**/params.yaml"
  template:
    metadata:
      name: '{{.cluster_name}}'
    spec:
      destination:
        name: ''
        namespace: '{{.cluster_name}}'
        server: 'https://kubernetes.default.svc'
      source:
        path: chart
        repoURL: 'https://github.com/herveleclerc/usine-k8s.git'
        targetRevision: HEAD
        helm:
          parameters:
          - name: cluster_name
            value: '{{.cluster_name}}'
          - name: cluster_fqdn
            value: '{{.cluster_fqdn}}'
          - name: 'k8s_version'
            value: '{{.k8s_version}}'
      sources: []
      project: default
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true
EOF

Cet applicationset va déployer le chart helm avec les paramètres stocké dans un autre repo.

Note : Remarquez les wildcards pour les paramètres on aura une boucle sur ces paramètres

Vous devriez avoir une arborescence identique à cela :

 tree .
.
├── applications
│   ├── kustomization.yaml
│   └── usine-k8s-root-application.yaml
├── applicationsets
│   └── usine-k8s-application-set.yaml
└── chart
├──Chart.yaml
├──charts
├──templates
│  ├──cluster.yaml
│  └──vcluster.yaml
└──values.yaml

Commit et push les modifications sur le repo

2.3.5 Déploiement

Aller dans le répertoire applications lancez la commande :

kubectl -k .

L'application root va être déployée elle va elle même déployer l'applicationset

En cliquant sur l'application root :

On voit qu'elle a déployé un applicationset qui déploie des applications

En cliquant sur l'application, on voit les différentes CR (custom resource) de notre cluster

2.3.6 Ajout / modification / suppression de cluster

Il suffit d'appliquer des modification dans le repo usine-k8s-params et de les pousser sur le repo

exemple:  créer un nouveau cluster

 tree .
.
└── infrastructure
└──clusters
├──cluster-dev0
│  └──params.yaml
└──cluster-dev1
└──params.yaml

Cette modification va créer automatiquement un nouveau cluster quand les informations seront "commit"

ArgoCD synchronise les repo et déploie le nouveau cluster

Le temps que le cluster soit provisionné l'appli est en "degraded". Et passe en déployé

Voila nous avons une usine a cluster kubernetes !

3. Accès au cluster déployé

Le cluster est déployer dans un namespace qui porte le nom du cluster_name qu'on a mis dans les fichier de paramètres; Pour générer le kubeconfig rien de plus simple

# Exemple

export CLUSTER_NAME="cluster-dev0"

kubectl get secret vc-${CLUSTER_NAME}  -n ${CLUSTER_NAME}  --template={{.data.config}} | base64 -d > kubeconfig.yaml

Vous pouvez tester ainsi :

 KUBECONFIG=./kubeconfig.yaml k get po -A
NAMESPACE        NAME                                    READY   STATUS    RESTARTS   AGE
kube-system      coredns-66ffcc6b58-4lhlt                1/1     Running   0          97s
projectsveltos   sveltos-agent-manager-9dcdbdbd4-pfvhd   2/2     Running   0          97s

Dans la partie 3 de ce billet nous allons voir comment automatiser les déploiements de composants communs à tous les clusters temporaires.

Suite à la partie 3

Découvrez les technologies d'alter way