AWS ElasticBeanstalk Docker-Thin-Pool wird voll und bewirkt eine erneute Bereitstellung des Dateisystems als schreibgeschützt?


9

Ich kann nicht herausfinden, wie AWS seinen Docker-Thin-Pool auf ElasticBeanstalk einrichtet und wie er gefüllt wird. Mein Docker Thin Pool füllt sich irgendwie und führt zum Absturz meiner Apps, wenn sie versuchen, auf die Festplatte zu schreiben.

Dies ist aus dem Inneren des Containers:

>df -h
>     /dev/xvda1                  25G  1.4G   24G   6%

Dem EBS ist tatsächlich eine 25-GB-Festplatte zugeordnet. 1,6 GB sind das, was du -sh /zurückkehrt.

Draußen in EC2 beginnt es harmlos genug ... (via lvs)

LV          VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
docker-pool docker twi-aot--- 11.86g             37.50  14.65

Das Dateisystem wird jedoch bald wieder schreibgeschützt bereitgestellt. via dmesg:

[2077620.433382] Buffer I/O error on device dm-4, logical block 2501385
[2077620.437372] EXT4-fs warning (device dm-4): ext4_end_bio:329: I/O error -28 writing to inode 4988708 (offset 0 size 8388608 starting block 2501632)
[2077620.444394] EXT4-fs warning (device dm-4): ext4_end_bio:329: I/O error     [2077620.473581] EXT4-fs warning (device dm-4): ext4_end_bio:329: I/O error -28 writing to inode 4988708 (offset 8388608 size 5840896 starting block 2502912)

[2077623.814437] Aborting journal on device dm-4-8.
[2077649.052965] EXT4-fs error (device dm-4): ext4_journal_check_start:56: Detected aborted journal
[2077649.058116] EXT4-fs (dm-4): Remounting filesystem read-only

Zurück im EC2-Instanzland meldet Docker Folgendes: (von docker info)

Pool Name: docker-docker--pool
Pool Blocksize: 524.3 kB
Base Device Size: 107.4 GB
Backing Filesystem: ext4
Data file:
Metadata file:
Data Space Used: 12.73 GB
Data Space Total: 12.73 GB
Data Space Available: 0 B
Metadata Space Used: 3.015 MB
Metadata Space Total: 16.78 MB
Metadata Space Available: 13.76 MB
Thin Pool Minimum Free Space: 1.273 GB

LVS gibt diese Informationen aus:

  --- Logical volume ---
  LV Name                docker-pool
  VG Name                docker
  LV UUID                xxxxxxxxxxxxxxxxxxxxxxxxxxxx
  LV Write Access        read/write
  LV Creation host, time ip-10-0-0-65, 2017-03-25 22:37:38 +0000
  LV Pool metadata       docker-pool_tmeta
  LV Pool data           docker-pool_tdata
  LV Status              available
  # open                 2
  LV Size                11.86 GiB
  Allocated pool data    100.00%
  Allocated metadata     17.77%
  Current LE             3036
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2

Was ist dieser dünne Pool, warum füllt er sich und wie kann ich ihn davon abhalten? Wenn ich mehr als 20 GB aus dem Container auf meinem / Volume frei habe, warum werden dann neue Schreibvorgänge gestoppt? Soweit ich das beurteilen kann, ist es nicht mit Dateien verbunden, in die meine Programme schreiben.

Vielen Dank!

Antworten:


8

Der .ebextensionsVorschlag von David Ellis hat für mich funktioniert. Ich kann seine Antwort nicht kommentieren, aber ich wollte hinzufügen, dass Sie ein neues EBS-Volume erstellen können, anstatt einen Snapshot zu verwenden. Um ein 40-GB-EBS-Volume bereitzustellen, habe ich Folgendes verwendet:

option_settings:
  - namespace: aws:autoscaling:launchconfiguration
    option_name: BlockDeviceMappings
    value: /dev/xvdcz=:40:true

Siehe auch diese Dokumentation , die ein Beispiel für die Zuordnung eines neuen 100-GB-EBS-Volumes enthält /dev/sdh.

Das trueam Ende bedeutet "Löschen bei Beenden".

Ich habe ein neues .ebextensionsVerzeichnis erstellt, das eine ebs.configDatei mit dem obigen Code enthält, und dieses Verzeichnis dann zusammen mit meinem komprimiert Dockerrun.aws.json. Beachten Sie, dass sich die Dockerrun-Datei auf der obersten Ebene der Zip-Datei befinden darf und nicht in einem Unterverzeichnis.

