Parlons de certaines des meilleures pratiques à suivre lors de l’utilisation de Kubernetes.

Kubernetes est une plateforme d’orchestration de conteneurs open-source qui automatise le déploiement de conteneurs, la mise à l’échelle et le désétalement continus, l’équilibrage de la charge des conteneurs et bien d’autres choses encore.

Étant donné que la conteneurisation est utilisée sur de nombreux serveurs de production avec des milliers de conteneurs, il devient très important de bien les gérer, et c’est ce que fait Kubernetes.

Si vous utilisez Kubernetes, vous devez adopter les meilleures pratiques pour une meilleure orchestration des conteneurs.

Voici une liste de certaines des meilleures pratiques de Kubernetes que vous devez suivre.

#1. Définissez les demandes et les limites de ressources

Lorsque vous déployez une grosse application sur un cluster de production avec des ressources limitées et que les nœuds manquent de mémoire ou de CPU, l’application s’arrête de fonctionner. Ce temps d’arrêt de l’application peut avoir un impact énorme sur l’entreprise. Mais vous pouvez résoudre ce problème en définissant des demandes et des limites de ressources.

Les demandes et les limites de ressources sont les mécanismes de Kubernetes qui permettent de contrôler l’utilisation des ressources telles que la mémoire et le processeur. Si un pod consomme tout le CPU et toute la mémoire, les autres pods seront privés de ressources et ne pourront pas exécuter l’application. Vous devez donc définir des demandes et des limites de ressources pour les modules afin d’accroître la fiabilité.

Pour votre information, la limite sera toujours plus élevée que la demande. Votre conteneur ne fonctionnera pas si votre demande est supérieure à la limite définie. Vous pouvez définir des demandes et des limites pour chaque conteneur d’un module. Le CPU est défini en millicores et la mémoire en octets (mégaoctet/mébibyte).

Vous trouverez ci-dessous un exemple de définition d’une limite de 500 millicores de CPU et de 128 mégaoctets, et de définition d’un quota de demandes de 300 millicores de CPU et de 64 mégaoctets.

conteneurs :
- nom : prodcontainer1
    image : ubuntu
    ressources :
        requêtes :
            memory : "64Mi"
            cpu : "300m"
        limites : 
            mémoire : "128Mi"
            cpu : "500m"

#2. Utilisez livenessProbe et readinessProbe

Les contrôles de santé sont très importants dans Kubernetes.

Il fournit deux types de contrôles de santé – Readiness probes et Liveness probes.

Les sondes de préparation sont utilisées pour vérifier si l’application est prête à servir le trafic ou non. Cette sonde doit être acceptée par Kubernetes avant qu’il ne commence à envoyer le trafic au pod exécutant l’application à l’intérieur d’un conteneur. Kubernetes cessera d’envoyer le trafic au pod tant que le contrôle de l’état de préparation n’aura pas échoué.

Les sondes de vivacité sont utilisées pour vérifier si l’application est toujours en cours d’exécution (vivante) ou si elle s’est arrêtée (morte). Si l’application fonctionne correctement, Kubernetes ne fait rien. Si votre application est morte, Kubernetes lance un nouveau pod et y exécute l’application.

Si ces vérifications ne sont pas effectuées correctement, les pods peuvent être interrompus ou commencer à recevoir des demandes d’utilisateurs avant même d’être prêts.

Il existe trois types de sondes qui peuvent être utilisées pour les contrôles de vivacité et de disponibilité – HTTP, Command et TCP.

Laissez-moi vous montrer un exemple de la sonde la plus courante, à savoir la sonde HTTP.

Dans ce cas, votre application comporte un serveur HTTP. Lorsque Kubernetes envoie un ping vers le serveur HTTP et obtient une réponse HTTP, il indique que l’application est saine, sinon elle est malsaine.

apiVersion : v1
kind : Pod
metadata :
 name : container10
spec :
 containers :
   - image : ubuntu
     name : container10
     livenessProbe :
       httpGet :
         path : /prodhealth
         port : 8080

#3. Construire des images de petits conteneurs

Il est préférable d’utiliser des images de conteneurs plus petites, car elles prennent moins de place et vous pourrez tirer et construire les images plus rapidement. Comme la taille de l’image est plus petite, les risques d’attaques de sécurité sont également moindres.

Il existe deux façons de réduire la taille des conteneurs : en utilisant une image de base plus petite et un modèle de construction. Actuellement, la dernière image de base de NodeJS pèse 345 Mo, tandis que l’image alpine de NodeJS ne pèse que 28 Mo, soit plus de dix fois moins. Utilisez donc toujours les images les plus petites et ajoutez les dépendances nécessaires à l’exécution de votre application.

