6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Κατά τη διάρκεια των ετών χρήσης του Kubernetes στην παραγωγή, έχουμε συγκεντρώσει πολλές ενδιαφέρουσες ιστορίες για το πώς τα σφάλματα σε διάφορα στοιχεία του συστήματος οδήγησαν σε δυσάρεστες ή/και ακατανόητες συνέπειες που επηρεάζουν τη λειτουργία των δοχείων και των λοβών. Σε αυτό το άρθρο έχουμε κάνει μια επιλογή από μερικά από τα πιο κοινά ή ενδιαφέροντα. Ακόμα κι αν δεν είστε ποτέ αρκετά τυχεροί να αντιμετωπίσετε τέτοιες καταστάσεις, το να διαβάζετε για τέτοιες μικρές αστυνομικές ιστορίες - ειδικά «από πρώτο χέρι» - είναι πάντα ενδιαφέρον, έτσι δεν είναι;

Ιστορία 1. Supercronic και Docker hanging

Σε ένα από τα συμπλέγματα, λαμβάναμε περιοδικά ένα παγωμένο Docker, το οποίο παρενέβαινε στην κανονική λειτουργία του συμπλέγματος. Ταυτόχρονα, παρατηρήθηκαν τα ακόλουθα στα αρχεία καταγραφής του Docker:

level=error msg="containerd: start init process" error="exit status 2: "runtime/cgo: pthread_create failed: No space left on device
SIGABRT: abort
PC=0x7f31b811a428 m=0

goroutine 0 [idle]:

goroutine 1 [running]:
runtime.systemstack_switch() /usr/local/go/src/runtime/asm_amd64.s:252 fp=0xc420026768 sp=0xc420026760
runtime.main() /usr/local/go/src/runtime/proc.go:127 +0x6c fp=0xc4200267c0 sp=0xc420026768
runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc4200267c8 sp=0xc4200267c0

goroutine 17 [syscall, locked to thread]:
runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1

…

Αυτό που μας ενδιαφέρει περισσότερο για αυτό το σφάλμα είναι το μήνυμα: pthread_create failed: No space left on device. Γρήγορη Μελέτη τεκμηρίωση εξήγησε ότι ο Docker δεν μπορούσε να διαχωρίσει μια διαδικασία, γι' αυτό και κατά διαστήματα πάγωσε.

Στην παρακολούθηση, η παρακάτω εικόνα αντιστοιχεί σε αυτό που συμβαίνει:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Παρόμοια κατάσταση παρατηρείται και σε άλλους κόμβους:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Στους ίδιους κόμβους βλέπουμε:

root@kube-node-1 ~ # ps auxfww | grep curl -c
19782
root@kube-node-1 ~ # ps auxfww | grep curl | head
root     16688  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root     17398  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root     16852  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root      9473  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root      4664  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root     30571  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root     24113  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root     16475  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root      7176  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>
root      1090  0.0  0.0      0     0 ?        Z    Feb06   0:00      |       _ [curl] <defunct>

Αποδείχθηκε ότι αυτή η συμπεριφορά είναι συνέπεια της εργασίας του pod υπερκρονικός (ένα βοηθητικό πρόγραμμα Go που χρησιμοποιούμε για την εκτέλεση εργασιών cron σε pods):

 _ docker-containerd-shim 833b60bb9ff4c669bb413b898a5fd142a57a21695e5dc42684235df907825567 /var/run/docker/libcontainerd/833b60bb9ff4c669bb413b898a5fd142a57a21695e5dc42684235df907825567 docker-runc
|   _ /usr/local/bin/supercronic -json /crontabs/cron
|       _ /usr/bin/newrelic-daemon --agent --pidfile /var/run/newrelic-daemon.pid --logfile /dev/stderr --port /run/newrelic.sock --tls --define utilization.detect_aws=true --define utilization.detect_azure=true --define utilization.detect_gcp=true --define utilization.detect_pcf=true --define utilization.detect_docker=true
|       |   _ /usr/bin/newrelic-daemon --agent --pidfile /var/run/newrelic-daemon.pid --logfile /dev/stderr --port /run/newrelic.sock --tls --define utilization.detect_aws=true --define utilization.detect_azure=true --define utilization.detect_gcp=true --define utilization.detect_pcf=true --define utilization.detect_docker=true -no-pidfile
|       _ [newrelic-daemon] <defunct>
|       _ [curl] <defunct>
|       _ [curl] <defunct>
|       _ [curl] <defunct>
…

