AWS ElasticBeanstalk docker-thin-pool переполняется и вызывает повторное монтирование файловой системы только для чтения?

10

Я не могу понять, как AWS настраивает свой «тонкий пул» Docker на ElasticBeanstalk и как он заполняется. Мой тонкий пул докера как-то заполняется и вызывает сбой моих приложений при попытке записи на диск.

Это изнутри контейнера:

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

На самом деле EBS имеет выделенный диск объемом 25 ГБ; 1,6 ГБ - это то, что du -sh /возвращается.

Снаружи в EC2 он начинается достаточно безобидно ... (через 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

Тем не менее, файловая система будет вскоре перемонтирована как доступная только для чтения. через 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

Вернувшись в страну экземпляров EC2, Докер сообщает об этом: (с 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 сбрасывает эту информацию:

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

Что это за тонкий пул, почему он заполняется, и как мне его остановить? Кроме того, если на моем / томе есть 20+ ГБ свободного пространства внутри контейнера, почему это останавливает новые записи? Насколько я могу судить, он не связан с файлами, в которые пишут мои программы.

Спасибо!

std''OrgnlDave
источник

Ответы:

8

.ebextensionsПредложил Дэвид Эллис работал для меня. Я не могу прокомментировать его ответ, но я хотел добавить, что вы можете создать новый том EBS вместо использования снимка. Чтобы смонтировать том EBS объемом 40 ГБ, я использовал следующее:

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

См. Также эту документацию , в которой приведен пример сопоставления нового тома EBS объемом 100 ГБ /dev/sdh.

В trueконце означает «удалить при завершении».

Я создал новый .ebextensionsкаталог, содержащий ebs.configфайл с вышеуказанным кодом, а затем сжал этот каталог вместе с моим Dockerrun.aws.json. Обратите внимание, что файл Dockerrun должен находиться на верхнем уровне zip, а не внутри подкаталога.

Чтобы узнать, где Elastic Beanstalk монтирует том, используйте lsblkсбойный экземпляр. Это было также /dev/xvdczдля меня, так что, возможно, это стандарт.

Джоко
источник
2

Мы получили удар по той же проблеме. Основная причина, по-видимому, заключается в том, что Docker не монтирует свой механизм хранения (с тонким предоставлением devicemapperв Elastic Beanstalk по умолчанию) с discardопциями, которые, в свою очередь, заполняют блоки до тех пор, пока не сломаются.

Я не смог найти определенного решения для этого, но вот обходной путь (см. Этот комментарий ), который я смог использовать на затронутых экземплярах:

docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/
FX
источник
1
Спасибо. Я пришел к такому же выводу и в итоге перевел все хранилище данных на EBS. Я думаю, что это немного глупо для действительно временных / временных файлов (которые продолжают перезаписываться), но что вы можете сделать?
std''OrgnlDave
Оказывается, что cronjob для этого есть в документации EC2, но это не упоминается в документах Beanstalk. На Beanstalk вы должны посмотреть, можете ли вы добавить хук для специального crontab или чего-то еще.
std''OrgnlDave
О, приятно знать! Не могли бы вы скопировать ссылку здесь как ссылку?
FX
1
docs.aws.amazon.com/AmazonECS/latest/developerguide/… ищите «отделка». Не совсем прямое упоминание об очень очевидной вещи
std''OrgnlDave
1
@ThomasGrainger .ebextensions файлы. Одна из самых неприятных в прикладе болей возможных творений в мире. Они запускаются при загрузке системы.
std''OrgnlDave
2

Я следовал предложениям, представленным в документации AWS, и теперь все работает.
Но мне пришлось объединить два решения: увеличить пространство и добавить cronjob для удаления старых файлов.
Вот что я сделал.

Во-первых, я изменил громкость, xvdczчтобы использовать 50 ГБ вместо 12 ГБ. Это хранилище, на котором мы можем видеть docker system info. В моем случае это всегда было полно, потому что я загружаю много файлов каждый день.

.ebextensions / BlockDevice-xvdcz.config

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

После того, как я добавил cronjob, чтобы очистить мои удаленные файлы, которые больше не использовались. Это было необходимо, потому что Докер по какой-то причине все еще хранил их. В моем случае достаточно одного раза в день. Если у вас больше загрузок, чем у меня, вы можете настроить cronjob для запуска сколько раз вам нужно.

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

Источник: https://docs.aws.amazon.com/pt_br/elasticbeanstalk/latest/dg/create_deploy_docker.container.console.html#docker-volumes

Данило Акамине
источник
1

Секция док-станции AWSasticbeanstalk Environment Configuration описывает, как она работает:

Для повышения производительности Elastic Beanstalk настраивает два тома хранилища Amazon EBS для экземпляров EC2 вашей среды Docker. В дополнение к корневому тому, предоставленному для всех сред Elastic Beanstalk, для хранения изображений в средах Docker предусмотрен второй том объемом 12 ГБ с именем xvdcz.

Если вам требуется больше места для хранения или увеличенный IOPS для образов Docker, вы можете настроить объем хранилища изображений, используя опцию конфигурации BlockDeviceMapping в пространстве имен aws: autoscaling: launchconfiguration.

Например, следующий файл конфигурации увеличивает размер тома хранилища до 100 ГБ при 500 выделенных IOPS:

Пример .ebextensions / blockdevice-xvdcz.config

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

Если вы используете опцию BlockDeviceMappings для настройки дополнительных томов для своего приложения, вы должны включить отображение для xvdcz, чтобы убедиться, что оно создано. В следующем примере настраиваются два тома: том хранения xvdcz с настройками по умолчанию и дополнительный том приложения объемом 24 ГБ с именем sdh:

Пример .ebextensions / blockdevice-sdh.config

option_settings:
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: /dev/xvdcz=:12:true:gp2,/dev/sdh=:24
JavaRocky
источник
0

Я бился головой с этой проблемой более суток и наконец понял это.

AWS использует devicemapperбэкэнд и создает том SSD объемом 12 ГБ, который он монтирует и использует для образов докеров. Вы должны переопределить том, который он будет монтировать, используя концепцию расширений эластичных бобов, и развернуть его через CLI (к сожалению, это невозможно сделать с помощью их графического интерфейса).

В каталоге у вас есть Dockerrun.aws.jsonфайл, создайте каталог с именем, .ebextensionsа затем создайте файл, который заканчивается .configвнутри него. Я позвонил мой 01.correctebsvolume.config. Затем поместите туда следующее содержимое:

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

Я прямо в одну из своих неудачных коробок и обнаружил, что она крепится /dev/xvdcz. Это может отличаться для вас. В snap-066cZZZZZZZZдолжен быть действительным снимок ID. Я создал образ AMI неисправного экземпляра и использовал снимок, созданный в процессе. 40, Сколько ГБ будет объем, поэтому замена в том, что вам нужно. Я не знаю, что trueили gp2делать, но они пришли из данных устройства блочного изображения AMI, поэтому я сохранил их.

Волшебство namespaceи option_nameпришло отсюда в документацию.


источник
Итак ... это монтирует корневой том Docker на EBS вместо тонкого пула?
std''OrgnlDave
Docker thinpool настроен для работы на томе EBS (ровно 12 ГБ). Это заменяет этот том на больший и является наименее инвазивным способом заставить его работать.
О, конфигурация thinpool, которую устанавливает Amazon, рассчитана на 100 ГБ, так что это верхний предел для этого ответа, и я не уверен, что это можно изменить.
0

Простое увеличение размера диска не решит проблему, а приведет к ошибке позже. AWS рекомендует сопоставить новый диск с вашим контейнером, чтобы любой создаваемый файл / файл удаления не влиял на слой опроса Docker.

Я в настоящее время смотрю на это, я еще не проверял, но решение, с которым я сталкиваюсь, имеет это на моем 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

Ценю любые комментарии.

neisantos
источник