😇

カスタム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