Το πρόβλημα είναι το εξής: όταν μια εργασία εκτελείται σε supercronic, η διαδικασία γεννιέται από αυτήν δεν μπορεί να τερματιστεί σωστά, μετατρέπεται σε βρυκόλακας.

Σημείωση: Για να είμαστε πιο ακριβείς, οι διεργασίες δημιουργούνται από εργασίες cron, αλλά το supercronic δεν είναι ένα αρχικό σύστημα και δεν μπορεί να «υιοθετήσει» διαδικασίες που δημιούργησαν τα παιδιά του. Όταν εγείρονται σήματα SIGHUP ή SIGTERM, δεν μεταβιβάζονται στις θυγατρικές διεργασίες, με αποτέλεσμα οι θυγατρικές διεργασίες να μην τερματίζονται και να παραμένουν σε κατάσταση ζόμπι. Μπορείτε να διαβάσετε περισσότερα για όλα αυτά, για παράδειγμα, στο ένα τέτοιο άρθρο.

Υπάρχουν δύο τρόποι επίλυσης προβλημάτων:

  1. Ως προσωρινή λύση - αυξήστε τον αριθμό των PID στο σύστημα σε μία μόνο χρονική στιγμή:
           /proc/sys/kernel/pid_max (since Linux 2.5.34)
                  This file specifies the value at which PIDs wrap around (i.e., the value in this file is one greater than the maximum PID).  PIDs greater than this  value  are  not  allo‐
                  cated;  thus, the value in this file also acts as a system-wide limit on the total number of processes and threads.  The default value for this file, 32768, results in the
                  same range of PIDs as on earlier kernels
  2. Ή εκκινήστε εργασίες στο supercronic όχι απευθείας, αλλά χρησιμοποιώντας το ίδιο τίνι, το οποίο είναι σε θέση να τερματίζει σωστά τις διαδικασίες και να μην δημιουργεί ζόμπι.

Ιστορία 2. "Ζόμπι" κατά τη διαγραφή μιας cgroup

Η Kubelet άρχισε να καταναλώνει πολύ CPU:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Σε κανέναν δεν θα αρέσει αυτό, οπότε οπλιστήκαμε Perf και άρχισε να αντιμετωπίζει το πρόβλημα. Τα αποτελέσματα της έρευνας ήταν τα εξής:

  • Η Kubelet ξοδεύει περισσότερο από το ένα τρίτο του χρόνου της CPU για να τραβήξει δεδομένα μνήμης από όλες τις cgroups:

    6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

  • Στη λίστα αλληλογραφίας προγραμματιστών πυρήνα μπορείτε να βρείτε συζήτηση του προβλήματος. Εν ολίγοις, η ουσία καταλήγει σε αυτό: διάφορα αρχεία tmpfs και άλλα παρόμοια πράγματα δεν αφαιρούνται εντελώς από το σύστημα κατά τη διαγραφή μιας cgroup, το λεγόμενο memcg βρυκόλακας. Αργά ή γρήγορα θα διαγραφούν από την προσωρινή μνήμη της σελίδας, αλλά υπάρχει πολλή μνήμη στον διακομιστή και ο πυρήνας δεν βλέπει το νόημα να χάνει χρόνο για τη διαγραφή τους. Γι' αυτό συσσωρεύονται συνέχεια. Γιατί συμβαίνει αυτό; Αυτός είναι ένας διακομιστής με cron jobs που δημιουργεί συνεχώς νέες θέσεις εργασίας, και μαζί τους νέα pods. Έτσι, δημιουργούνται νέες cgroups για κοντέινερ σε αυτά, τα οποία σύντομα διαγράφονται.
  • Γιατί το cAdvisor στο kubelet σπαταλά τόσο πολύ χρόνο; Αυτό είναι εύκολο να το δει κανείς με την απλούστερη εκτέλεση time cat /sys/fs/cgroup/memory/memory.stat. Εάν σε ένα υγιές μηχάνημα η λειτουργία διαρκεί 0,01 δευτερόλεπτα, τότε στο προβληματικό cron02 διαρκεί 1,2 δευτερόλεπτα. Το θέμα είναι ότι το cAdvisor, το οποίο διαβάζει πολύ αργά δεδομένα από το sysfs, προσπαθεί να λάβει υπόψη τη μνήμη που χρησιμοποιείται σε ζόμπι cgroups.
  • Για να αφαιρέσουμε αναγκαστικά τα ζόμπι, δοκιμάσαμε να καθαρίσουμε τις κρυφές μνήμες όπως συνιστάται στο LKML: sync; echo 3 > /proc/sys/vm/drop_caches, - αλλά ο πυρήνας αποδείχθηκε πιο περίπλοκος και τράκαρε το αυτοκίνητο.

