Haute Disponibilité

Ce guide présente l'ensemble des éléments de configuration nécessaires pour améliorer la disponibilité et la continuité de service de vos applications déployées dans un cluster Kubernetes managés par cegedim.cloud.

Il s'agit d'un guide indispensable pour que votre stratégie de reprise après sinistre réponde aux exigences de cegedim.cloud.

Comment configurer les déploiements pour tirer parti des capacités HA ?

Une fois votre cluster Kubernetes configuré pour fonctionner selon la topologie de haute disponibilité (HA), certaines bonnes pratiques de configuration sont nécessaires pour permettre à vos applications :

  • pour fonctionner de façon simultanée sur tous les centres de données de la région.

  • de disposer d'une capacité suffisante dans tous les centres de données en cas de catastrophe sur l'un d'entre eux

Configuration du déploiement

Pour rappel, les nœuds des clusters Kubernetes sont répartis dans 3 zones de disponibilité (AZ) et 2 centres de données :

  • AZ "A" et "B" fonctionnent sur le centre de données primaire.

  • AZ "C" fonctionne sur le centre de données secondaire.

Nombre de répliques

Pour les services sans état qui prennent en charge la mise à l'échelle, la meilleure pratique consiste à faire fonctionner au moins trois pods :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  replicas: 3

Anti-affinité

Ces 3 pods doivent être correctement configurés pour qu'au moins un pod fonctionne sur chaque zone de disponibilité :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - nginx
              topologyKey: "failure-domain.beta.kubernetes.io/zone"
      containers:
      - name: web-app
        image: nginx

Nous utilisons preferedDuringSchedulingIgnoredDuringExecution et non requiredDuringSchedulingIgnoredDuringExecution car nous voulons que cette exigence soit "souple" : Kubernetes permettra alors de programmer plusieurs pods sur la même AZ si vous exécutez plus de répliques que d'AZ, ou en cas de défaillance d'une zone.

Dans kube 1.20, failure-domain.beta.kubernetes.io/zone sera déprécié, la nouvelle clé de topologie sera topologie.kubernetes.io/zone

Contraintes d'étalement pour les pods

Comment dimensionner votre cluster HA ?

Si vous utilisez la topologie de cluster haute disponibilité, votre objectif est de déployer des applications résilientes en cas de panne du centre de données.

Cette page décrit quelques bonnes pratiques pour déterminer le dimensionnement des nœuds de travail pour chaque zone de disponibilité où vos charges de travail sont exécutées.

Réfléchir au "pire des scénarios".

Pour rappel, Kubernetes Cluster est déployé dans 3 zones de disponibilité, et 2 centres de données. Dans le pire des cas, une seul zone de disponibilité fonctionnera si le centre de données primaire subit un sinistre majeur.

C'est l'hypothèse à prendre en compte pour déterminer le dimensionnement "nominal", que l'on peut appeler "Si le centre de données primaire tombe en panne, de quelle capacité de CPU / RAM ai-je besoin pour continuer à faire fonctionner mon application ?".

Définir la capacité nominale

Comprendre vos besoins

Pour déterminer cette capacité, puis les nœuds de travail déployés dans la zone de disponibilité "C" (combien, et avec quelles ressources), vous aurez besoin de 3 paramètres :

ParamètreDescription

Minimum Business Continuity Objective (MBCO)

Comme le RTO / RPO, le MBCO est un paramètre majeur pour dimensionner votre DRP.

En résumé, il s'agit du pourcentage de capacité de votre application déployée qui est nécessaire pour que votre entreprise soit opérationnelle.

Selon la taille de vos charges de travail lorsque vous les exécutez dans 3 AZ, la performance que vous jugez suffisante peut être de 30%, 50% ou 100%.

Par exemple, si vous avez une application avec 3 répliques de 4GB RAM sur chaque AZ, vous pouvez déterminer le MBCO de manière très différente :

  • 33%

    • il suffit qu'un seul fonctionne pendant la panne, car les performances seront correctes.

    • vous pouvez prendre le risque de ne pas avoir de redondance pendant la période de panne

  • 66%

    • soit, 2 pods minimum sont nécessaires pour avoir une performance OK

    • et/ou vous ne voulez pas prendre le risque d'échouer si le seul pod restant échoue.

  • 100%

    • vous avez absolument besoin de 3 pods minimum pour faire fonctionner le service avec des performances nominales

Le choix vous appartient !

Pods Ressources Demandes

Comme Kubernetes essaiera de replanifier vos pods en cas de panne, les requêtes sont un paramètre absolument majeur à gérer.

Si l'AZ-C n'a pas assez de ressources pour satisfaire toutes les exigences des déploiements de pods souhaités, Kubernetes ne les déploiera pas, et peut-être que vos applications ne seront pas disponibles !

