Configurer un cluster avec Cert-manager, ingress-nginx, external DNS pour pouvoir héberger une application sur Kubernetes

Configurer un cluster avec Cert-manager, ingress-nginx, external DNS pour pouvoir héberger une application sur Kubernetes

Publié le


Do not index
Do not index
Primary Keyword
Lié à Analyse sémantique (Articles liés) 1
Lié à Analyse sémantique (Articles liés)
Statut rédaction
A optimiser SEO
Lié à Analyse sémantique (Articles liés) 2

Introduction

Dans ce tutoriel, nous allons commencer par créer un cluster Kubernetes sur Scaleway avec Terraform puis nous verrons comment configurer et installer cert-manager, ingress-nginx et external DNS pour pouvoir héberger une application sur Kubernetes.
Terraform ayant des limitations dans la création de modules avec des providers dynamique, nous allons donc séparer dans deux dossiers la partie création de cluster et la partie configuration du cluster.

Présentation ingress-nginx

L'ingress Nginx Kubernetes est un contrôleur Ingress qui permet aux utilisateurs de déployer facilement des applications sur un cluster Kubernetes. Il permet aux utilisateurs de configurer des règles de routage et des mappings de ports pour leurs applications, et donne aux utilisateurs un point d'entrée unique pour leurs applications. En outre, ingress-nginx est configurable et extensible, ce qui permet aux utilisateurs d'ajouter des fonctionnalités supplémentaires à leur cluster Kubernetes.

Présentation External DNS

External DNS est un outil qui vous permet de configurer automatiquement vos enregistrements DNS pour vos services Kubernetes. Il est capable de configurer des enregistrements DNS pour des services telles que Load Balancers, Ingresses et Services externes. Cela permet à votre application d'être accessible depuis l'extérieur en utilisant un nom de domaine.

Présentation cert-manager

Cert-Manager est un outil qui vous permet de gérer facilement les certificats SSL pour vos applications sur Kubernetes. Il peut automatiquement gérer la demande et le renouvellement des certificats, et vous donne un moyen simple de configurer une variété de stratégies pour la gestion des certificats. Cert-Manager est un outil utile pour les développeurs qui souhaitent mettre en œuvre un certificat SSL sur leur application Kubernetes.

Prérequis pour créer et configurer le cluster Kubernetes

Créer une paire de clés d’accès Scaleway pour permettre à Terraform de créer les ressources, puis l’exporter dans en variable d’environnement comme ci-dessous :
export SCW_ACCESS_KEY="my-access-key"
export SCW_SECRET_KEY="my-secret-key"

Création du cluster Kubernetes sur Scaleway

Créez un dossier scaleway_cluster puis y ajouter un fichier nommé cluster.tf qui ressemble à la configuration ci dessous :
# Plus d'option de configuration du cluster ici : https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/k8s_cluster
resource "scaleway_k8s_cluster" "cluster" {
  name    = "scaleway_cluster"  
  version = "1.24.7"
  cni     = "cilium"
}

# Plus d'option de configuration du cluster ici : https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/resources/k8s_pool
resource "scaleway_k8s_pool" "pool" {
  cluster_id  = scaleway_k8s_cluster.cluster.id
  name        = "pool"
  node_type   = "PLAY2-NANO"
  size        = 1
  min_size    = 1
  max_size    = 5
  autoscaling = true
  autohealing = true
}

resource "local_file" "kubeconfig" {
  content  = scaleway_k8s_cluster.cluster.kubeconfig[0].config_file
  filename = "../configuration/kubeconfig"
}
Cette configuration crée :
  • Un cluster Kubernetes à la version 1.24.7 avec comme CNI cilium
  • Un groupe des noeuds qui s’autoheal composé d’un noeudNANO pouvant scale entre 1 à 5 noeud
  • Le “Kubeconfig” du cluster dans un fichier sur votre PC
 