Τι να κάνω? Το πρόβλημα διορθώνεται (διαπράττω, και για περιγραφή βλ μήνυμα απελευθέρωσης) ενημέρωση του πυρήνα Linux στην έκδοση 4.16.

Ιστορία 3. Το Systemd και η βάση του

Και πάλι, το kubelet καταναλώνει πάρα πολλούς πόρους σε ορισμένους κόμβους, αλλά αυτή τη φορά καταναλώνει πάρα πολλή μνήμη:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Αποδείχθηκε ότι υπάρχει πρόβλημα στο systemd που χρησιμοποιείται στο Ubuntu 16.04 και παρουσιάζεται κατά τη διαχείριση προσαρτήσεων που δημιουργούνται για σύνδεση subPath από ConfigMaps ή μυστικά. Αφού το λοβό ολοκληρώσει την εργασία του η υπηρεσία systemd και η βάση σέρβις παραμένουν στο σύστημα. Με την πάροδο του χρόνου, ένας τεράστιος αριθμός από αυτούς συσσωρεύεται. Υπάρχουν ακόμη και θέματα σχετικά με αυτό το θέμα:

  1. #5916;
  2. kubernetes #57345.

...το τελευταίο από τα οποία αναφέρεται στο PR στο systemd: #7811 (θέμα στο systemd - #7798).

Το πρόβλημα δεν υπάρχει πλέον στο Ubuntu 18.04, αλλά αν θέλετε να συνεχίσετε να χρησιμοποιείτε το Ubuntu 16.04, μπορεί να βρείτε χρήσιμη τη λύση μας σε αυτό το θέμα.

Έτσι φτιάξαμε το ακόλουθο DaemonSet:

---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  labels:
    app: systemd-slices-cleaner
  name: systemd-slices-cleaner
  namespace: kube-system
spec:
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: systemd-slices-cleaner
  template:
    metadata:
      labels:
        app: systemd-slices-cleaner
    spec:
      containers:
      - command:
        - /usr/local/bin/supercronic
        - -json
        - /app/crontab
        Image: private-registry.org/systemd-slices-cleaner/systemd-slices-cleaner:v0.1.0
        imagePullPolicy: Always
        name: systemd-slices-cleaner
        resources: {}
        securityContext:
          privileged: true
        volumeMounts:
        - name: systemd
          mountPath: /run/systemd/private
        - name: docker
          mountPath: /run/docker.sock
        - name: systemd-etc
          mountPath: /etc/systemd
        - name: systemd-run
          mountPath: /run/systemd/system/
        - name: lsb-release
          mountPath: /etc/lsb-release-host
      imagePullSecrets:
      - name: antiopa-registry
      priorityClassName: cluster-low
      tolerations:
      - operator: Exists
      volumes:
      - name: systemd
        hostPath:
          path: /run/systemd/private
      - name: docker
        hostPath:
          path: /run/docker.sock
      - name: systemd-etc
        hostPath:
          path: /etc/systemd
      - name: systemd-run
        hostPath:
          path: /run/systemd/system/
      - name: lsb-release
        hostPath:
          path: /etc/lsb-release

... και χρησιμοποιεί το ακόλουθο σενάριο:

#!/bin/bash