Verwenden Sie lsblkdie fehlerhafte Instanz , um herauszufinden, wo Elastic Beanstalk das Volume bereitstellt. Es war auch /dev/xvdczfür mich, vielleicht ist das der Standard.


2

Wir wurden von demselben Problem getroffen. Die Hauptursache scheint darin zu liegen, dass Docker seine Speicher-Engine ( devicemapperstandardmäßig Thin Provisioning in Elastic Beanstalk) nicht mit den discardOptionen bereitstellt, die wiederum Blöcke füllen, bis sie kaputt gehen.

Ich konnte keine definitive Lösung dafür finden, aber hier ist eine Problemumgehung (siehe diesen Kommentar ), die ich für betroffene Instanzen verwenden konnte:

docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/

1
Vielen Dank. Ich kam zu dem gleichen Schluss und stellte schließlich den gesamten Datenspeicher auf EBS um. Ich denke, das ist ein bisschen albern für wirklich vorübergehende / temporäre Dateien (die immer wieder überschrieben werden), aber hey, was können Sie tun?
std''OrgnlDave

Es stellt sich heraus, dass ein Cronjob dafür in der EC2-Dokumentation enthalten ist, aber in Beanstalk-Dokumenten nicht erwähnt wird. Auf Beanstalk müssten Sie sehen, ob Sie einen Haken für eine spezielle Crontab oder etwas hinzufügen könnten.
std''OrgnlDave

Oh, schön zu wissen! Würde es Ihnen etwas ausmachen, den Link hier als Referenz zu kopieren?
FX

1
docs.aws.amazon.com/AmazonECS/latest/developerguide/… Suche nach "trim". Nicht gerade eine einfache Erwähnung einer sehr offensichtlichen Sache
std''OrgnlDave

1
@ ThomasGrainger .ebextensions-Dateien. Einer der schmerzhaftesten Hintern nervt mögliche Kreationen der Welt. Sie werden beim Systemstart ausgeführt.
std''OrgnlDave

2

Ich habe die Vorschläge in der AWS-Dokumentation befolgt und jetzt funktioniert alles.
Aber ich musste zwei Lösungen kombinieren: Speicherplatz erhöhen und Cronjob hinzufügen, um alte Dateien zu entfernen.
Folgendes habe ich getan.

Zuerst habe ich die Lautstärke so geändert xvdcz, dass 50 GB anstelle von 12 GB verwendet werden. Das ist der Speicher, auf dem wir sehen können docker system info. In meinem Fall war es immer voll, weil ich jeden Tag viele Dateien hochlade.

.ebextensions / blockdevice-xvdcz.config

option_settings:
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: /dev/xvdcz=:50:true

Nachdem ich einen Cronjob hinzugefügt habe, um meine gelöschten Dateien zu bereinigen, die nicht mehr verwendet wurden. Es war erforderlich, weil Docker sie aus irgendeinem Grund immer noch behielt. In meinem Fall ist es einmal am Tag genug. Wenn Sie mehr Uploads als ich haben, können Sie den Cronjob so konfigurieren, dass er so oft ausgeführt wird, wie Sie benötigen.

.ebextensions / cronjob.config

files:
    "/etc/cron.d/mycron":
        mode: "000644"
        owner: root
        group: root
        content: |
            0 23 * * * root /usr/local/bin/remove_old_files.sh

     "/usr/local/bin/remove_old_files.sh":
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/bin/bash
            docker ps -q | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ sudo fstrim /proc/Z/root/
            exit 0

 commands:
    remove_old_cron:
        command: "rm -f /etc/cron.d/*.bak"

Quelle: https://docs.aws.amazon.com/pt_br/elasticbeanstalk/latest/dg/create_deploy_docker.container.console.html#docker-volumes


1

AWS ElasticBeanstalk Docker-Abschnitt Umgebungskonfiguration dokumentiert, wie es funktioniert:

Um die Leistung zu verbessern, konfiguriert Elastic Beanstalk zwei Amazon EBS-Speichervolumes für die EC2-Instanzen Ihrer Docker-Umgebung. Zusätzlich zu dem für alle Elastic Beanstalk-Umgebungen bereitgestellten Root-Volume wird ein zweites 12-GB-Volume mit dem Namen xvdcz für die Image-Speicherung in Docker-Umgebungen bereitgestellt.

