Closed eggplants closed 4 years ago
そうですね。 機能としては欲しいなぁと僕も思っていました。 セキュリティ的に気にすることが多そうなので、少し設計の時間を下さい。 今週から来週あたりで対応しようと思います
dm.basesize
で制限をかけられる?
Dockerでルートディスクサイズを調整する
初期設定では10GBらしいけれど、僕の環境ではホストのストレージの空き容量いっぱい使えそう
(;^q^)? › d run --rm -it ubuntu bash
root@8fdcb7f2bb15:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 286G 177G 95G 66% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/sda5 286G 177G 95G 66% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
(*'-')! › d run --rm --storage-opt size=20g -it ubuntu bash
docker: Error response from daemon: --storage-opt is supported only for overlay over xfs with 'pquota' mount option.
See 'docker run --help'.
(*'-')! › docker info | awk '11<=NR && NR<=14{ print }'
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: false
(*'-')! › d run --rm --storage-driver=xfs --storage-opt size=20g -it ubuntu bash
unknown flag: --storage-driver
See 'docker run --help'.
ストレージ・ドライバを設定するには dockerd コマンドで --storage-driver=<名前> オプションを使うか、あるいは、 /etc/default/docker ファイル中の DOCKER_OPTS 行を編集します。
Docker の利用にあたり、最も安定かつ手間がかからないという面では、以下の点が考えられます。
ディストリビューションの標準ストレージ・ドライバを使います 。Docker をインストールする時、システム上の設定に応じてデフォルトのストレージ・ドライバを選択します。デフォルトのストレージ・ドライバの使用は、安定性に対する重要な要素になります。デフォルトのものを使わなければ、バグや微妙な差違に遭遇する可能性が増えるかもしれません。
(;^q^)? › find /etc/default/
/etc/default/
/etc/default/grub.pacnew
/etc/default/syslog-ng@default
/etc/default/ufw
/etc/default/locale
/etc/default/useradd
/etc/default/grub
/etc/default/cpupower
/etc/default/tlp
/etc/default/keyboard
/etc/default/docker がない
起動オプションは特に指定していない。
(*'-')! › ps aux | grep dockerd
jiro4989 5366 0.0 0.0 7340 2532 pts/3 S+ 09:30 0:00 grep dockerd
root 22080 0.2 0.8 6461320 105784 ? Ssl 1月31 2:24 /usr/bin/dockerd -H fd://
systemdでcontainerdは起動している。
(*'-')! › sudo pstree | head -n 30
systemd-+-ModemManager---2*[{ModemManager}]
|-dockerd-+-containerd-+-containerd-shim-+-nginx---nginx
| | | `-9*[{containerd-shim}]
| | `-16*[{containerd}]
| `-507*[{dockerd}]
systemdのdocker用の設定がない。
(*'-')! › sudo find /etc/systemd | grep -i docker
(;^q^)? › systemctl status docker | cat
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2020-01-31 18:39:04 JST; 14h ago
Docs: https://docs.docker.com
Main PID: 22080 (dockerd)
Tasks: 535 (limit: 4915)
Memory: 409.3M
CGroup: /system.slice/docker.service
├─22080 /usr/bin/dockerd -H fd://
├─22091 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
├─29619 containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6592dd915a10f31d4535ee392473f8d5dfeaab14ac4cf008d3c244cd90e1ca4b -address /var/run/docker/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
├─29637 nginx: master process nginx -g daemon off;
└─29656 nginx: worker process
/usr/lib/systemd/system/docker.service
のほうにあった
(*'-')! › grep ExecStart /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd://
あった。ここを変更してdockerdを再起動したら変わるかもしれない。
09:43:03 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo vi /usr/lib/systemd/system/docker.service
09:43:06 jiro4989@jiro4989-pc /tmp
(*'-')! › grep ExecStart /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --storage-driver=xfs
#ExecStart=/usr/bin/dockerd -H fd://
09:43:09 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl restart docker
Warning: The unit file, source configuration file or drop-ins of docker.service changed on disk. Run 'systemctl daemon-reload' to reload units.
^C
09:43:26 jiro4989@jiro4989-pc /tmp
(;^q^)? › sudo systemctl daemon-reload docker
Too many arguments.
09:43:32 jiro4989@jiro4989-pc /tmp
(;^q^)? › sudo systemctl daemon-reload
09:43:43 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl restart docker
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xe" for details.
起動できなかった。
(;^q^)? › sudo systemctl status docker | cat
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2020-02-01 09:43:56 JST; 2min 20s ago
Docs: https://docs.docker.com
Process: 13827 ExecStart=/usr/bin/dockerd -H fd:// --storage-driver=xfs (code=exited, status=1/FAILURE)
Main PID: 13827 (code=exited, status=1/FAILURE)
2月 01 09:43:56 jiro4989-pc systemd[1]: docker.service: Service RestartSec=100ms expired, scheduling restart.
2月 01 09:43:56 jiro4989-pc systemd[1]: docker.service: Scheduled restart job, restart counter is at 3.
2月 01 09:43:56 jiro4989-pc systemd[1]: Stopped Docker Application Container Engine.
2月 01 09:43:56 jiro4989-pc systemd[1]: docker.service: Start request repeated too quickly.
2月 01 09:43:56 jiro4989-pc systemd[1]: docker.service: Failed with result 'exit-code'.
2月 01 09:43:56 jiro4989-pc systemd[1]: Failed to start Docker Application Container Engine.
起動→失敗を繰り返していたのでsystemdが止めた
設定を戻して /etc/default/docker に設定を書いてみる。
(*'-')! › sudo vi /usr/lib/systemd/system/docker.service
09:52:07 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl daemon-reload
09:52:12 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo vi /etc/default/docker
09:53:30 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl daemon-reload
09:53:33 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl restart docker
09:53:45 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-02-01 09:53:45 JST; 14s ago
起動はした
(*'-')! › docker run --rm -it ubuntu bash
root@079bcc41099f:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 286G 177G 95G 66% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/sda5 286G 177G 95G 66% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
変わってない。多分設定を読み込んでいない気がする。
systemdを使うようになってこっちの設定は読み込まれなくなったらしい?
systemdでの起動時に環境変数をセットしてみる。
(*'-')! › sudo vi /usr/lib/systemd/system/docker.service
10:07:09 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo grep Env /usr/lib/systemd/system/docker.service
Environment="DOCKER_OPTS=--storage-driver=devicemapper"
10:07:25 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl daemon-reload
10:07:39 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl restart docker
10:07:50 jiro4989@jiro4989-pc /tmp
(*'-')! › sudo systemctl status docker | cat
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-02-01 10:07:50 JST; 14s ago
Docs: https://docs.docker.com
Main PID: 27678 (dockerd)
Tasks: 520 (limit: 4915)
Memory: 128.4M
CGroup: /system.slice/docker.service
├─27678 /usr/bin/dockerd -H fd://
└─27688 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
起動はした
(*'-')! › docker run --rm -it ubuntu bash
root@200ee4729a1e:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 286G 177G 95G 66% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/sda5 286G 177G 95G 66% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
root@200ee4729a1e:/# exit
exit
10:09:43 jiro4989@jiro4989-pc /tmp
(*'-')! › docker run --rm --storage-opt size=20G -it ubuntu bash
docker: Error response from daemon: --storage-opt is supported only for overlay over xfs with 'pquota' mount option.
See 'docker run --help'.
変わってない
(;^q^)? › docker info | awk '11<=NR && NR<=14{ print }'
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: false
かわってない
OverlayFS は2つのストレージ・ドライバがあります。どちらも同じ OverlayFS 技術を使っていますが、実装が異なり、ディスク・ストレージ上の互換性がありません。ストレージに互換性がないため、両者を切り替えるためには、全てのイメージ内容の再構築が必要です。
docker system prune -f
docker images -qa | xargs docker rmi -f
をしてキレイにしてみたけれど変わらず
環境変数じゃなくて起動オプションに直接書くようにした。
sudo vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --storage-driver=devicemapper
docker run --rm -it ubuntu
しようとしたらDockerイメージを再取得し始めたので、多分今までのイメージが破棄されて、新しいファイルシステム用のイメージを取得しようとしたんだと思う。
root@e3b790e17b95:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:5-9836830-c8d19490620a274a4163cf2535600cf708be4a63842a3e4263d70e5bb41341bc 10G 174M 9.9G 2% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/sda5 286G 91G 181G 34% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
root@e3b790e17b95:/#
Avail 10GB になってるのでデフォルト値の10GBになったみたい。
シェル芸botのDockerイメージがどうなるか試す
root@4f8f809165f4:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:5-9836830-ecc82d8f18a5252070308f2eda89862ca2f64f1bc565f3dd401584fafb71db31 10G 5.3G 4.8G 53% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/sda5 286G 96G 175G 36% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
シェル芸botだと起動直後は4.8GB使用可能。十分そう
10GB上限で10GB以上のファイルを生成してみる
root@4f8f809165f4:/tmp# dd if=/dev/zero of=/tmp/out.dat bs=1GB count=15
dd: '/tmp/out.dat' の書き込みエラー: デバイスに空き領域がありません
6+0 レコード入力
5+0 レコード出力
5058199552 bytes (5.1 GB, 4.7 GiB) copied, 17.2248 s, 294 MB/s
root@4f8f809165f4:/tmp# ls -lah
合計 4.8G
drwxrwxrwt 4 root root 59 2月 1 11:20 .
drwxr-xr-x 19 root root 4.0K 2月 1 11:15 ..
drwxr-xr-x 2 root root 6 1月 30 11:15 hsperfdata_root
-rw-r--r-- 1 root root 4.8G 2月 1 11:21 out.dat
drwxr-xr-x 4 root root 194 1月 30 11:05 scripts
root@4f8f809165f4:/tmp#
きちんとエラーになって終了した
ホストにマウントしているディレクトリを検証する。
(*'-')! › d run --rm -v $PWD/images:/images -it theoldmoon0602/shellgeibot bash
root@b01b91b6dc24:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:5-9836830-9325f6722ca6a41a54c9fb59c64ab8a4f6a95ab3529887d6847a6195b3401bba 10G 5.3G 4.8G 53% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
tmpfs 5.8G 1.5M 5.8G 1% /images
/dev/sda5 286G 96G 175G 36% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
なんて5.8GBなんて中途半端なサイズが使用可能なんだろう?
ホストPCでは /tmp はtmpfs として5.8GBに制限されてる。
(*'-')! › df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
dev 5.8G 0 5.8G 0% /dev
run 5.8G 1.7M 5.8G 1% /run
/dev/sda5 286G 96G 175G 36% /
tmpfs 5.8G 270M 5.5G 5% /dev/shm
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
tmpfs 5.8G 1.5M 5.8G 1% /tmp
ユーザディレクトリ配下のディレクトリをマウントするようにしたらやはり制限なく使用可能だった。 webshではimagesを生成するディレクトリは特にファイルシステムを分けていないので、/images配下だとストレージを無制限に使用可能ということになる。
一時ファイルシステム (TMPFS) の作成 などで高速で揮発性のあるtmpfsを作成できる。 これでimages用のファイルシステムを作るか。
単純にマウントするだとだめ。リブート時に解除されるので、ブート時にマウントするように設定も必要。
調査を進めてわかったけれど、これアプリ側でできることなにもないな。 infraリポジトリのほうで調査ログ残すべきだった。
一時ファイルシステム (TMPFS) の作成 これSolarisでの手順だった・・・。
Twitterだと1ツイートに5MBの画像を最大4枚使用できるはず。 20MBの2倍以上あればよいだろう、ということで50MBを上限値にする。
tmpfsだとインメモリにデータを保持するから高速な反面巨大なデータを扱えないか。
特定ディレクトリに容量制限のが適当かな
コレを実行してみる。
sudo su -
dd if=/dev/zero of=/var/www/images.fs bs=1M count=64
mke2fs -t ext4 /var/www/images.fs
install -d -o www-data -g www-data -m 0755 /var/www/images
mount -o loop -t ext4 /var/www/images.fs /var/www/images
作った結果。
(*'-')! › ll
合計 62497
drwxr-xr-x 3 root root 4096 2月 1 14:07 .
drwxr-xr-x 14 root root 4096 2月 1 13:36 ..
drwxr-xr-x 3 root root 1024 2月 1 14:09 images
-rw-r--r-- 1 root root 67108864 2月 1 14:09 images.fs
作成したファイルシステムをマウントしたディレクトリをDockerコンテナにボリュームする。 コンテナ内の使用可能なストレージを見る。
(*'-')! › docker run --rm -v $PWD/images:/images -it ubuntu bash
root@2b0ce8f360c1:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:5-9836830-930d8217086bfde64efe7aac0cc4c0af7302a80d0ff0c9caa81db54819d9462c 10G 174M 9.9G 2% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/loop16 58M 1.3M 53M 3% /images
/dev/sda5 286G 96G 175G 36% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
/imagesのAvailが53Mになっている。 コンテナ内部からも制限がかかっていることがわかる。
起動時にマウントするように設定を加える。
# vi /etc/fstab
/var/www/images.fs /var/www/images ext4 defaults,loop 0 0
コレで行けそう
こんな感じで実施すればいいかな。
コンテナの制限はいけたけれど、ホストをマウントしてるところが制限かかってないなぁ。 あとimagesの権限がrootになってた。マウントしたときに権限がかわったんだろうか。
ホストをマウントしてるところに制限がかからなかったのは /images のマウント方式を変えたからだった。 直接ホストのimagesをマウントするのではなく、volumeを作成してvolumeをマウントして、volumeからmvで移動する方式でやってる。 volume作成時に容量制限をかける必要がある。
https://docs.docker.com/engine/reference/commandline/volume_create/
storage-driverの変更自体は必要だったけれど、images.fsの作成はいらなかったやも。 失敗失敗。次に活かす。
tmpfsでボリュームを作成する。
(;^q^)? › docker volume create --opt type=tmpfs --opt device=tmpfs --opt o=size=64m images1
images1
作成したボリュームをマウントしてコンテナを起動する。
(*'-')! › docker run -v images1:/images -it ubuntu bash
root@c59de8f2bf84:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:5-9836830-49b22c3ec4523fc1ab4e7c1e8aa7510d9c4ddb784517aeb54d46bf69bbd7f720 10G 174M 9.9G 2% /
tmpfs 64M 0 64M 0% /dev
tmpfs 5.8G 0 5.8G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
tmpfs 64M 0 64M 0% /images
/dev/sda5 286G 97G 175G 36% /etc/hosts
tmpfs 5.8G 0 5.8G 0% /proc/asound
tmpfs 5.8G 0 5.8G 0% /proc/acpi
tmpfs 5.8G 0 5.8G 0% /proc/scsi
tmpfs 5.8G 0 5.8G 0% /sys/firmware
いけたっぽい
これをやるならアプリ側も改修が必要だなぁ。 docker runする前にvolumeを作成してからマウントする必要がある。
アプリ側のタスク追加。これでZipBomb対策と画像取り込みはいけるはず。
devicemapperは非推奨らしいので storage-driver をまた別のに変更しないとだめ。 やりなおし
https://docs.docker.com/storage/storagedriver/select-storage-driver/
¹) The overlay storage driver is deprecated in Docker Engine - Enterprise 18.09, and will be removed in a future release. It is recommended that users of the overlay storage driver migrate to overlay2.
²) The devicemapper storage driver is deprecated in Docker Engine 18.09, and will be removed in a future release. It is recommended that users of the devicemapper storage driver migrate to overlay2.
overlay2 への移行をオススメらしい。 ようは初期設定のドライバー
Docker (ファイル/CPU/メモリ/プロセス) のリソースを制限する方法まとめ 生成できるファイルサイズの上限を指定できる?
上限未満のファイルを大量に生成する場合を制限できないので根本解決にはならないな。 まぁかけておくことの効果はありそう。
チョット記事が古いけれど Dockerコンテナのdisk quota設定 で一応制限がかけられる。手間はかかるが。
見た感じ overlay2 + extfs では容量制限はかけられないので、ホスト側でクオーターを設定するしかない。
quota初めて使うので検証が必要。眠いから起きてからやる
いつも使わせてもらっており大変助かっています。 要望なのですが、最大4枚の画像入力機能が欲しいです。 あると大変ありがたいです。 ご検討のほどよろしくお願いします…