AWS ElasticBeanstalk docker-thin-pool si riempie e causa il re-mount del filesystem in sola lettura?


10

Non riesco a capire come AWS abbia configurato il "thin pool" Docker su ElasticBeanstalk e come venga riempito. Il mio thin pool docker si sta riempiendo in qualche modo e sta causando l'arresto anomalo delle mie app quando provano a scrivere su disco.

Questo è dall'interno del contenitore:

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

L'EBS, infatti, ha un disco da 25 GB suddiviso su di esso; 1.6 GB è ciò che du -sh /ritorna.

Fuori in EC2, inizia abbastanza innocuamente ... (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

Tuttavia, il filesystem verrà presto reinstallato in sola lettura. 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

Ritornando all'istanza EC2, Docker riporta questo: (da 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 scarica queste informazioni:

  --- 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

Che cos'è questo thin pool, perché si riempie e come posso impedirlo? Inoltre, se ho 20+ GB liberi dall'interno del contenitore sul mio / volume, perché interrompe le nuove scritture? Per quanto ne so, non è collegato ai file su cui stanno scrivendo i miei programmi.

Grazie!

Risposte:


8

Il .ebextensionssuggerito da David Ellis ha funzionato per me. Non riesco a commentare la sua risposta, ma volevo aggiungere che è possibile creare un nuovo volume EBS invece di utilizzare un'istantanea. Per montare un volume EBS da 40 GB, ho usato quanto segue:

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

Vedi anche questa documentazione , che ha un esempio di mappatura di un nuovo volume EBS da 100 GB /dev/sdh.

Alla truefine significa "elimina al termine".

Ho creato una nuova .ebextensionsdirectory contenente un ebs.configfile con il codice sopra, quindi ho compresso quella directory insieme a my Dockerrun.aws.json. Si noti che il file Dockerrun deve trovarsi al livello superiore dello zip, non all'interno di una sottodirectory.

Per trovare il punto in cui Elastic Beanstalk sta montando il volume, utilizzare lsblksull'istanza non riuscita. È stato anche /dev/xvdczper me, quindi forse questo è lo standard.


3

Siamo stati colpiti dallo stesso problema. La causa principale sembra essere Docker che non monta il suo motore di archiviazione (thin provisioning devicemapperper impostazione predefinita in Elastic Beanstalk) con le discardopzioni, che a loro volta riempiono i blocchi fino a quando non si rompono.

Non sono riuscito a trovare una soluzione definitiva a questo, ma ecco una soluzione alternativa (vedi questo commento ) che sono stato in grado di utilizzare su istanze interessate:

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

1
Grazie. Sono arrivato alla stessa conclusione e ho finito per cambiare tutta l'archiviazione dei dati su EBS. Penso che sia un po 'sciocco per i file veramente transitori / temporanei (che continuano a essere sovrascritti) ma hey cosa puoi o?
std''OrgnlDave,

Si scopre che un cronjob per questo è nella documentazione EC2, ma non è menzionato nei documenti di Beanstalk. Su Beanstalk dovresti vedere se potresti aggiungere un hook per un crontab speciale o qualcosa del genere.
std''OrgnlDave,

Oh, bello da sapere! Ti dispiacerebbe copiare qui il link come riferimento?
FX

1
docs.aws.amazon.com/AmazonECS/latest/developerguide/… cerca "trim". Non esattamente una semplice menzione di una cosa molto ovvia
std''OrgnlDave,

1
@ThomasGrainger .ebextensions file. Una delle creazioni più fastidiose nel culo possibili al mondo. Funzionano all'avvio del sistema.
std''OrgnlDave

2

Ho seguito i suggerimenti forniti sulla documentazione di AWS e ora tutto funziona.
Ma ho dovuto combinare due soluzioni: aumentare lo spazio e aggiungere cronjob per rimuovere i vecchi file.
Ecco cosa ho fatto.

Innanzitutto, ho modificato il volume xvdczper utilizzare 50 GB anziché 12 GB. Questo è lo spazio di archiviazione su cui possiamo vedere docker system info. Nel mio caso è stato sempre pieno perché carico molti file ogni giorno.

.ebextensions / BlockDevice-xvdcz.config

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

Dopo aver aggiunto un cronjob per pulire i miei file eliminati che non erano più utilizzati. Era necessario perché Docker li teneva ancora per qualche motivo. Nel mio caso una volta al giorno è abbastanza. Se hai più caricamenti di me, puoi configurare il cronjob per eseguire quante volte hai bisogno.

.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"

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


1

Sezione docker di AWS elasticbeanstalk Ambiente La configurazione documenta come funziona:

Per prestazioni migliori, Elastic Beanstalk configura due volumi di archiviazione Amazon EBS per le istanze EC2 dell'ambiente Docker. Oltre al volume di root predisposto per tutti gli ambienti Elastic Beanstalk, un secondo volume da 12 GB denominato xvdcz è predisposto per l'archiviazione di immagini negli ambienti Docker.

Se hai bisogno di più spazio di archiviazione o maggiore IOPS per le immagini Docker, puoi personalizzare il volume di archiviazione delle immagini usando l'opzione di configurazione BlockDeviceMapping nello spazio dei nomi aws: autoscaling: launchconfiguration.

Ad esempio, il seguente file di configurazione aumenta la dimensione del volume di archiviazione a 100 GB con 500 IOPS con provisioning:

Esempio .ebextensions / blockdevice-xvdcz.config

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

Se si utilizza l'opzione BlockDeviceMappings per configurare volumi aggiuntivi per l'applicazione, è necessario includere un mapping per xvdcz per assicurarsi che sia stato creato. L'esempio seguente configura due volumi, il volume di archiviazione delle immagini xvdcz con le impostazioni predefinite e un ulteriore volume dell'applicazione da 24 GB denominato sdh:

Esempio .ebextensions / blockdevice-sdh.config

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

0

Ho battuto la testa contro questo problema per oltre un giorno e alla fine l'ho capito.

AWS utilizza il devicemapperback-end e crea un volume SSD da 12 GB che monta e utilizza per le immagini docker. Devi sovrascrivere il volume che monterebbe attraverso il concetto di estensioni elasticbeanstalk e distribuirlo tramite la CLI (sfortunatamente non c'è modo di farlo tramite la loro GUI).

Nella directory in cui hai il tuo Dockerrun.aws.jsonfile, crea una directory chiamata .ebextensionse quindi crea un file che termina al suo .configinterno. Ho chiamato il mio 01.correctebsvolume.config. Quindi inserisci i seguenti contenuti:

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

Mi sono imbattuto in uno dei miei box falliti direttamente e ho scoperto che stava montando /dev/xvdcz. Esso può essere diverso per voi. Le snap-066cZZZZZZZZdeve essere un ID valido snapshot. Ho creato un'immagine AMI dell'istanza non riuscita e ho usato l'istantanea che ha creato nel processo. Il 40numero di GB sarà il volume, quindi sostituisci ciò di cui hai bisogno. Non so cosa trueo gp2cosa facciano, ma provenivano dai dati del dispositivo di blocco delle immagini AMI, quindi li ho conservati.

La magia namespacee option_namevieni da qui nella documentazione.


Quindi ... questo monta il volume Docker di root su EBS invece del thin pool?
std''OrgnlDave

Il thinpool docker è impostato per funzionare su un volume EBS (esattamente di 12 GB). Questo sostituisce quel volume con uno più grande ed è il modo meno invasivo per farlo funzionare.

Oh, la configurazione thinpool che Amazon imposta è per 100 GB, quindi questo è il limite massimo per questa risposta, e non sono sicuro che possa essere regolato.

0

L'aumento della dimensione del disco non risolverà il problema, ma si limiterà a errori in seguito. AWS consiglia di mappare un nuovo disco sul contenitore in modo che qualsiasi file di creazione / eliminazione file non influisca sul livello polling Docker.

Attualmente lo sto guardando, non ho ancora testato ma la soluzione che ho riscontrato è avere questo sul mio 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

Apprezzo qualsiasi commento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.