カスタムAMIでService Connetが起動しない
事象
ECS on EC2で構築されたシステムに、サービス間通信暗号化のためにService Connectを導入しようとしたところ、うまく起動せず嵌ってしまった。
ECSサービスでService Connectを有効にすると、Service Connectのside car containerが正常に起動せずタスクが失敗してしまう。Service Connectでは以下ログが出力しており、/tmpディレクトリでbootstrap fileを作成できず起動に失敗しているように見える。
time="2025-03-25T08:45:28Z" level=error msg="Cannot create bootstrap file.
open /tmp/envoy-config-3516003767.yaml: permission denied"
原因
EC2のカスタムAMI作成の際にpermissionの変更をしていたことが原因だった。
公式のAmazon ECS-optimized AMIをベースとして、ansibleでCIS Benchmarksに対応するようセキュリティ設定を加えていた。この設定の中で、dockerのoverlay2で管理されるストレージ領域の書き込みpermissionを制限してしまっていた。
なぜカスタムAMI時点でのpermission変更がcontainer起動時の/tmpディレクトリに影響するのか?と思ったが、conatinerのストレージはimage layerとcontainer layerの重ね合わせとなるため、AMI作成時に存在するimage layerのpermissionを変更してしまうと、そのimageを元に起動するcontainerもpermission変更の影響を受けてしまう。
https://docs.docker.com/engine/storage/drivers/overlayfs-driver/#how-the-overlay2-driver-works
確認
実際にAmazon ECS-optimized AMI(Amazon Linux 2023)を起動して中身を見てみると、既にService Connectのimageがpullされている。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ecs-service-connect-agent interface-v1 c3db5c7ced40 3 weeks ago 170MB
amazon/amazon-ecs-agent latest 985cc8e388e3 4 weeks ago 105MB
amazon/amazon-ecs-pause 0.1.0 9dd4685d3644 10 years ago 702kB
docker historyコマンドでimage layerを確認すると、上から6番目のlayerで/tmpディレクトリを作成していることがわかる。
# docker history ecs-service-connect-agent:interface-v1
IMAGE CREATED CREATED BY SIZE COMMENT
c3db5c7ced40 3 weeks ago 24.1kB Agent Binary 'CMD ["/usr/bin/agent"]'
<missing> 3 weeks ago ADD https://github.com/krallin/tini/releases… 24.1kB buildkit.dockerfile.v0
<missing> 3 weeks ago ENV TINI_VERSION=v0.19.0 0B buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c chmod +x /usr/bin/agent && … 15.9MB buildkit.dockerfile.v0
<missing> 3 weeks ago ADD agent/appnet-agent /usr/bin/agent # buil… 15.9MB buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c mkdir -p /tmp && chmod 4777 /… 0B buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c chmod -R 0755 /agent-resource… 4.34kB buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c chmod +x /usr/bin/curl /usr… 65.1MB buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c ln -sf /bin/sh /usr/bin/sh # … 7B buildkit.dockerfile.v0
<missing> 3 weeks ago ADD health_check.sh /health_check.sh # build… 579B buildkit.dockerfile.v0
<missing> 3 weeks ago ADD THIRD-PARTY-LICENSES.txt /THIRD-PARTY-LI… 222kB buildkit.dockerfile.v0
<missing> 3 weeks ago ADD wasm/aws_appmesh_aggregate_stats.wasm /a… 351kB buildkit.dockerfile.v0
<missing> 3 weeks ago ADD agent/resources /agent-resources # build… 4.34kB buildkit.dockerfile.v0
<missing> 3 weeks ago ADD envoy-static /usr/bin/envoy # buildkit 59.4MB buildkit.dockerfile.v0
<missing> 3 weeks ago ADD curl /usr/bin/curl # buildkit 5.74MB buildkit.dockerfile.v0
<missing> 3 weeks ago COPY /usr/sbin/setcap /usr/sbin/ # buildkit 11.3kB buildkit.dockerfile.v0
<missing> 3 weeks ago COPY /usr/bin/chmod /usr/bin/grep /usr/bin/l… 405kB buildkit.dockerfile.v0
<missing> 3 weeks ago COPY /bin/sh /bin/vi /bin/cat /bin/ # buildk… 987kB buildkit.dockerfile.v0
<missing> 3 weeks ago COPY /lib64/ld-linux-x86-64.so.2 /lib64/libc… 4.61MB buildkit.dockerfile.v0
<missing> 3 weeks ago COPY /etc/pki /etc/pki # buildkit 965kB buildkit.dockerfile.v0
さらにdocker inspectコマンドを実行すると、imageの実データが格納されている場所がわかる。LowerDirが今までの積み重ねのlayer、UpperDirが最新のlayer、MergedDirがそれらの重ね合わせである。(WorkDirは一時的な作業ディレクトリ)
# docker inspect c3db5c7ced40 | grep Dir
"WorkingDir": "",
"WorkingDir": "/",
"LowerDir": "/var/lib/docker/overlay2/092c2524dc4267a98ff68c55c59943dfd9d2def48a89bcc3aceadebadfb8a10b/diff:/var/lib/docker/overlay2/11e0b34039d8ca0cf415a4f2033a67e74300dd33cc4dd1f3b6c30aeca0a76815/diff:/var/lib/docker/overlay2/9b85746a2fbaf4a2cf6c84a07cfdc454d1ab4e99ff069191cefbc5e8cee0908f/diff:/var/lib/docker/overlay2/3dd6a752030887c9980ee320b0d50245a969cd533c86aa3218ce144689a20b6b/diff:/var/lib/docker/overlay2/8f9b84d5227ec5accd28df1ed13bb6101a25d84955c59babc2d538739bae94cc/diff:/var/lib/docker/overlay2/eb2a8800850e0ea42fc40b9766669160c2a474c95267d33fa7f0c7a2637cb01d/diff:/var/lib/docker/overlay2/f5131e6af2efcf0ad25646c734ae8102f2c7ebe20e41a42ccddd3337532c99aa/diff:/var/lib/docker/overlay2/c3546ab8da352c2b9d6c8fc3b26ebaa5738896a9c33e90de6acb7aae58df1428/diff:/var/lib/docker/overlay2/ce9fe42f3f74317dca73bef7b5552c3b0353177882979f1c19cec9923cac28e2/diff:/var/lib/docker/overlay2/f36b8556762ec51d9dc6a03bfeb1422b82e0317376ae3c46ceade405f526690b/diff:/var/lib/docker/overlay2/4f015bcf8c1680fe37d84270de717261812f1a156a368f832b1f513a79309ddc/diff:/var/lib/docker/overlay2/56105c610b1d0748c705de25c945cd712710440b5255085433aec95a847178b2/diff:/var/lib/docker/overlay2/c1b7f4679e27a12b277a444d867ede7e98ce728ba4e40026637c6db4f2762510/diff:/var/lib/docker/overlay2/429f0ba583a686213c457b7b9369fb88d4f4fe20b262e5c14e14e2f4ba2f302c/diff:/var/lib/docker/overlay2/4855bdd1e12a8000af0d9102cf5f5897f383c17eff152c2782e1378047910737/diff:/var/lib/docker/overlay2/e966b961fc5f050bb27099728128fb4bcdf0f1eba2148cd9861cdcafa397a99f/diff:/var/lib/docker/overlay2/efd4a41478d74207e60b18a298141587b68df7008d50d7a2089eedbdf17cc636/diff:/var/lib/docker/overlay2/3f44f920975e4f42e139d4e5243ded9d72495929b4fcadb48fcd7d4c97e1088f/diff",
"MergedDir": "/var/lib/docker/overlay2/ef3d3fb44c414301107eb1305f8acd35286a9b1ef0fd7de0069090e6cd95ef9c/merged",
"UpperDir": "/var/lib/docker/overlay2/ef3d3fb44c414301107eb1305f8acd35286a9b1ef0fd7de0069090e6cd95ef9c/diff",
"WorkDir": "/var/lib/docker/overlay2/ef3d3fb44c414301107eb1305f8acd35286a9b1ef0fd7de0069090e6cd95ef9c/work
上から6番目周辺のLowerDirの中身を確認すると、/tmpディレクトリを発見した。(LowerDirに最新のlayerは含まれないのと、ENVを設定しているだけのlayerは実データに含まれないので、実際にはLowerDirの4番目のディレクトリに存在)
この/tmpディレクトリの書き込みpermissionを変更すると、このimageを元に起動するコンテナも影響を受けてしまう、というのが今回の原因だった。
# ls -l /var/lib/docker/overlay2/3dd6a752030887c9980ee320b0d50245a969cd533c86aa3218ce144689a20b6b/diff
total 0
drwxr-xr-x. 2 root root 6 Mar 22 10:15 etc
drwsrwxrwx. 2 root root 6 Mar 22 10:15 tmp
学び
無闇にoverlay2配下のimage layerを変更してはいけない
Discussion