# we will work only on xenial
hostrelease="/etc/lsb-release-host"
test -f ${hostrelease} && grep xenial ${hostrelease} > /dev/null || exit 0

# sleeping max 30 minutes to dispense load on kube-nodes
sleep $((RANDOM % 1800))

stoppedCount=0
# counting actual subpath units in systemd
countBefore=$(systemctl list-units | grep subpath | grep "run-" | wc -l)
# let's go check each unit
for unit in $(systemctl list-units | grep subpath | grep "run-" | awk '{print $1}'); do
  # finding description file for unit (to find out docker container, who born this unit)
  DropFile=$(systemctl status ${unit} | grep Drop | awk -F': ' '{print $2}')
  # reading uuid for docker container from description file
  DockerContainerId=$(cat ${DropFile}/50-Description.conf | awk '{print $5}' | cut -d/ -f6)
  # checking container status (running or not)
  checkFlag=$(docker ps | grep -c ${DockerContainerId})
  # if container not running, we will stop unit
  if [[ ${checkFlag} -eq 0 ]]; then
    echo "Stopping unit ${unit}"
    # stoping unit in action
    systemctl stop $unit
    # just counter for logs
    ((stoppedCount++))
    # logging current progress
    echo "Stopped ${stoppedCount} systemd units out of ${countBefore}"
  fi
done

... και εκτελείται κάθε 5 λεπτά χρησιμοποιώντας το προαναφερθέν supercronic. Το Dockerfile του μοιάζει με αυτό:

FROM ubuntu:16.04
COPY rootfs /
WORKDIR /app
RUN apt-get update && 
    apt-get upgrade -y && 
    apt-get install -y gnupg curl apt-transport-https software-properties-common wget
RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable" && 
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && 
    apt-get update && 
    apt-get install -y docker-ce=17.03.0*
RUN wget https://github.com/aptible/supercronic/releases/download/v0.1.6/supercronic-linux-amd64 -O 
    /usr/local/bin/supercronic && chmod +x /usr/local/bin/supercronic
ENTRYPOINT ["/bin/bash", "-c", "/usr/local/bin/supercronic -json /app/crontab"]

Ιστορία 4. Ανταγωνιστικότητα κατά τον προγραμματισμό ομάδων

Παρατηρήθηκε ότι: εάν έχουμε ένα λοβό τοποθετημένο σε έναν κόμβο και η εικόνα του αντλείται για πολύ μεγάλο χρονικό διάστημα, τότε ένα άλλο λοβό που «χτυπά» τον ίδιο κόμβο απλά θα δεν αρχίζει να τραβάει την εικόνα του νέου pod. Αντίθετα, περιμένει μέχρι να τραβήξει την εικόνα του προηγούμενου pod. Ως αποτέλεσμα, ένα pod που ήταν ήδη προγραμματισμένο και του οποίου η εικόνα θα μπορούσε να είχε ληφθεί σε μόλις ένα λεπτό θα καταλήξει στην κατάσταση containerCreating.

Τα γεγονότα θα μοιάζουν κάπως έτσι:

Normal  Pulling    8m    kubelet, ip-10-241-44-128.ap-northeast-1.compute.internal  pulling image "registry.example.com/infra/openvpn/openvpn:master"

Αποδεικνύεται ότι μια μεμονωμένη εικόνα από ένα αργό μητρώο μπορεί να εμποδίσει την ανάπτυξη ανά κόμβο.

Δυστυχώς, δεν υπάρχουν πολλοί τρόποι εξόδου από την κατάσταση:

  1. Προσπαθήστε να χρησιμοποιήσετε το Μητρώο Docker απευθείας στο σύμπλεγμα ή απευθείας με το σύμπλεγμα (για παράδειγμα, Μητρώο GitLab, Nexus κ.λπ.).
  2. Χρησιμοποιήστε βοηθητικά προγράμματα όπως Kraken.

Ιστορία 5. Οι κόμβοι κολλάνε λόγω έλλειψης μνήμης

