はじめに
皆さん、どうもです。k.s.ロジャースのやすもんです。
今回は、先日構築したECSのamazonlinux2環境でコンテナインスタンスがぶっ壊れるという落とし穴にハマったので、現象の共有と回避方法を書いていきたいと思います。
前提
- AWSのECS上に構築する
- イメージはamazonlinux2を利用
- systemctlを利用してサービスの管理をしたい
ECS上に上記の前提でhttpdが動くコンテナを作成
まずはローカルで構築
適当にhttpdが動くdockerを用意します
# amazon linux
FROM amazonlinux:2
# httpd24
RUN yum -y install httpd
RUN systemctl enable httpd.service
ビルドしてコンテナ起動
$ docker build -t test:latest ./
$ docker run --privileged -d -t -p 8080:80 --name testapp test:latest /sbin/init
ECSにデプロイする
タスク定義を作成
systemctlを利用するために特権付与し、コマンドで/sbin/init
を指定
落とし穴
一見、上記まで実行して「あれ?できてるやん?」て思うかもしれませんが、落とし穴はここからです
ECSを利用している方々は、CIを組んで自動でデプロイできる仕組みを作り、頻繁にイメージとコンテナが更新されるという運用をしている方が大半だと思います。
ということで、次に全く同じ構成で新しいタスク定義を作成して手動で更新してやりましょう
タスクを停止します
エラー内容は
CannotStartContainerError: API error (500): cgroups: cannot find cgroup mount destination: unknown
ほう。。。cgroupをマウントできずにエラーとな。。。
色々調査して以下のような記事を見つけて対応しようと試みるも。。。
http://blog.livedoor.jp/kkss06122015-armadillo/archives/10167213.html
そもそも、ECSのインスタンスの/sys/fs/cgroup
配下はからっぽ。。。
記述されているsudo mkdir /sys/fs/cgroup/systemd
も権限エラーで実行できず、systemdを無理やり作ってマウントすることも不可でした。
どうやら、特権付与(privileged)をtrueにしてしまうと初回起動はするが、その後コンテナを更新したときにマウントエラーが発生し、以降コンテナが立ち上がらなくなるみたいだ・・・
そして、systemctlを利用するには、特権付与(privileged)をtrueにしないといけない。
特権付与(privileged)をtrueにせず、systemctlを使えようにする方法など色々調査して実験してみたが、この現象を回避する方法はなさそうだった。
回避方法
では、この落とし穴をどう回避するのかというと、docker経験者はピンとくるかもしれませんが、foreground固定します。
また、殆どの場合systemctlを利用したい場合は複数のサービスを起動させたいという理由があると思うので、以下のように記述します。
# amazon linux
FROM amazonlinux:2
# httpd24
RUN yum -y install httpd php-fpm
CMD /bin/bash -c "httpd && php-fpm && tail -f /dev/null"
こうすることで、systemctlを利用しないため、特権付与(privileged)が不要になります。
よって、コンテナを再作成したときのcgroupのマウントエラーが発生しなくなるという感じです。
補足ですが、Dockerfile上でCMDを指定したのでタスク定義で指定していたcommandの/sbin/init
は不要になります。
最後に
今回はECS上にamazonlinux2を構築したときにハマった落とし穴を紹介しました。
実際に私自身この落とし穴に2~3日ハマって、systemctlは利用しないという結論に至りました。
もっとスマートな解決法を知っている方はコメント欄にて教えて頂きたいです!
Wantedlyでもブログ投稿してます
Techブログに加えて会社ブログなどもやっているので、気になった方はぜひ覗いてみてください。
https://www.wantedly.com/companies/ks-rogers