AWS ElasticBeanstalk docker-thin-pool se remplit et provoque le remontage du système de fichiers en lecture seule?

9

Je ne peux pas comprendre comment AWS configure leur `` pool léger '' Docker sur ElasticBeanstalk et comment il se remplit. Mon pool mince de dockers se remplit d'une manière ou d'une autre et provoque le blocage de mes applications lorsqu'elles essaient d'écrire sur le disque.

C'est de l'intérieur du conteneur:

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

L'EBS dispose en fait d'un disque de 25 Go qui lui est alloué; 1,6 Go est ce qui du -sh /revient.

Dehors en EC2, ça commence assez innocemment ... (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

Cependant, le système de fichiers sera bientôt remonté en lecture seule. 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

De retour dans l'instance EC2, Docker rapporte ceci: (à partir de 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 vide ces informations:

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

Qu'est-ce que ce bassin mince, pourquoi se remplit-il et comment puis-je l'empêcher de le faire? De plus, si j'ai plus de 20 Go d'espace libre à l'intérieur du conteneur sur mon / volume, pourquoi arrête-t-il les nouvelles écritures? Autant que je sache, il n'est pas connecté aux fichiers sur lesquels mes programmes écrivent.

Je vous remercie!

std''OrgnlDave
la source

Réponses:

8

La .ebextensionssuggestion de David Ellis a fonctionné pour moi. Je ne suis pas en mesure de commenter sa réponse, mais je voulais ajouter que vous pouvez créer un nouveau volume EBS au lieu d'utiliser un instantané. Pour monter un volume EBS de 40 Go, j'ai utilisé ce qui suit:

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

Consultez également cette documentation , qui contient un exemple de mappage d'un nouveau volume EBS de 100 Go /dev/sdh.

À truela fin signifie "supprimer à la fin".

J'ai créé un nouveau .ebextensionsrépertoire contenant un ebs.configfichier avec le code ci-dessus, puis j'ai compressé ce répertoire avec mon Dockerrun.aws.json. Notez que le fichier Dockerrun doit être au niveau supérieur du zip, pas à l'intérieur d'un sous-répertoire.

Pour trouver où Elastic Beanstalk monte le volume, utilisez lsblksur l'instance défaillante. C'était aussi /dev/xvdczpour moi, alors c'est peut-être la norme.

joko
la source
2

Nous avons été touchés par le même problème. La cause première semble être que Docker ne monte pas son moteur de stockage (provisionné devicemapperpar défaut dans Elastic Beanstalk) avec les discardoptions, qui remplissent à leur tour les blocs jusqu'à ce qu'ils se cassent.

Je n'ai pas pu trouver de solution définitive à cela, mais voici une solution de contournement (voir ce commentaire ) que j'ai pu utiliser sur les instances affectées:

docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/
FX
la source
1
Merci. Je suis arrivé à la même conclusion et j'ai fini par changer tout le stockage de données sur EBS. Je pense que c'est un peu idiot pour les fichiers vraiment transitoires / temporaires (qui continuent d'être écrasés) mais bon, que pouvez-vous faire?
std''OrgnlDave
Il s'avère qu'un cronjob pour cela est dans la documentation EC2, mais il n'est pas mentionné dans les documents Beanstalk. Sur Beanstalk, vous devriez voir si vous pouvez ajouter un crochet pour une crontab spéciale ou quelque chose.
std''OrgnlDave
Oh, c'est bon à savoir! Pourriez-vous copier le lien ici comme référence?
FX
1
docs.aws.amazon.com/AmazonECS/latest/developerguide/… recherchez "trim". Pas exactement une simple mention d'une chose très évidente
std''OrgnlDave
1
@ThomasGrainger. Fichiers d'extensions. L'une des créations les plus douloureuses au monde les plus ennuyeuses. Ils s'exécutent au démarrage du système.
std''OrgnlDave
2

J'ai suivi les suggestions fournies sur la documentation AWS et tout fonctionne maintenant.
Mais j'ai dû combiner deux solutions: augmenter l'espace et ajouter cronjob pour supprimer les anciens fichiers.
Voici ce que j'ai fait.

Tout d'abord, j'ai changé le volume xvdczpour utiliser 50 Go au lieu de 12 Go. C'est le stockage sur lequel nous pouvons voir docker system info. Dans mon cas, il était toujours plein car je télécharge beaucoup de fichiers chaque jour.

.ebextensions / blockdevice-xvdcz.config

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

Après avoir ajouté un cronjob pour nettoyer mes fichiers supprimés qui n'étaient plus utilisés. Cela était nécessaire car Docker les conservait encore pour une raison quelconque. Dans mon cas, une fois par jour, c'est assez. Si vous avez plus de téléchargements que moi, vous pouvez configurer le cronjob pour exécuter le nombre de fois dont vous avez besoin.

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

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

Danilo Akamine
la source
1

La section de configuration de l'environnement AWS élastiquebeanstalk docker explique comment cela fonctionne:

Pour de meilleures performances, Elastic Beanstalk configure deux volumes de stockage Amazon EBS pour les instances EC2 de votre environnement Docker. En plus du volume racine provisionné pour tous les environnements Elastic Beanstalk, un deuxième volume de 12 Go nommé xvdcz est provisionné pour le stockage d'images sur les environnements Docker.

Si vous avez besoin de plus d'espace de stockage ou d'augmentation d'IOPS pour les images Docker, vous pouvez personnaliser le volume de stockage d'image en utilisant l'option de configuration BlockDeviceMapping dans l'espace de noms aws: autoscaling: launchconfiguration.

Par exemple, le fichier de configuration suivant augmente la taille du volume de stockage à 100 Go avec 500 IOPS provisionnés:

Exemple .ebextensions / blockdevice-xvdcz.config

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

Si vous utilisez l'option BlockDeviceMappings pour configurer des volumes supplémentaires pour votre application, vous devez inclure un mappage pour xvdcz pour vous assurer qu'il est créé. L'exemple suivant configure deux volumes, le volume de stockage d'image xvdcz avec les paramètres par défaut et un volume d'application supplémentaire de 24 Go nommé sdh:

Exemple .ebextensions / blockdevice-sdh.config

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

J'ai battu ma tête contre ce problème pendant plus d'une journée et j'ai finalement compris.

AWS utilise le devicemapperbackend et crée un volume SSD de 12 Go qu'il monte et utilise pour les images docker. Vous devez remplacer le volume qu'il monterait via le concept d'extensions élastiquebeanstalk et déployer via la CLI (il n'y a aucun moyen de le faire via leur interface graphique, malheureusement).

Dans le répertoire où vous avez votre Dockerrun.aws.jsonfichier, créez un répertoire appelé .ebextensions, puis créez un fichier qui se termine à l' .configintérieur de celui-ci. J'ai appelé le mien 01.correctebsvolume.config. Mettez ensuite le contenu suivant dedans:

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

Je me faufilai directement dans l'un de mes coffres défectueux et trouvai qu'il montait /dev/xvdcz. Cela peut être différent pour vous. Le snap-066cZZZZZZZZdoit être un ID d'instantané valide. J'ai créé une image AMI de l'instance défaillante et utilisé l'instantané qu'il a créé dans le processus. Le 40nombre de Go sera le volume, alors remplacez-le par ce dont vous avez besoin. Je ne sais pas ce que le trueou gp2faire, mais ils sont venus à partir des données de périphérique bloc d'image AMI, donc je les ai gardés.

La magie namespaceet option_namevenir d' ici dans la documentation.


la source
Alors ... cela monte le volume Docker racine sur EBS au lieu du pool mince?
std''OrgnlDave
Le docker thinpool est configuré pour fonctionner sur un volume EBS (exactement 12 Go). Cela remplace ce volume par un plus grand et est le moyen le moins invasif de le faire fonctionner.
Oh, la configuration Thinpool d'Amazon est de 100 Go, c'est donc la limite supérieure pour cette réponse, et je ne sais pas si cela peut être ajusté.
0

L'augmentation de la taille du disque ne résoudra pas le problème, il se produira une erreur plus tard. AWS recommande de mapper un nouveau disque sur votre conteneur afin que tout fichier de création / suppression n'affecte pas la couche d'interrogation Docker.

Je le recherche actuellement, je n'ai pas encore testé mais la solution que je rencontre est d'avoir ceci sur mon 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

Appréciez tous les commentaires.

neisantos
la source