Pour réduire encore davantage la taille des images de conteneurs, vous pouvez utiliser un modèle de construction. Le code est construit dans le premier conteneur, puis le code compilé est empaqueté dans le dernier conteneur sans tous les compilateurs et outils nécessaires pour réaliser le code compilé, ce qui rend l’image du conteneur encore plus petite.

#4. Accordez des niveaux d’accès sûrs (RBAC)

Il est très important d’avoir un cluster Kubernetes sécurisé.

L’accès au cluster doit être bien configuré. Vous devez définir le nombre de requêtes par utilisateur par seconde/minute/heure, les sessions simultanées autorisées par adresse IP, la taille des requêtes et la limite des chemins et des noms d’hôtes. Cela vous aidera à protéger le cluster contre les attaques DDoS.

Les développeurs et les ingénieurs DevOps qui travaillent sur un cluster Kubernetes doivent avoir un niveau d’accès défini. La fonction de contrôle d’accès basé sur les rôles (RBAC) de Kubernetes est utile ici. Vous pouvez utiliser les rôles et les ClusterRoles pour définir les profils d’accès. Pour faciliter la configuration du RBAC, vous pouvez utiliser les gestionnaires rbac open-source disponibles pour vous aider à simplifier la syntaxe ou utiliser Rancher, qui fournit le RBAC par défaut.

apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
  name : cluster-role
rules :
- apiGroups : [""]
  ressources : ["pods"]
  verbes : ["get", "list"]

Kubernetes Secrets stocke des informations confidentielles telles que les jetons d’authentification, les mots de passe et les clés ssh. Vous ne devriez jamais vérifier Kubernetes Secrets sur le dépôt IaC, sinon, il sera exposé à ceux qui ont accès à votre dépôt git.

DevSecOps est un mot à la mode qui parle de DevOps et de sécurité. Les organisations adoptent cette tendance car elles en comprennent l’importance.

#5. Restez à jour

Il est recommandé de toujours avoir la dernière version de Kubernetes installée sur le cluster.

La dernière version de Kubernetes comprend de nouvelles fonctionnalités, des mises à jour de fonctionnalités précédentes, des mises à jour de sécurité, des corrections de bogues, etc. Si vous utilisez Kubernetes avec un fournisseur de cloud, la mise à jour devient très facile.

#6. Utilisez les espaces de noms

Kubernetes est livré avec trois espaces de noms différents : default, kube-system et kube-public.

Ces espaces de noms jouent un rôle très important dans un cluster Kubernetes pour l’organisation et la sécurité entre les équipes.

Il est logique d’utiliser l’espace de noms par défaut si vous êtes une petite équipe qui ne travaille que sur 5 à 10 microservices. Mais une équipe en pleine croissance ou une grande organisation aura plusieurs équipes travaillant sur un environnement de test ou de production, de sorte que chaque équipe doit avoir un espace de noms distinct pour une gestion plus facile.

Si elle ne le fait pas, elle peut finir par écraser ou perturber accidentellement l’application/la fonctionnalité d’une autre équipe sans même s’en rendre compte. Il est conseillé de créer plusieurs espaces de noms et de les utiliser pour segmenter vos services en morceaux gérables.

Voici un exemple de création de ressources à l’intérieur d’un espace de noms :

apiVersion : v1
kind : Pod
métadonnées :
   nom : pod01
namespace : prod
   labels :
      image : pod01
spec :
   conteneurs :
- name : prod01
  Image : ubuntu

#7. Utilisez les étiquettes

Au fur et à mesure que vos déploiements Kubernetes se développent, ils incluront invariablement plusieurs services, pods et autres ressources. Le suivi de ces ressources peut devenir fastidieux. Il peut être encore plus difficile de décrire dans Kubernetes comment ces diverses ressources interagissent, comment vous voulez qu’elles soient répliquées, mises à l’échelle et entretenues. Les étiquettes dans Kubernetes sont très utiles pour résoudre ces problèmes.

Les étiquettes sont des paires clé-valeur utilisées pour organiser les éléments dans l’interface Kubernetes.

Par exemple, app : kube-app, phase : test, role : front-end. Ils sont utilisés pour décrire la façon dont les différents objets et ressources du cluster fonctionnent ensemble.

apiVersion : v1
kind : Pod
metadata :
 name : test-pod
 labels :
   environnement : testing
   équipe : test01
spec :
 conteneurs :
   - name : test01
     image : "Ubuntu
     ressources :
       limites :
        cpu : 1