Κατά τη λειτουργία διαφόρων εφαρμογών, συναντήσαμε επίσης μια κατάσταση όπου ένας κόμβος παύει εντελώς να είναι προσβάσιμος: το SSH δεν αποκρίνεται, όλοι οι δαίμονες παρακολούθησης πέφτουν και μετά δεν υπάρχει τίποτα (ή σχεδόν τίποτα) ανώμαλο στα αρχεία καταγραφής.

Θα σας το πω σε εικόνες χρησιμοποιώντας το παράδειγμα ενός κόμβου όπου λειτουργούσε το MongoDB.

Έτσι φαίνεται το top να ατυχήματα:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Και κάπως έτσι - μετά ατυχήματα:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Στην παρακολούθηση, υπάρχει επίσης ένα απότομο άλμα, στο οποίο ο κόμβος παύει να είναι διαθέσιμος:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

Έτσι, από τα στιγμιότυπα οθόνης είναι σαφές ότι:

  1. Η μνήμη RAM στο μηχάνημα είναι κοντά στο τέλος.
  2. Υπάρχει ένα απότομο άλμα στην κατανάλωση RAM, μετά από το οποίο η πρόσβαση σε ολόκληρο το μηχάνημα απενεργοποιείται απότομα.
  3. Μια μεγάλη εργασία φτάνει στο Mongo, η οποία αναγκάζει τη διαδικασία DBMS να χρησιμοποιεί περισσότερη μνήμη και να διαβάζει ενεργά από το δίσκο.

Αποδεικνύεται ότι εάν το Linux εξαντληθεί η ελεύθερη μνήμη (πέσει η πίεση μνήμης) και δεν υπάρχει ανταλλαγή, τότε να Όταν φτάσει ο δολοφόνος OOM, μπορεί να προκύψει μια πράξη εξισορρόπησης μεταξύ της εισαγωγής σελίδων στην προσωρινή μνήμη σελίδων και της εγγραφής τους πίσω στο δίσκο. Αυτό γίνεται από το kswapd, το οποίο με γενναιότητα ελευθερώνει όσο το δυνατόν περισσότερες σελίδες μνήμης για μετέπειτα διανομή.

Δυστυχώς, με μεγάλο φορτίο I/O σε συνδυασμό με μικρή ποσότητα ελεύθερης μνήμης, Το kswapd γίνεται το σημείο συμφόρησης ολόκληρου του συστήματος, γιατί είναι δεμένοι με αυτό όλα εκχωρήσεις (σφάλματα σελίδας) σελίδων μνήμης στο σύστημα. Αυτό μπορεί να συνεχιστεί για πολύ μεγάλο χρονικό διάστημα εάν οι διεργασίες δεν θέλουν πλέον να χρησιμοποιούν μνήμη, αλλά είναι σταθερές στην άκρη της αβύσσου του OOM-killer.

Το φυσικό ερώτημα είναι: γιατί ο δολοφόνος του OOM έρχεται τόσο αργά; Στην τρέχουσα επανάληψη του, το OOM killer είναι εξαιρετικά ανόητο: θα σκοτώσει τη διαδικασία μόνο όταν αποτύχει η προσπάθεια εκχώρησης μιας σελίδας μνήμης, π.χ. εάν αποτύχει το σφάλμα σελίδας. Αυτό δεν συμβαίνει για μεγάλο χρονικό διάστημα, επειδή το kswapd ελευθερώνει με γενναιότητα σελίδες μνήμης, απορρίπτοντας την προσωρινή μνήμη σελίδων (ολόκληρο το I/O του δίσκου στο σύστημα, στην πραγματικότητα) πίσω στο δίσκο. Πιο αναλυτικά, με μια περιγραφή των βημάτων που απαιτούνται για την εξάλειψη τέτοιων προβλημάτων στον πυρήνα, μπορείτε να διαβάσετε εδώ.

Αυτή η συμπεριφορά πρέπει να βελτιωθεί με πυρήνα Linux 4.6+.

Ιστορία 6. Τα pod κολλάνε σε κατάσταση εκκρεμότητας

Σε ορισμένα συμπλέγματα, στα οποία λειτουργούν πραγματικά πολλά λοβοί, αρχίσαμε να παρατηρούμε ότι τα περισσότερα από αυτά «κολλάνε» για πολύ μεγάλο χρονικό διάστημα στην πολιτεία Pending, αν και τα ίδια τα κοντέινερ Docker εκτελούνται ήδη στους κόμβους και μπορούν να εργαστούν με το χέρι.

