O docker-thin-pool do AWS ElasticBeanstalk fica cheio e causa a remontagem do sistema de arquivos como somente leitura?

9

Não consigo descobrir como a AWS configura o 'thin pool' do Docker no ElasticBeanstalk e como está sendo preenchido. Meu thin pool do Docker está se enchendo de alguma forma e está causando o travamento dos meus aplicativos quando eles tentam gravar no disco.

Isto é de dentro do contêiner:

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

De fato, o EBS possui um disco de 25 GB distribuído a ele; 1,6 gb é o que du -sh /retorna.

Lá fora, no EC2, ele começa de maneira inocente o suficiente ... (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

No entanto, o sistema de arquivos em breve será novamente montado como somente leitura. 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 volta à instância do EC2, o Docker relata isso: (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

O LVS despeja essa informação:

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

O que é esse pool fino, por que ele enche e como eu o impedi de fazer isso? Além disso, se eu tenho mais de 20 GB livres de dentro do contêiner no meu / volume, por que interrompe novas gravações? Tanto quanto posso dizer, não está conectado aos arquivos nos quais meus programas estão gravando.

Obrigado!

std''OrgnlDave
fonte

Respostas:

8

O .ebextensionssugerido por David Ellis funcionou para mim. Não consigo comentar sua resposta, mas gostaria de acrescentar que você pode criar um novo volume EBS em vez de usar um instantâneo. Para montar um volume EBS de 40 GB, usei o seguinte:

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

Consulte também esta documentação , que possui um exemplo de mapeamento para um novo volume EBS de 100 GB /dev/sdh.

No truefinal significa "excluir ao finalizar".

Criei um novo .ebextensionsdiretório contendo um ebs.configarquivo com o código acima e, em seguida, fechei esse diretório junto com o meu Dockerrun.aws.json. Observe que o arquivo Dockerrun deve estar no nível superior do zip, não dentro de um subdiretório.

Para descobrir onde o Elastic Beanstalk está montando o volume, use lsblkna instância com falha. Também foi /dev/xvdczpara mim, então talvez esse seja o padrão.

joko
fonte
2

Fomos atingidos pelo mesmo problema. A causa raiz parece que o Docker não está montando seu mecanismo de armazenamento (com provisionamento thin devicemapperpor padrão no Elastic Beanstalk) com as discardopções, que por sua vez preenchem os blocos até que sejam quebrados.

Não consegui encontrar uma solução definitiva para isso, mas aqui está uma solução alternativa (veja este comentário ) que pude usar nas instâncias afetadas:

docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/
FX
fonte
1
Obrigado. Cheguei à mesma conclusão e acabei alterando todo o armazenamento de dados para o EBS. Eu acho que isso é um pouco bobo para arquivos temporários / realmente transitórios (que continuam sendo substituídos), mas ei, o que você pode fazer?
std''OrgnlDave
Acontece que um cronjob para isso está na documentação do EC2, mas não é mencionado nos documentos do Beanstalk. No Beanstalk, você teria que ver se poderia adicionar um gancho para um crontab especial ou algo assim.
std''OrgnlDave
Oh, que bom saber! Você se importaria de copiar o link aqui como referência?
FX
1
docs.aws.amazon.com/AmazonECS/latest/developerguide/… procure por "aparar". Não é exatamente uma menção direta de uma coisa muito óbvia
std
1
@ThomasGrainger .ebextensions arquivos. Uma das maiores dores no bumbum irritante possível criações no mundo. Eles são executados na inicialização do sistema.
precisa saber é o seguinte
2

Segui as sugestões fornecidas na documentação da AWS e tudo está funcionando agora.
Mas tive que combinar duas soluções: aumentar o espaço e adicionar cronjob para remover arquivos antigos.
Aqui está o que eu fiz.

Primeiro, mudei o volume xvdczpara usar 50 GB em vez de 12 GB. Esse é o armazenamento que podemos ver docker system info. No meu caso, estava sempre cheio, porque eu carrego muitos arquivos todos os dias.

.ebextensions / blockdevice-xvdcz.config

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

Depois adicionei um cronjob para limpar meus arquivos excluídos que não eram mais usados. Foi necessário porque o Docker ainda os mantinha por algum motivo. No meu caso, uma vez por dia é suficiente. Se você tiver mais uploads do que eu, poderá configurar o cronjob para executar quantas vezes você precisar.

.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

Danilo Akamine
fonte
1

Seção docker do AWS elasticbeanstalk Documentação de configuração do ambiente como funciona:

Para melhorar o desempenho, o Elastic Beanstalk configura dois volumes de armazenamento do Amazon EBS para as instâncias do EC2 do seu ambiente Docker. Além do volume raiz provisionado para todos os ambientes Elastic Beanstalk, um segundo volume de 12 GB chamado xvdcz é provisionado para armazenamento de imagens em ambientes Docker.

Se você precisar de mais espaço de armazenamento ou aumento de imagens de IOPS para Docker, poderá personalizar o volume de armazenamento de imagens usando a opção de configuração BlockDeviceMapping no espaço de nome aws: autoscaling: launchconfiguration.

Por exemplo, o seguinte arquivo de configuração aumenta o tamanho do volume de armazenamento para 100 GB com 500 IOPS provisionados:

Exemplo .ebextensions / blockdevice-xvdcz.config

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

Se você usar a opção BlockDeviceMappings para configurar volumes adicionais para seu aplicativo, inclua um mapeamento para xvdcz para garantir que ele seja criado. O exemplo a seguir configura dois volumes, o volume de armazenamento de imagem xvdcz com configurações padrão e um volume de aplicativo adicional de 24 GB chamado sdh:

Exemplo .ebextensions / blockdevice-sdh.config

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

Eu bati minha cabeça contra esse problema por mais de um dia e finalmente descobri.

A AWS está usando o devicemapperback - end e cria um volume SSD de 12 GB que monta e usa para as imagens do docker. Você precisa substituir o volume que ele montaria pelo conceito de extensões elasticbeanstalk e implantá-lo via CLI (infelizmente não há como fazer isso por meio da interface gráfica do usuário).

No diretório em que você possui seu Dockerrun.aws.jsonarquivo, crie um diretório chamado .ebextensionse, em seguida, crie um arquivo que termine .configdentro dele. Eu chamei o meu 01.correctebsvolume.config. Em seguida, coloque o seguinte conteúdo lá:

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

Mergulhei em uma das minhas caixas fracassadas diretamente e achei que estava montando /dev/xvdcz. Ele pode ser diferente para você. As snap-066cZZZZZZZZnecessidades para ser um ID snapshot válido. Criei uma imagem AMI da instância com falha e usei a captura instantânea criada no processo. O 40é quantos GB o volume será, então substituto em que você precisa. Não sei o que é trueou o que gp2faz, mas eles vieram dos dados do dispositivo de bloqueio de imagem da AMI, então eu os mantive.

A mágica namespacee option_namevem daqui na documentação.


fonte
Então ... isso monta o volume raiz do Docker no EBS em vez do thin pool?
precisa saber é o seguinte
O docking thinpool está configurado para ser executado em um volume EBS (de exatamente 12 GB). Isso substitui esse volume por um maior e é a maneira menos invasiva de fazê-lo funcionar.
Ah, a configuração thinpool da Amazon é de 100 GB, então esse é o limite superior para esta resposta, e não tenho certeza se isso pode ser ajustado.
0

Apenas aumentar o tamanho do disco não resolverá o problema, apenas erros mais tarde. A AWS recomenda o mapeamento de um novo disco para seu contêiner, para que qualquer arquivo de criação / exclusão não afete a camada de pesquisa do Docker.

Atualmente, estou olhando para ele, ainda não testei, mas a solução que encontrei está tendo isso no meu 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

Aprecie qualquer comentário.

neisantos
fonte