AWSがElasticBeanstalkにDockerの「シンプール」を設定する方法と、それがどのように満たされるかを理解できません。 Dockerシンプールが何らかの理由でいっぱいになり、アプリがディスクに書き込もうとするとクラッシュします。
これはコンテナの中からです:
>df -h
> /dev/xvda1 25G 1.4G 24G 6%
実際、EBSには25GBのディスクが割り当てられています。 1.6 GBは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はこれを報告します:(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 GB以上の空きがある場合、なぜ新しい書き込みが停止されるのですか?私の知る限り、プログラムが書き込んでいるファイルに接続されていません。
ありがとうございました!
デビッド・エリスが提案した.ebextensions
は私のために働いた。彼の回答についてコメントすることはできませんが、スナップショットを使用する代わりに新しいEBSボリュームを作成できることを付け加えておきます。 40GB EBSボリュームをマウントするために、私は以下を使用しました:
option_settings:
- namespace: aws:autoscaling:launchconfiguration
option_name: BlockDeviceMappings
value: /dev/xvdcz=:40:true
新しい100GB EBSボリュームを/dev/sdh
にマッピングする例がある このドキュメント も参照してください。
末尾のtrue
は、「終了時に削除」を意味します。
上記のコードで.ebextensions
ファイルを含む新しいebs.config
ディレクトリを作成し、そのディレクトリをDockerrun.aws.json
と一緒に圧縮しました。 Dockerrunファイルは、サブディレクトリ内ではなく、Zipの最上位にある必要があることに注意してください。
Elastic Beanstalkがボリュームをマウントしている場所を見つけるには、失敗したインスタンスでlsblk
を使用します。それはまた私にとって/dev/xvdcz
だったので、それが標準であるかもしれません。
私はAWSドキュメントで提供された提案に従いましたが、すべてが現在機能しています。
しかし、私は2つのソリューションを組み合わせる必要がありました。スペースを増やすことと、cronjobを追加して古いファイルを削除することです。
これが私がやったことです。
まず、ボリュームxvdcz
を12GBではなく50GBに変更しました。これがdocker system info
に表示されるストレージです。私の場合、毎日たくさんのファイルをアップロードしているので、いつもいっぱいでした。
。ebextensions/blockdevice-xvdcz.config
option_settings:
aws:autoscaling:launchconfiguration:
BlockDeviceMappings: /dev/xvdcz=:50:true
Cronjobを追加した後、使用されなくなった削除済みファイルを削除しました。なんらかの理由でDockerがまだそれらを保持しているため、これが必要でした。私の場合、一日一回で十分です。私よりもアップロード数が多い場合は、必要なだけ実行するように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"
私たちは同じ問題に見舞われました。根本的な原因は、Dockerがストレージエンジン(Elastic Beanstalkではデフォルトでシンプロビジョニングされたdevicemapper
)をdiscard
オプションでマウントしていないためと思われます。
私はこれに対する明確な解決策を見つけることができませんでしたが、影響を受けるインスタンスで使用できた回避策( このコメント を参照)があります:
docker ps -qa | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/
AWS elasticbeanstalk Dockerセクション 環境設定 がどのように機能するかを文書化します:
パフォーマンスを向上させるために、Elastic Beanstalkは、Docker環境のEC2インスタンス用に2つのAmazon EBSストレージボリュームを構成します。すべてのElastic Beanstalk環境用にプロビジョニングされたルートボリュームに加えて、xvdczという名前の2番目の12GBボリュームがDocker環境でのイメージストレージ用にプロビジョニングされます。
Dockerイメージのストレージ容量を増やすかIOPSを増やす必要がある場合は、aws:autoscaling:launchconfiguration名前空間のBlockDeviceMapping構成オプションを使用して、イメージストレージボリュームをカスタマイズできます。
たとえば、次の構成ファイルは、500のプロビジョニングされたIOPSでストレージボリュームのサイズを100 GBに増やします。
例.ebextensions/blockdevice-xvdcz.config
option_settings:
aws:autoscaling:launchconfiguration:
BlockDeviceMappings: /dev/xvdcz=:100::io1:500
BlockDeviceMappingsオプションを使用してアプリケーションの追加のボリュームを構成する場合は、xvdczのマッピングを含めて、ボリュームが作成されるようにする必要があります。次の例では、デフォルト設定のイメージストレージボリュームxvdczと、sdhという名前の追加の24 GBアプリケーションボリュームの2つのボリュームを構成します。
例.ebextensions/blockdevice-sdh.config
option_settings:
aws:autoscaling:launchconfiguration:
BlockDeviceMappings: /dev/xvdcz=:12:true:gp2,/dev/sdh=:24
ディスクのサイズを増やすだけでは問題は解決せず、後でエラーが発生します。作成ファイル/削除ファイルがDocker Poll Layerに影響を与えないように、新しいディスクをコンテナにマッピングすることをお勧めします。
私は現在それを探しています、私はまだテストしていませんが、私が遭遇した解決策はこれをm 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
コメントを感謝します。
私はこの問題に1日以上頭をぶつけて、ようやくそれを理解しました。
AWSは devicemapper
バックエンドを使用しており、Dockerイメージにマウントして使用する12GB SSDボリュームを作成します。 elasticbeanstalk拡張機能の概念でマウントするボリュームをオーバーライドして、CLI経由でデプロイする必要があります(残念ながら、GUI経由でこれを行う方法はありません)。
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
私は失敗したボックスの1つに直接sshで入力し、それが/dev/xvdcz
をマウントしていることを発見しました。それはあなたのために異なるかもしれません。 snap-066cZZZZZZZZ
は有効なスナップショットIDである必要があります。失敗したインスタンスのAMIイメージを作成し、プロセスで作成したスナップショットを使用しました。 40
はボリュームのGB数になるため、必要なものに置き換えます。 true
またはgp2
の機能はわかりませんが、それらはAMIイメージブロックデバイスデータから取得されたため、保持しました。
マジックnamespace
とoption_name
は、ドキュメントの here に由来します。