Я не могу понять, как 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 сообщает следующее: (из информация о докере
)
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+ ГБ свободных внутри контейнера на моем томе /, почему он останавливает новые записи? Насколько я могу судить, он не связан с файлами, в которые пишут мои программы.
Спасибо!
Мы столкнулись с той же проблемой. Основная причина, по-видимому, в том, что Docker не монтирует свой механизм хранения (с тонким предоставлением devicemapper
по умолчанию в Elastic Beanstalk) с параметрами discard
, которые, в свою очередь, заполняют блоки до тех пор, пока не сломаются.
Мне не удалось найти однозначного решения этой проблемы, но вот обходной путь (см. этот комментарий ), который я смог использовать на затронутых экземплярах:
docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/
.ebextensions
, предложенные Дэвидом Эллисом, сработали для меня. Я не могу комментировать его ответ, но я хотел добавить, что вы можете создать новый том EBS вместо использования снимка. Чтобы смонтировать том EBS объемом 40 ГБ, я использовал следующее:
option_settings:
- namespace: aws:autoscaling:launchconfiguration
option_name: BlockDeviceMappings
value: /dev/xvdcz=:40:true
См. Также эту документацию , в которой есть пример сопоставления нового тома EBS объемом 100 ГБ с / dev / sdh
. 12122] true
в конце означает «удалять при завершении».
Я создал новый каталог .ebextensions
, содержащий файл ebs.config
с приведенный выше код, затем заархивировал этот каталог вместе с моим Dockerrun.aws.json
. Обратите внимание, что файл Dockerrun должен находиться на верхнем уровне zip-архива, а не внутри подкаталога.
Чтобы узнать, где Elastic Beanstalk монтирует том, используйте lsblk
на отказавшем экземпляре. Для меня это был также / dev / xvdcz
, так что, возможно, это стандарт.
Простое увеличение размера диска не решит проблему, позже возникнет ошибка. . 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
Благодарю за любые комментарии.
Раздел докеров AWS elasticbeanstalk Конфигурация среды описывает, как это работает:
Для повышения производительности Elastic Beanstalk настраивает два тома хранения Amazon EBS для экземпляров EC2 вашей среды Docker. В дополнение к корневому тому, предоставленному для всех сред Elastic Beanstalk, второй том xvdcz объемом 12 ГБ выделен для хранения образов в средах Docker.
Если вам нужно больше места для хранения или увеличенное количество операций ввода-вывода в секунду для образов 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
Я боролся с этой проблемой больше дня и, наконец, понял ее.
AWS использует серверную часть devicemapper
и создает том SSD объемом 12 ГБ, который он монтирует и использует образы докеров. Вы должны переопределить том, который он будет монтировать с помощью концепции расширений elasticbeanstalk, и развернуть через интерфейс командной строки (к сожалению, это невозможно сделать через их графический интерфейс).
В каталоге у вас есть Dockerrun.aws. json
, создайте каталог с именем .ebextensions
, а затем создайте внутри него файл, заканчивающийся на .config
. Я назвал свой 01.correctebsvolume.config
. Затем поместите туда следующее содержимое:
option_settings:
- пространство имен: aws: autoscaling: launchconfiguration
option_name: BlockDeviceMappings
значение: / dev / xvdcz = snap-066cZZZZZZZZ: 40: true: gp2
Я напрямую подключился к одному из своих сбойных боксов и обнаружил, что он монтируется / dev / xvdcz
. Это может быть другим для вас. Snap-066cZZZZZZZZ
должен быть действительным идентификатором моментального снимка. Я создал образ AMI отказавшего экземпляра и использовал снимок, который он создал в процессе. 40
- это сколько ГБ будет на томе, поэтому замените то, что вам нужно. Я не знаю, что делают true
или gp2
, но они пришли из данных устройства блока изображений AMI, поэтому я сохранил их.
Волшебное пространство имен
и option_name
взяты из здесь в документации.
Я выполнил рекомендации, содержащиеся в документации AWS, и теперь все работает.
Но мне пришлось объединить два решения: увеличить пространство и добавить cronjob для удаления старых файлов.
Вот что я сделал.
Сначала я изменил объем xvdcz
, чтобы использовать 50 ГБ вместо 12 ГБ. Это хранилище, которое мы видим в информации о системе докеров
. В моем случае он всегда был заполнен, потому что я загружаю много файлов каждый день.
.ebextensions / blockdevice-xvdcz.config
option_settings:
aws:autoscaling:launchconfiguration:
BlockDeviceMappings: /dev/xvdcz=:50:true
После того, как я добавил задание cron для очистки удаленных файлов, которые больше не использовались. Это было необходимо, потому что Docker по какой-то причине все еще хранил их. В моем случае достаточно одного раза в день. Если у вас больше загрузок, чем у меня, вы можете настроить задание cron для запуска столько раз, сколько вам нужно.
.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"