Vous pouvez bien évidemment changer la version du cluster ainsi que les configurations du node pool afin de matcher vos besoins (CPU, RAM, replicas…)
Créer ensuite un fichier version.tf avec le contenu suivant pour verrouiller la version du provider Scaleway à la version 2.9.1, cela vous garantira que ce tuto fonctionnera pour vous aussi 😉
terraform {
  required_providers {
    scaleway = {
      source  = "scaleway/scaleway"
      version = "2.9.1"
    }
	}

  required_version = "~> 1.3"
}
Une fois que la configuration du cluster vous convient, il vous suffit de taper les commandes suivantes pour le créer :
cd scaleway_cluster
terraform init
terraform plan
terraform apply

Installation ingress-nginx

Créez ingress.tf sous le dossier k8s_core_services:
Cette configuration utilise une chart Helm pour la création d’un contrôleur Ingress Nginx nommé ingress dans le cluster créé précédemment.
resource "helm_release" "nginx" {
  name          = "ingress"
  repository    = "https://kubernetes.github.io/ingress-nginx"
  chart         = "ingress-nginx"
  wait_for_jobs = true
}

Installation External DNS

External DNS utilisera le jeton API de Cloudflare pour accéder à votre compte et créer l’enregistrement DNS.
Lors de l'utilisation de l'authentification par le jeton API, ce dernier doit se voir accorder les privilèges de lecture de zone, de modification DNS et ressources de la zone. Si vous souhaitez restreindre davantage les autorisations de l'API à une ou plusieurs zones spécifiques, vous devez également changer les privilèges au niveau des ressources de la zone.
Pour la création du jeton API : Cliquez sur “Mon Profil” dans le site de Clouflare > “Jetons API”> “Créer un jeton” > “Créer un jeton personnalisé” > “Commencer” puis appliquez la configuration ci-dessous.
notion image
Après la création du jeton API, créez un fichier cloudflare-secret.yaml sous le dossier k8s_core_services:
apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
  namespace: kube-system
stringData:
  cloudflare_api_token: CLOUDFLARE_API_TOKEN
Appliquez kubectl apply -f cloudflare-secret.yaml
Une fois que le secret est créé, créez external_dns.tf sous le dossier k8s_core_services
L’external DNS va être créé en utilisant une chart Helm, l’authentification au niveau de Cloudflare est obligatoire pour la création d’un enregistrement DNS.
resource "helm_release" "external_dns" {
  repository = "https://charts.bitnami.com/bitnami"
  chart      = "external-dns"
  name      = "external-dns"
  namespace = "kube-system"
  values = [
<<-EOF
# Make sur to create a secret with the CF_API_TOKEN in the kube-system namespace before
provider: cloudflare
cloudflare:
  email: <CLOUDFLARE_ACCOUNT_EMAIL>
  secretName: cloudflare-api-token-secret
  proxied: false
    EOF  
  ]
}

Installation cert-manager

Similaire à External DNS, le cert-manager utilisera le token de Cloudflare pour la signature des certificats. Vous aurez donc besoin d’un nouveau secret dans le namespace: cert-manager
Cette fois, Terraform se chargera de sa création.
Créez le fichier cloudflare-secret-cert.yaml sous le dossier k8s_core_services :
apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
  namespace: cert-manager
stringData:
  cloudflare_api_token: <CLOUDFLARE_API_TOKEN>
