Docker-Speicherüberwachung und Stresstestmethoden

Docker-Speicherüberwachung und Stresstestmethoden

Der ausgeführte Docker-Container zeigt, dass der Speicher erschöpft ist, und der Containerspeicher ist erschöpft, ohne dass er neu gestartet wird. Durch Überprüfen des Hintergrunds wird festgestellt, dass der Prozess nicht viel Speicher belegt. Der Speicher wird von Cadvisor überwacht und mithilfe der Cadvisor-Seitenberechnungsmethode berechnet. Deshalb habe ich beschlossen, etwas zur Speicherberechnung von Docker zu recherchieren.

Docker-Version:

Kunde:
 Version: 1.12.6
 API-Version: 1.24
 Go-Version: go1.6.4
 Git-Commit: 78d1802
 Gebaut: Di 10 Jan 20:20:01 2017
 Betriebssystem/Architektur: linux/amd64

Server:
 Version: 1.12.6
 API-Version: 1.24
 Go-Version: go1.6.4
 Git-Commit: 78d1802
 Gebaut: Di 10 Jan 20:20:01 2017
 Betriebssystem/Architektur: linux/amd64

Kubernetes-Version:

Client-Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.2+coreos.0", GitCommit:"4c0769e81ab01f47eec6f34d7f1bb80873ae5c2b", GitTreeState:"clean", BuildDate:"2017-10-25T16:24:46Z", GoVersion:"go1.8.3", Compiler:"gc", Plattform:"linux/amd64"}
Serverversion: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.2+coreos.0", GitCommit:"4c0769e81ab01f47eec6f34d7f1bb80873ae5c2b", GitTreeState:"clean", BuildDate:"2017-10-25T16:24:46Z", GoVersion:"go1.8.3", Compiler:"gc", Plattform:"linux/amd64"}

1. Erstellen Sie eine Pod-YAML-Datei, verwenden Sie das Busybox-Image zum Testen und legen Sie ein Limit von 2 Kernen und 2 GB Speicher für das Image fest

[docker@k8s busybox]$ cat busybox.yaml


API-Version: v1
Art: Pod
Metadaten:
 Name: Busybox
 Namespace: Standard
Spezifikation:
 Behälter:
 - Bild: registry.dcos:8021/public/busybox:latest
 Befehl:
  - schlafen
  - "3600"
 imagePullPolicy: IfNotPresent
 Name: Busybox
 Ressourcen:
  Grenzen:
  Zentralprozessor: "2"
  Speicher: 2Gi
  Anfragen:
  CPU: 100 M
  Speicher: 64Mi
 restartPolicy: Immer

2. Generieren Sie den Busybox-Dienst über den Befehl kubectl

[docker@k8s busybox]$ kubectl create -f busybox.yaml


Pod "Busybox" erstellt

3. Gehen Sie in das Verzeichnis /sys/fs/cgroup/memory des Containers und überprüfen Sie die folgenden Dateien mit ls

-rw-r--r-- 1 root root 0 31. Mai 03:18 cgroup.clone_children
--w--w--w- 1 root root 0 31. Mai 03:18 cgroup.event_control
-rw-r--r-- 1 root root 0 31. Mai 03:18 cgroup.procs
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.failcnt
--w------ 1 root root 0 31. Mai 03:18 memory.force_empty
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.numa_stat
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.oom_control
---------- 1 root root 0 31. Mai 03:18 memory.pressure_level
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 31. Mai 03:18 memory.stat
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.swappiness
-r--r--r-- 1 root root 0 31. Mai 03:18 Speicherverbrauch in Bytes
-rw-r--r-- 1 root root 0 31. Mai 03:18 memory.use_hierarchy
-rw-r--r-- 1 root root 0 31. Mai 03:18 notify_on_release
-rw-r--r-- 1 root root 0 31. Mai 03:18 Aufgaben

