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+ ГБ свободного пространства внутри контейнера, почему это останавливает новые записи? Насколько я могу судить, он не связан с файлами, в которые пишут мои программы.

Спасибо!

Ответы:


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/

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.