Créez cert_manager.tf sous le dossier k8s_core_services :
Ce module est responsable de la création du cert-manager qui utilisera “DNS-01 challenge” pour prouver que vous contrôlez le DNS de votre nom de domaine en mettant une valeur spécifique dans un enregistrement TXT sous ce nom de domaine. Si la vérification est effectuée, un certificat va être généré.
L'émetteur de production letsencrypt-prod a des limites de débit très strictes. Lorsque vous expérimentez et apprenez, il peut être très facile d'atteindre ces limites. En raison de ce risque, nous commencerons par l'émetteur intermédiaire letsencrypt-staging, une fois que nous serons satisfaits qu'il fonctionne, nous passerons à l'émetteur de production.
Le serveur de l’émetteur de production cluster_issuer_server = "https://acme-v02.api.letsencrypt.org/directory"
module "cert_manager" {
  source                                 = "terraform-iaac/cert-manager/kubernetes"
  version                                = "2.5.0"
  cluster_issuer_email                   = "USER_EMAIL"
  cluster_issuer_name                    = "letsencrypt-staging"
  cluster_issuer_private_key_secret_name = "letsencrypt-staging"
  cluster_issuer_server                  = "https://acme-staging-v02.api.letsencrypt.org/directory"
  solvers = [
    {
      dns01 = {
        cloudflare = {
          email = "CLOUDFLARE_ACCOUNT_EMAIL"
          apiTokenSecretRef = {
            name = "cloudflare-api-token-secret"
            key  = "cloudflare_api_token"
          }
        },
      }
    }
  ]
}
data "kubectl_file_documents" "secret" {
  content = file("./cloudflare-secret-cert.yaml")
}
resource "kubectl_manifest" "secret" {
  for_each  = data.kubectl_file_documents.secret.manifests
  yaml_body = each.value
}

Exemple de déploiement d’un container nginx

Une fois que vous avez configuré votre cluster Kubernetes, cert-manager, ingress-nginx et external DNS, vous êtes prêt à déployer votre application sur le cluster. Pour cela, vous devez créer un manifest Kubernetes qui décrit le déploiement de votre application. Le manifest comprendra un déploiement, un service et un ingress. Une fois le manifest créé, vous pouvez l'utiliser pour déployer votre application sur Kubernetes.
Créez manifests.yaml sous dossier k8s_core_services:
Vous devez ainsi changer les valeurs suivantes par:
  • APPLICATION_DOCKER_IMAGE: nom de l’image docker de votre application.
  • APPLICATION_DOCKER_IMAGE_PORT: le port du conteneur.
  • FQDN: nom de domaine complet.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: <APPLICATION_DOCKER_IMAGE>
        name: nginx
        ports:
        - containerPort: <APPLICATION_DOCKER_IMAGE_PORT>
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: <APPLICATION_DOCKER_IMAGE>
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    external-dns.alpha.kubernetes.io/hostname: <FQDN> #example toto.keltio.com
    external-dns.alpha.kubernetes.io/ttl: "60" #optional
    kubernetes.io/ingress.class: "nginx"    
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - <FQDN>
    secretName: letsencrypt-staging
  rules:
  - host:<FQDN>
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
Créez le fichier version.tf dans le dossier k8s_core_services :
terraform {
  required_providers {
    scaleway = {
      source  = "scaleway/scaleway"
      version = "2.9.1"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.4"
    }
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = ">= 1.7.0"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "2.8.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "2.17.0"
    }
  }
  required_version = "~> 1.3"
}

Architecture de dossier

Ci-dessous l’architecture de dossier à mettre en place.
├── scaleway_cluster
│  ├── version.tf
│  ├── cluster.tf
├── k8s_core_services
│  ├── ingress.tf
│  ├── cloudflare-secret.yaml
│  ├── external_dns.tf
│  ├── cloudflare-secret-cert.yaml
│  ├── cert_manager.tf
│  ├── manifests.yaml
│  ├── version.tf
Une fois que la configuration est mise en place, tapez les commandes suivantes:
cd k8s_core_services
terraform init
terraform plan
terraform apply

Conclusion

Dans ce tutoriel, nous avons montré comment configurer un cluster Kubernetes avec Terraform, cert-manager, ingress-nginx et external DNS pour héberger une application.
Nous avons également montré comment créer un manifest Kubernetes pour le déploiement de l'application.
Grâce à ces outils, vous pouvez facilement héberger votre application sur Kubernetes et la rendre accessible aux utilisateurs.
 

S'inscrire à la newsletter DevSecOps Keltio

Pour recevoir tous les mois des articles d'expertise du domaine

S'inscrire

Écrit par

Rayen Merghad
Rayen Merghad

Rayen est notre DevOps Junior, il aime partager son savoir et pratiquer la callisthénie 🤩