Ainsi, vous pouvez réduire la douleur de la production Kubernetes en étiquetant toujours les ressources et les objets.

#8. Journalisation de l’audit

Pour identifier les menaces dans le cluster Kubernetes, l’audit des journaux est très important. L’audit permet de répondre à des questions telles que ce qui s’est passé, pourquoi cela s’est passé, qui l’a fait se produire, etc.

Toutes les données relatives aux demandes faites à kube-apiserver sont stockées dans un fichier journal appelé audit.log. Ce fichier est structuré au format JSON.

Dans Kubernetes, par défaut, le journal d’audit est stocké dans <em>/var/log/audit.log</em> et la politique d’audit est présente dans <em>/etc/kubernetes/audit-policy.yaml</em>.

Pour activer la journalisation des audits, démarrez kube-apiserver avec ces paramètres :

--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/audit.log

Voici un exemple de fichier audit.log configuré pour enregistrer les changements dans les pods :

apiVersion : audit.k8s.io/v1
kind : Policy
omitStages :
  - "RequestReceived"
rules :
  - niveau : RequestResponse
    ressources :
    - group : ""
      ressources : ["pods"]
   - niveau : Métadonnées
     ressources :
     - groupe : ""
      ressources : ["pods/log", "pods/status"]

Vous pouvez toujours revenir en arrière et vérifier les journaux d’audit en cas de problème dans le cluster Kubernetes. Cela vous aidera à rétablir l’état correct du cluster.

#9. Appliquer les règles d’affinité (Node/Pod)

Il existe deux mécanismes dans Kubernetes pour associer les pods aux nœuds d’une meilleure manière – l’affinité pod et l’affinité nœud. Il est recommandé d’utiliser ces mécanismes pour améliorer les performances.

En utilisant l’affinité de nœud, vous pouvez planifier des pods sur les nœuds en fonction de critères définis. Selon les exigences du pod, le nœud correspondant est sélectionné et assigné dans un cluster Kubernetes.

apiVersion : v1
kind : Pod
metadata :
  name : ubuntu
spec :
  affinity :
    nodeAffinity : 
preferredDuringSchedulingIgnoredDuringExecution :
      - weight : 2
        préférence :        
matchExpressions :
          - key : disktype
            opérateur : In
            valeurs :
            - ssd   
  conteneurs :
  - name : ubuntu
    image : ubuntu
    imagePullPolicy : IfNotPresent

En utilisant l’affinité des pods, vous pouvez planifier plusieurs pods sur le même nœud (pour améliorer la latence) ou décider de garder les pods sur des nœuds séparés (pour la haute disponibilité) afin d’augmenter la performance.

apiVersion : v1
kind : Pod
métadonnées :
  name : ubuntu-pod
spec :
  affinity :
    podAffinity :
     
requiredDuringSchedulingIgnoredDuringExecution :
      - labelSelector :
         
matchExpressions :
          - key : security
            opérateur : In
            valeurs :
            - S1
        topologyKey : failure-domain.beta.kubernetes.io/zone
  containers :
  - name : ubuntu-pod
    image : ubuntu

Après avoir analysé la charge de travail de votre cluster, vous devez décider de la stratégie d’affinité à utiliser.

#10. Terminaison de Kubernetes

Kubernetes met fin aux pods lorsqu’ils ne sont plus nécessaires. Vous pouvez l’initier par une commande ou un appel API, les pods sélectionnés passent à l’état de terminaison et aucun trafic n’est envoyé à ces pods. Un message SIGTERM est alors envoyé à ces pods, après quoi les pods s’arrêtent.

Les pods sont arrêtés de manière gracieuse, par défaut la période de grâce est de 30 secondes. Si les pods sont toujours en cours d’exécution, Kubernetes envoie un message SIGKILL qui les arrête de force. Enfin, ces modules sont supprimés par Kubernetes du serveur API sur la machine maître.

Si vos pods prennent toujours plus de 30 secondes, vous pouvez augmenter ce délai de grâce à 45 ou 60 secondes.

apiVersion : v1
kind : Pod
metadata :
 name : container10
spec :
 containers :
   - image : ubuntu
     name : container10
  terminationGracePeriodSeconds : 60

Conclusion

J’espère que ces bonnes pratiques vous aideront à mieux orchestrer les conteneurs avec Kubernetes. Allez-y et essayez de les mettre en œuvre dans votre cluster Kubernetes pour obtenir de meilleurs résultats.

Ensuite, découvrez les meilleurs outils Kubernetes pour une réussite DevOps.