Ταυτόχρονα, στο describe δεν υπάρχει τίποτα λάθος:

  Type    Reason                  Age                From                     Message
  ----    ------                  ----               ----                     -------
  Normal  Scheduled               1m                 default-scheduler        Successfully assigned sphinx-0 to ss-dev-kub07
  Normal  SuccessfulAttachVolume  1m                 attachdetach-controller  AttachVolume.Attach succeeded for volume "pvc-6aaad34f-ad10-11e8-a44c-52540035a73b"
  Normal  SuccessfulMountVolume   1m                 kubelet, ss-dev-kub07    MountVolume.SetUp succeeded for volume "sphinx-config"
  Normal  SuccessfulMountVolume   1m                 kubelet, ss-dev-kub07    MountVolume.SetUp succeeded for volume "default-token-fzcsf"
  Normal  SuccessfulMountVolume   49s (x2 over 51s)  kubelet, ss-dev-kub07    MountVolume.SetUp succeeded for volume "pvc-6aaad34f-ad10-11e8-a44c-52540035a73b"
  Normal  Pulled                  43s                kubelet, ss-dev-kub07    Container image "registry.example.com/infra/sphinx-exporter/sphinx-indexer:v1" already present on machine
  Normal  Created                 43s                kubelet, ss-dev-kub07    Created container
  Normal  Started                 43s                kubelet, ss-dev-kub07    Started container
  Normal  Pulled                  43s                kubelet, ss-dev-kub07    Container image "registry.example.com/infra/sphinx/sphinx:v1" already present on machine
  Normal  Created                 42s                kubelet, ss-dev-kub07    Created container
  Normal  Started                 42s                kubelet, ss-dev-kub07    Started container

Μετά από λίγο σκάψιμο, υποθέσαμε ότι το kubelet απλά δεν έχει χρόνο να στείλει όλες τις πληροφορίες σχετικά με την κατάσταση των pods και τις δοκιμές ζωντανότητας/ ετοιμότητας στον διακομιστή API.

Και αφού μελετήσαμε τη βοήθεια, βρήκαμε τις ακόλουθες παραμέτρους:

--kube-api-qps - QPS to use while talking with kubernetes apiserver (default 5)
--kube-api-burst  - Burst to use while talking with kubernetes apiserver (default 10) 
--event-qps - If > 0, limit event creations per second to this value. If 0, unlimited. (default 5)
--event-burst - Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. Only used if --event-qps > 0 (default 10) 
--registry-qps - If > 0, limit registry pull QPS to this value.
--registry-burst - Maximum size of bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry-qps. Only used if --registry-qps > 0 (default 10)

Όπως φαίνεται, οι προεπιλεγμένες τιμές είναι αρκετά μικρές, και στο 90% καλύπτουν όλες τις ανάγκες... Ωστόσο, στην περίπτωσή μας αυτό δεν ήταν αρκετό. Επομένως, ορίζουμε τις ακόλουθες τιμές:

--event-qps=30 --event-burst=40 --kube-api-burst=40 --kube-api-qps=30 --registry-qps=30 --registry-burst=40

... και επανεκκινήσαμε τα kubelets, μετά από την οποία είδαμε την ακόλουθη εικόνα στα γραφήματα των κλήσεων προς τον διακομιστή API:

6 διασκεδαστικά σφάλματα συστήματος στη λειτουργία του Kubernetes [και η λύση τους]

... και ναι, όλα άρχισαν να πετάνε!

PS

Για τη βοήθειά τους στη συλλογή σφαλμάτων και στην προετοιμασία αυτού του άρθρου, εκφράζω τη βαθιά μου ευγνωμοσύνη στους πολυάριθμους μηχανικούς της εταιρείας μας, και ιδιαίτερα στον συνάδελφό μου από την ομάδα Έρευνας και Ανάπτυξης Andrey Klimentyev (zuzzas).

ΜΑΔ

Διαβάστε επίσης στο blog μας:

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο