Je ne sais pas si tel était le cas s'il y avait une telle question, alors pardonnez-moi si je ne pouvais pas la trouver.

J'ai un cluster basé sur 3 nœuds, mon application se compose d'un frontend et d'un backend avec chacun en cours d'exécution 2 réplicas:

  • front1 - en cours d'exécution sur node1
  • front2 - en cours d'exécution sur node2
  • be1 - node1
  • be2 ​​- node2
  • Les deux pods FE sont diffusés derrière frontend-service
  • Les deux pods BE sont en service derrière be-service

Lorsque j'ai arrêté node-2, l'application s'est arrêtée et dans mon interface utilisateur, j'ai pu voir des erreurs d'application.

J'ai vérifié les journaux et j'ai découvert que mon application a tenté d'atteindre le type de service des pods backend et qu'elle n'a pas répondu puisque be2 n'était pas en cours d'exécution, le planificateur n'a pas encore terminé celui existant.

Ce n'est que lorsque le nœud a été arrêté et supprimé du cluster, les pods ont été replanifiés sur le troisième nœud et l'application était de nouveau en ligne.

Je sais qu'un maillage de service peut aider en supprimant les pods qui ne répondent pas du trafic, cependant, je ne veux pas encore l'implémenter et en essayant de comprendre quelle est la meilleure solution pour acheminer le trafic vers les pods sains dans un moyen rapide et facile, 5 minutes de temps d'arrêt, c'est beaucoup de temps.

Voici mes spécifications de déploiement be:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: backend
  name: backend
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: backend
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: backend
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-Application
                operator: In
                values:
                - "true"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - backend
            topologyKey: kubernetes.io/hostname
      containers:
      - env:
        - name: SSL_ENABLED
          value: "false"
        image: quay.io/something:latest
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /liveness
            port: 16006
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 20
          successThreshold: 1
          timeoutSeconds: 10
        name: backend
        ports:
        - containerPort: 16006
          protocol: TCP
        - containerPort: 8457
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /readiness
            port: 16006
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 1500m
            memory: 8500Mi
          requests:
            cpu: 6m
            memory: 120Mi
      dnsPolicy: ClusterFirst

Voici mon service backend:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: identity
  name: backend
  namespace: default
spec:
  clusterIP: 10.233.34.115
  ports:
  - name: tcp
    port: 16006
    protocol: TCP
    targetPort: 16006
  - name: internal-http-rpc
    port: 8457
    protocol: TCP
    targetPort: 8457
  selector:
    app: backend
  sessionAffinity: None
  type: ClusterIP
0
Tomer Leibovich 28 févr. 2021 à 20:58

1 réponse

Meilleure réponse

Ceci est une réponse wiki de la communauté. N'hésitez pas à le développer.

Comme déjà mentionné par @TomerLeibovich, le principal problème ici était dû au Configuration des sondes:

Les sondes ont un certain nombre de champs que vous pouvez utiliser pour plus précisément contrôler le comportement des contrôles de vivacité et de préparation:

  • initialDelaySeconds: Nombre de secondes après le démarrage du conteneur avant que les sondes de vivacité ou de préparation ne soient lancées. La valeur par défaut est 0 seconde. La valeur minimale est 0.

  • periodSeconds: à quelle fréquence (en secondes) effectuer la sonde. Par défaut à 10 secondes. La valeur minimale est 1.

  • timeoutSeconds: nombre de secondes après lesquelles la sonde expire. La valeur par défaut est 1 seconde. La valeur minimale est 1.

  • successThreshold: succès consécutifs minimum pour que la sonde soit considérée comme réussie après avoir échoué. La valeur par défaut est 1. Doit être 1 pour la vivacité et les sondes de démarrage. La valeur minimale est 1.

  • failureThreshold: Lorsqu'une sonde échoue, Kubernetes essaiera des échecs de temps avant d'abandonner. Abandonner en cas de vivacité sonde signifie redémarrer le conteneur. En cas de disponibilité, sondez le Le pod sera marqué comme non prêt. La valeur par défaut est 3. La valeur minimale est 1.

Plus la configuration d'expulsion de pod:

Le kubelet doit préserver la stabilité des nœuds lorsque le calcul est disponible les ressources sont faibles. Ceci est particulièrement important lorsqu'il s'agit de ressources de calcul incompressibles, telles que la mémoire ou l'espace disque. Si ces ressources sont épuisées, les nœuds deviennent instables.

Changer le seuil à 1 au lieu de 3 et réduire l'expulsion du pod a résolu le problème car le pod est maintenant expulsé plus tôt.

0
Wytrzymały Wiktor 9 mars 2021 à 12:25