Wenn Sie mehr Speicherplatz oder mehr IOPS für Docker-Images benötigen, können Sie das Image-Speichervolumen mithilfe der Konfigurationsoption BlockDeviceMapping im Namespace aws: autoscaling: launchconfiguration anpassen.

Die folgende Konfigurationsdatei erhöht beispielsweise die Größe des Speichervolumens mit 500 bereitgestellten IOPS auf 100 GB:

Beispiel .ebextensions / blockdevice-xvdcz.config

option_settings:
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: /dev/xvdcz=:100::io1:500

Wenn Sie die Option BlockDeviceMappings verwenden, um zusätzliche Volumes für Ihre Anwendung zu konfigurieren, sollten Sie eine Zuordnung für xvdcz hinzufügen, um sicherzustellen, dass diese erstellt wird. Im folgenden Beispiel werden zwei Volumes konfiguriert, das Image-Speicher-Volume xvdcz mit Standardeinstellungen und ein zusätzliches 24-GB-Anwendungs-Volume mit dem Namen sdh:

Beispiel .ebextensions / blockdevice-sdh.config

option_settings:
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: /dev/xvdcz=:12:true:gp2,/dev/sdh=:24

0

Ich habe über einen Tag lang meinen Kopf gegen dieses Problem geschlagen und es schließlich herausgefunden.

AWS verwendet das devicemapperBackend und erstellt ein 12-GB-SSD-Volume, das für die Docker-Images bereitgestellt und verwendet wird. Sie müssen das Volume überschreiben, das über das ElasticBeanstalk-Erweiterungskonzept bereitgestellt und über die CLI bereitgestellt werden soll (dies ist leider nicht über die GUI möglich).

Dockerrun.aws.jsonErstellen Sie in dem Verzeichnis, in dem Sie Ihre Datei haben, ein Verzeichnis mit dem Namen .ebextensionsund erstellen Sie dann eine Datei, die darin endet .config. Ich habe meine angerufen 01.correctebsvolume.config. Fügen Sie dann den folgenden Inhalt ein:

option_settings: - namespace: aws:autoscaling:launchconfiguration option_name: BlockDeviceMappings value: /dev/xvdcz=snap-066cZZZZZZZZ:40:true:gp2

Ich ssh'ed in eine meiner fehlerhaften Boxen direkt und stellte fest, dass es montiert wurde /dev/xvdcz. Es kann für Sie anders sein. Das snap-066cZZZZZZZZmuss eine gültige Snapshot-ID sein. Ich habe ein AMI-Image der fehlerhaften Instanz erstellt und den dabei erstellten Snapshot verwendet. Das 40ist, wie viele GB das Volumen sein wird, also ersetzen Sie, was Sie brauchen. Ich weiß nicht, was die trueoder gp2tun, aber sie stammen aus den AMI-Image-Block-Gerätedaten, also habe ich sie behalten.

Die Magie namespaceund option_namekommen von hier in die Dokumentation.


Also ... wird das Root-Docker-Volume auf EBS anstelle des Thin Pools bereitgestellt?
std''OrgnlDave

Der Docker-Thinpool ist für die Ausführung auf einem EBS-Volume (genau 12 GB) eingerichtet. Dies ersetzt dieses Volume durch ein größeres und ist der am wenigsten invasive Weg, um es zum Laufen zu bringen.

Oh, die von Amazon eingerichtete Thinpool-Konfiguration ist für 100 GB vorgesehen. Dies ist also die Obergrenze für diese Antwort, und ich bin mir nicht sicher, ob dies angepasst werden kann.

0

Nur eine Vergrößerung der Festplatte löst das Problem nicht, es tritt nur später ein Fehler auf. AWS empfiehlt, Ihrem Container eine neue Festplatte zuzuordnen, damit das Erstellen / Löschen von Dateien keine Auswirkungen auf den Docker Poll Layer hat.

Ich schaue es gerade an, ich habe es noch nicht getestet, aber die Lösung, auf die ich stoße, ist dies auf meiner blockdevice.config

commands:
  01mount:
    command: "mount /dev/sdh /tmp"
option_settings:
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: /dev/xvda=:16:true:gp2,/dev/xvdcz=:12:true:gp2,/dev/sdh=:12:true:ephemeral0

Schätzen Sie alle Kommentare.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.