Wir konzentrieren uns hauptsächlich auf mehrere Dateien

Dateiname Bedeutung
Speicherverbrauch in Bytes Die Menge des verwendeten Speichers (einschließlich Cache und Puffer) (Bytes), entspricht used_meme in Linux
Speicherlimit in Bytes Die Gesamtmenge des begrenzten Speichers (Bytes), entspricht total_mem in Linux
Speicher.failcnt Anzahl fehlgeschlagener Speicheranforderungen
Speicher.stat Speicherbezogener Status

Der Inhalt der Datei memory.stat

Felder Bedeutung
Cache Seitencache, einschließlich tmpfs (shmem), in Bytes
rss Anonymer und Swap-Cache, ausgenommen tmpfs (shmem), in Bytes
zugeordnete_Datei Größe der im Speicher abgebildeten Datei, einschließlich tmpfs (shmem), in Bytes
pgpgin Anzahl der im Speicher abgelegten Seiten
pgpgout Anzahl der aus dem Speicher gelesenen Seiten
tauschen Die Menge des verwendeten Swaps in Bytes
aktiv_anon Anonyme und Swap-Caches, einschließlich tmpfs (shmem), in Bytes in der aktiven LRU-Liste (Least-Recently-Used)
inactive_anon Anonyme und Swap-Caches in der inaktiven LRU-Liste, einschließlich tmpfs (shmem), in Bytes
aktive_datei Dateigestützter Speicher in der aktiven LRU-Liste, in Bytes
inaktive_Datei Dateigestützter Speicher in der inaktiven LRU-Liste, in Bytes
unbesiegbar Nicht erneuerbarer Speicher in Bytes
hierarchisches_Speicherlimit Speicherlimit der Ebene, die die Speicher-Cgroup enthält, in Bytes
hierarchisches_memsw_limit Speicher- und Swap-Grenzen für die Ebene, die die Speicher-Cgroup enthält, in Bytes

Datei „memory.limit_in_bytes“ anzeigen

/sys/fs/cgroup/memory # cat Speicher.limit_in_bytes 
2147483648

Das Speicherlimit des Computing-Containers beträgt 2 GB, was dem in der YAML-Datei definierten Speicherlimit entspricht. Sehen Sie sich die Datei memory.usag_in_bytes an

/sys/fs/cgroup/memory # cat Speicherverbrauch in Bytes 
2739376

Verwenden Sie die Container-ID von Docker Stats, um die Speichernutzung des Containers anzuzeigen, die mit den Daten von memory.usage_in_bytes übereinstimmt.

4. Verwenden Sie den Befehl dd, um schnell eine 1,5 g große Datei zu generieren

~ # dd wenn=/dev/zero von=test bs=1M Anzahl=1500
1500+0 Datensätze in
1500+0 Datensätze verfügbar
1572864000 Bytes (1,5 GB) kopiert, 1,279989 Sekunden, 1,1 GB/s

Verwenden Sie die Container-ID von Docker Stats, um den vom Container belegten Speicher erneut anzuzeigen

Zeigen Sie die Datei memory.usage_in_bytes an

/sys/fs/cgroup/memory # cat Speicherverbrauch in Bytes 
1619329024

Es wurde festgestellt, dass der vom Container belegte Speicher 1,5 g erreicht hat. Überprüfen Sie memory.stat

/sys/fs/cgroup/memory # cat speicher.stat
Cache 1572868096
rss 147456
rss_huge 0
zugeordnete_Datei 0
schmutzig 1572868096
Rückschreiben 0
tauschen 0
pgpgin 384470
pgpgout 433
pgfehler 607
0
inactive_anon 77824
active_anon 12288
inaktive_Datei 1572864000
aktive_datei 4096
nicht räumbar 0
hierarchisches_Speicherlimit 2147483648
hierarchisches_memsw_limit 4294967296
Gesamtcache 1572868096
total_rss 147456
total_rss_huge 0
total_mapped_file 0
total_dirty 1572868096
total_writeback 0
Gesamtswap 0
Gesamt_pgpgin 384470
total_pgpgout 433
total_pgfault 607
total_pgmajfault 0
total_inactive_anon 77824
total_active_anon 12288
total_inactive_file 1572864000
Gesamtanzahl aktiver Dateien 4096
total_unbesiegbar 0