Pour connaître vos demandes, vous pouvez exécuter cette commande : kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"-"}{range .spec.containers[*]}{"/"}{.name}{";"}{.resources.requests.cpu}{";"}{.resources.limits.cpu}{";"}{.resources.requests.memory}{";"}{.resources.limits.memory}{"\n"}{end}{"\n"}{end}' | grep -v -e '^$'

Utilisation des ressources

Déterminer les demandes, c'est bien pour être sûr que Kubernetes déploiera autant de pods que vous le souhaitez, mais qu'en est-il de la capacité réelle utilisée par vos pods ? Il faut également en tenir compte pour avoir une idée des ressources "brutes" dont vos applications ont besoin.

Pour le déterminer, vous pouvez exécuter cette commande pour connaître l'utilisation actuelle de votre pod : kubectl top pod

Calculer le dimensionnement

Vous avez alors deux possibilités pour calculer la taille :

  • Au niveau de la granularité "Cluster Level": si vous débutez le processus et que vos charges de travail ne sont pas aussi complexes ou variables, utilisez cette option :

    • Déterminer un MBCO global pour les déploiements croisés

    • Additionner toutes les demandes de ressources des pods pour obtenir un numéro unique.

    • Additionner toutes les ressources utilisées par les pods pour obtenir un nombre unique.

  • Au niveau de la granularité "Pod Level" : Si vous voulez que le dimensionnement soit parfaitement adapté et que vous en avez le temps, prenez le temps de déterminer ces paramètres pour chaque déploiement de votre cluster Kubernetes, car le MBCO peut varier ! Par exemple :

    • Une application web nécessitera un MBCO avec 100 %.

    • Un cache nécessitera un MBCO de 50%.

    • Une fonctionnalité "agréable à avoir" ou un outil interne peut être à 0 %.

Le calcul au "niveau de cluster" n'est pas assez précis pour être absolument certain que le cluster sera d'une taille appropriée. Il suffit de le savoir et d'évaluer si cela vaut la peine de prendre le risque.

Dans tous les cas, ce dimensionnement doit être réévalué régulièrement, en fonction des nouveaux déploiements ou des redimensionnements que vous effectuez dans vos opérations quotidiennes.

Utilisation de la granularité au niveau des clusters

Si vous avez additionné toutes les demandes et l'utilisation, et que vous avez déterminé le MBCO au niveau du "cluster", vous pouvez utiliser cette formule simple pour calculer le dimensionnement requis pour l'AZ "C" dans le centre de données secondaire :

required_capacity = MBCO * max(requests, usage)

Utilisation de la granularité "Pod

Si vous avez déterminé un MBCO par déploiement, vous devrez calculer votre dimensionnement avec une formule plus complexe :

required_capacity = sum(pod.MBCO * max(pod.requests, pod.usage))

Ajustez vos descripteurs de déploiement

Une fois que vous avez calculé votre MBCO, il est important de tirer parti des capacités de Kubernetes (QoS, notamment PodDisruptionBudget) pour que votre déploiement suive votre décision.

Ajustez la taille de votre groupe

Utilisez ITCare ou demandez l'aide de notre support pour dimensionner votre cluster.

Comment utiliser la QoS et la disponibilité garantie de Kubernetes ?

Au cours de cette phase, vous devrez hiérarchiser vos actifs et définir les composants qui sont essentiels à la disponibilité de vos services.

connaître l'utilisation de vos ressources, une fois le déploiement effectué, il est bon d'observer la consommation de ressources de votre charge de travail.

vous pouvez accéder à vos métriques via l'interface utilisateur de rancher ou via un client comme Lens.

Qualité du service

Dans Kubernetes il y a 3 classes de QoS :

  • Garantie

  • Burstable

  • BestEffort

Pour les charges de travail critiques, vous pouvez utiliser la QOS "garantie", qui définit simplement les limites de ressources égales aux demandes de ressources :

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
  replicas: 3
  template:
    spec:
      resources:
        limits:
          memory: "200Mi"
          cpu: "700m"
        requests:
          memory: "200Mi"
          cpu: "700m"

Pour les charges de travail moins critiques, vous pouvez utiliser le QOS "Burstable", qui définira les limites de ressources et les demandes.

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
  replicas: 2
  template:
    spec:
      resources:
        requests:
          memory: "200Mi"
          cpu: "700m"

Budget pour la perturbation des pods

Le budget de perturbation des pods vous permettra de configurer votre tolérance aux pannes et le nombre de pannes que votre application peut supporter avant d'être indisponible.

Stateless

Avec une charge de travail sans état, l'objectif est d'avoir un nombre minimum de pods disponibles à tout moment, pour ce faire vous pouvez définir un simple budget de perturbation des pods :

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: myapp

Stateful

Avec une charge de travail à état, le but est d'avoir un nombre maximum de pods indisponibles à tout moment, afin de maintenir le quorum par exemple :

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      app: myapp

Horizontal Pod Autoscaler

Scénarios de trafic élevé :

Last updated