監査上の理由からFargateがreadonlyRootFilesystemで動いてほしかったので、nginxコンテナを使った検証のメモ。
基本方針
- nginxイメージそのままでは動かないのでカスタムイメージを作る
/var
をタスクストレージにマウントする/tmp
は/var/tmp
へのsymlink- 二つ以上のタスクストレージをマウントできなかったため(二つ目以降のmountPointは無視された)
Dockerfile
FROM --platform=linux/amd64 nginx VOLUME /var # `VOLUME` を指定しておかないと # 元々のイメージにあるファイルが # マウントしたボリュームにコピーされなかった RUN rmdir /tmp && \ ln -s /var/tmp /tmp && \ rm /var/run /var/lock && \ mv /run /var/run && \ ln -s /var/run/lock /var/lock # このイメージでは `/var/run` `/var/lock` は # ぞれぞれ `/var/run` 配下へのsymlinkになっているので # 構成を変更する
ECSタスク定義 (ecspresso)
{ containerDefinitions: [ { cpu: 0, essential: true, image: '123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-nginx:latest', name: 'my-nginx-ro', portMappings: [ { containerPort: 80, hostPort: 80, protocol: 'tcp', }, ], readonlyRootFilesystem: true, mountPoints: [ { sourceVolume: 'var', containerPath: '/var' }, ], }, ], cpu: '256', memory: '512', taskRoleArn: 'arn:aws:iam::123456789012:role/MyTaskRole', executionRoleArn: 'arn:aws:iam::123456789012:role/MyExecRole', family: 'my-nginx-ro', networkMode: 'awsvpc', requiresCompatibilities: [ 'FARGATE', ], volumes: [ { name: 'var' }, ], // 必須ではない // ephemeralStorage: { // sizeInGiB: 50, // }, }
動作確認
root@ip-10-0-3-229:/# touch x touch: cannot touch 'x': Read-only file system root@ip-10-0-3-229:/# touch /tmp/x root@ip-10-0-3-229:/# touch /var/tmp/x root@ip-10-0-3-229:/#
その他
- 何もマウントしないと
/etc/hots
がタスクストレージにマウントされているように見えたが、なぜ… /var
がread onlyになるとECS execできなくなるということがわかった- タスクストレージで複数のmountPointを使う方法はわからなかった
- タスクストレージ以外でマウントするとなるとEFSかsidecarのボリュームか
- DockerボリュームはFargateでは使えないっぽい*1
参考
- Fargate タスクストレージ - Amazon Elastic Container Service
- バインドマウント - Amazon Elastic Container Service
- Docker ボリューム - Amazon Elastic Container Service
- コンテナのセキュリティ対策!AWS ECS (fargate)でタスクをreadonlyRootFilesystemで運用する | SEEDS Creators' Blog | 株式会社シーズ
2023/05/28 追記
ephemeralStorageをマウントしなくても書き込み可にはなった あとVOLUMEを複数書けば symlinkをごにょごにょしなくても、書き込み可のディレクトリ増やせた