Das Cache-Feld in der Datei memory.stat fügt 1,5 g hinzu, und das Feld inactive_file beträgt 1,5 g, sodass der von dd generierte Dateicache auf der inactive_file berechnet wird. Dies führt dazu, dass die Speicherüberwachung des Containers hoch ist, da der Cache wiederverwendbar ist und nicht den vom Prozess belegten Speicher widerspiegelt.

Generell lässt sich der Überwachungsspeicher nach folgender Formel berechnen:

active_anon + inactive_anon = anonymer Speicher + Dateicache für tmpfs + Swap-Cache
daher
active_anon + inactive_anon ≠ rss, weil RSS kein tmpfs enthält.
active_file + inactive_file = Cache - Größe des tmpfs

Die tatsächliche Speichernutzung wird also wie folgt berechnet:

tatsächlich genutzter Speicher = Speicherverbrauch in Bytes – (aktive Datei + inaktive Datei)

5. Stresstests

(1) Bereiten Sie das Tomcat-Image und das JMeter-Stresstest-Tool vor. Die Tomcat-YAML-Datei lautet wie folgt

API-Version: Erweiterungen/v1beta1
Art: Bereitstellung
Metadaten:
 Name: Tomcat-Bereitstellung
Spezifikation:
 Replikate: 1
 Vorlage:
 Metadaten:
  Beschriftungen:
  App: Tomcat
 Spezifikation:
  Behälter:
  - Name: Kater
  Bild: registy.dcos:8021/public/tomcat:8
  Häfen:
  - ContainerPort: 8080
  Ressourcen:
   Grenzen:
   Zentralprozessor: "1"
   Speicher: 300Mi
--- 
API-Version: v1
Art: Dienstleistung
Metadaten:
 Beschriftungen:
 Name: Kater
 Name: Kater
 Namespace: Standard
Spezifikation:
 Häfen:
 - Name: Kater
 Port: 8080
 Protokoll: TCP
 ZielPort: 8080
 Typ: NodePort 
 Wähler:
 App: Tomcat

Begrenzen Sie in der YAML-Datei den vom Tomcat-Image verwendeten Speicher auf 300 Mi und führen Sie den Befehl zum Generieren der Datei aus. Verwenden Sie Docker-Statistiken, um die Speichernutzung des Tomcat-Containers ohne Last anzuzeigen.

(2) Extrahieren Sie den Service-NodePort von Tomcat

[docker@ecs-5f72-0006 ~]$ kubectl get svc tomcat -o=custom-columns=nodePort:.spec.ports[0].nodePort
KnotenPort
31401

(3) Melden Sie sich auf der offiziellen JMeter-Website an, um das Stresstest-Tool herunterzuladen

Führen Sie das JMeter-Tool unter Windows aus, wechseln Sie zum Bin-Verzeichnis, klicken Sie auf „JMeter ausführen“ und konfigurieren Sie JMeter wie folgt:

Nachdem Sie die Testoptionen konfiguriert haben, klicken Sie auf die Schaltfläche „Start“, um den Stresstest zu starten. Überprüfen Sie die Speichernutzung des Containers anhand der Docker-Statistiken und stellen Sie fest, ob das Limit erreicht wurde.

Mithilfe von „kubectl get pods“ haben wir den Laufstatus des Pods überprüft und festgestellt, dass Tomcat beendet wurde, weil der Speicher das Limit überschritten hat.

Zusammenfassen

Es gab schon immer Probleme mit der Speicherüberwachung von Docker Stats. Docker bezieht Cache/Puffer in Speicherberechnungen ein, was zu Missverständnissen führt. Die Berechnungsmethode des Docker-Speichers ist dieselbe wie die der Linux-Speichernutzung, die auch Cache/Puffer umfasst.

Der Cache ist jedoch wiederverwendbar und wird häufig bei E/A-Anfragen verwendet. Dabei wird der Speicher genutzt, um Daten freizugeben, auf die zur Verbesserung der Systemleistung erneut zugegriffen werden kann.

Auf dem offiziellen GitHub haben viele Leute Probleme mit der Speicherüberwachung gemeldet. Erst in der Docker-Version 17.06 wurde dieses Problem durch Docker-Statistiken gelöst.

Dies lässt die Anzeige der Docker-Statistiken jedoch nur normal aussehen. Beim Aufrufen des Containers zur Überprüfung der Speichernutzung ist der Cache immer noch enthalten. Wenn die von cadvisor gesammelten Daten direkt verwendet werden, ist der Cache immer noch enthalten.

Durch einen Stresstest von Docker haben wir schließlich herausgefunden, dass der Pod neu gestartet wird, wenn der Stresstest die Speichergrenze des Programms erreicht. Dies erklärt auch, warum bei Verwendung der Docker-Überwachung der Pod nicht neu gestartet wird, selbst wenn der Speicher zu 99 % oder mehr belegt ist. Ein beträchtlicher Teil des Speichers wird vom Cache belegt.

Das Obige ist meine persönliche Erfahrung. Ich hoffe, es kann Ihnen als Referenz dienen. Ich hoffe auch, dass Sie 123WORDPRESS.COM unterstützen werden. Sollten dennoch Fehler oder unvollständige Überlegungen vorliegen, freue ich mich über eine Korrektur.

Das könnte Sie auch interessieren:
  • Lösung für den ES-Speicherüberlauf beim Starten von Docker
  • Docker View JVM-Speichernutzung
  • Docker View-Prozess, Speicher und Cup-Verbrauch
  • Problem „Nicht genügend Speicher“ und Lösung, wenn Docker Elasticsearch startet
  • So begrenzen Sie den für einen Container in Docker verfügbaren Speicher
  • Docker führt Vorgänge mit dem angegebenen Speicher aus

<<:  Grundlegende Verwendung von exists, in und any in MySQL

>>:  Vergessen Sie nicht, den HTML-Tag zu schließen

Artikel empfehlen

Zusammenfassung verschiedener Methoden zur JS-Datentyperkennung

Inhaltsverzeichnis Hintergrund Welche Methoden gi...

So ändern Sie die Ubuntu-Quellliste (Quellliste) - detaillierte Erklärung

Einführung Die Standardquelle von Ubuntu ist kein...

So verwenden Sie den Linux-Befehl md5sum

01. Befehlsübersicht md5sum - MD5-Prüfcode berech...

Objektorientierte JavaScript-Implementierung eines Lupengehäuses

In diesem Artikel wird der spezifische Code der o...

Einführung in CSS-Stileinführungsmethoden und ihre Vor- und Nachteile

Drei Möglichkeiten, CSS einzuführen 1. Inline-Sti...

Schritte zum Erstellen des Projekts vite+vue3+element-plus

Verwenden Sie vite, um ein vue3-Projekt zu erstel...

Uniapps Erfahrung in der Entwicklung kleiner Programme

1. Erstellen Sie ein neues UI-Projekt Zunächst ei...

Vollständiges Beispiel einer Vue-Polling-Request-Lösung

Verständnis von Umfragen Tatsächlich liegt der Sc...

So implementieren Sie Lastenausgleich in MySQL

Vorwort MySQL ist ein schnelles, leistungsstarkes...

Erste Schritte mit GDB unter Linux

Vorwort gdb ist ein sehr nützliches Debugging-Too...