Conflit d'utilisation du processeur Kubernetes et des métriques du conteneur Docker

9

Nous avons récemment transféré notre environnement de production à Kubernetes. Je voudrais appliquer les limites du processeur sur les conteneurs. Je reçois des métriques de CPU conflictuelles qui ne vont pas ensemble. Voici ma configuration:

  • Agents DataDog s'exécutant en tant que Daemonset
  • Applications existantes fonctionnant sans limites de CPU
  • Les conteneurs en question sont des applications Ruby multithread
  • Deux mesures: kubernetes.cpu.usage.{avg,max}etdocker.cpu.usage
  • c4.xlarge nœuds de cluster (4 vCPU ou 4000 m en termes de Kubernetes)

kubernetes.cpu.usage.maxsignale ~ 600m pour les conteneurs en question. docker.cpu.usagerapports ~ 60%. Il s'ensuit qu'une limite de 1 000 m de processeur serait plus que suffisante en fonctionnement normal.

J'ai fixé la limite à 1000m. Puis docker.container.throttlesmonte de manière significative tout kubernetes.cpu.usage.maxet docker.cpu.usagereste le même. Le système tombe à genoux pendant cette période. Cela n'a pas de sens pour moi.

J'ai recherché les statistiques de Docker. Il semble que docker stats(et l'API sous-jacente) normalisent la charge en fonction des cœurs de processeur. Donc dans mon cas, docker.cpu.usagede 60% vient (4000m * 0,60) à 2400m en termes Kubernetes. Cependant, cela ne correspond à aucun nombre de Kubernetes. J'ai fait une autre expérience pour tester mon hypothèse que les nombres de Kubernetes sont incorrects. J'ai fixé la limite à 2600 m (pour une marge supplémentaire). Cela n'a entraîné aucun étranglement. Cependant, Kubernetes a observé que l'utilisation du processeur n'a pas changé. Cela me laisse confus.

Mes questions sont donc:

  • Est-ce que cela ressemble à un bug dans Kubernetes (ou quelque chose dans la pile?)
  • Ma compréhension est-elle correcte?

Ma question de suivi concerne la façon de déterminer correctement le CPU pour les applications Ruby. Un conteneur utilise Puma. Il s'agit d'un serveur Web multithread avec une quantité configurable de threads. Les requêtes HTTP sont gérées par l'un des threads. La deuxième application est un serveur d'épargne utilisant le serveur fileté. Chaque connexion TCP entrante est gérée par son propre thread. Le thread se ferme à la fermeture de la connexion. Ruby comme GIL (Global Interpreter Lock) donc un seul thread peut exécuter du code Ruby à la fois. Cela permet à plusieurs threads d'exécuter des E / S et des choses comme ça.

Je pense que la meilleure approche est de limiter le nombre de threads en cours d'exécution dans chaque application et d'approcher les limites du processeur Kubernetes en fonction du nombre de threads. Les processus ne bifurquent pas, donc l'utilisation totale du processeur est plus difficile à prévoir.

La question ici est: comment prévoir correctement l'utilisation du processeur et les limites de ces applications?

ahawkins
la source
Avez-vous essayé sur un nœud 1cpu et un nœud 2 cpu pour voir comment le nombre est corrélé (ou non)?
Tensibai

Réponses:

4

Plusieurs choses ici:

  1. Vous êtes sur AWS ec2, donc tout ce que vous faites sur votre instance pour mesurer le processeur calcule le processeur au niveau de l'hyperviseur et non au niveau de l'instance. Pour cela, exécutez n'importe quel test de charge et vérifiez iostat -ct 1 et l'utilisation du processeur dans cloudwatch. L'utilisation du processeur dans cloudwatch est toujours supérieure de 10 à 20% à ce que rapportera iostat et c'est parce que iostat donnera l'utilisation du processeur au niveau de l'hyperviseur.

  2. En tant que docker pour voir comment kubernetes et les métriques de docker se comparent, je suggère d'exécuter les conteneurs avec --cpuset = 1 ou n'importe quel nombre pour permettre à tous les conteneurs d'utiliser un seul vCPU.

  3. Également dans AWS 1 CPU = 2vcpu. Il est hyperthreadé à 2. Vous pouvez peut-être en tenir compte lors du calcul.

  4. Enfin, la meilleure métrique à utiliser pour voir l'utilisation du processeur pour une application particulière est d'utiliser htop et de corréler avec vos métriques cloudwatch.

  5. J'ai également observé que le démon docker s'épinglait parfois à l'un des processeurs virtuels et donc lorsque vous le réduisez à 1000 m, peut-être que l'ensemble de la configuration ralentit car la réduction se produit sur l'un des vpcus. Vous pouvez utiliser mpstat pour en savoir plus.

  6. Enfin, au niveau de l'hôte, vous pouvez épingler Docker sur un seul processeur et en observer davantage.

J'espère que cela vous rapproche un peu plus. Mettez-moi à jour si vous avez déjà trouvé une solution.

lakshayk
la source