お疲れ様です。矢儀 @yuki_ink です。
ECS、使ってますか??
ECSでコンテナを動かすにあたり、必ず用意しないといけないのが次の2つです。
- Dockerfile ※ひいてはDockerイメージ
- ECSタスク定義
DockerfileとECSタスク定義の目的や用途は以下の通りで、両者は相互補完の関係にあると思います。
項目 | Dockerfile | ECSタスク定義 |
---|---|---|
主目的 | イメージのビルド | イメージの実行設定 |
定義内容 | アプリケーション構築の手順 | コンテナの実行パラメータ |
再利用性 | アプリ単位で共通のものを利用 | 環境ごとに分ける |
機密情報の扱い | そもそも含めないようにする | Secrets ManagerやSSM Parameter Storeと連携して取得 |
ここで問題となるのは「どちらでも設定できる項目はどうすればいいの?」ということです。
記事執筆時点で、以下の項目については、Dockerfileでもタスク定義でも、どちらでも宣言できるものになっています。
- 環境変数(ENV)
- ヘルスチェック(HEALTHCHECK)
- エントリポイント・コマンド(ENTRYPOINT / CMD)
これらの項目について、どこで設定を定義すべきなのか考えていきます。
前提として、Dockerfileの設定よりタスク定義の設定の方が優先されます。
また、Dockerfileを修正すると、再度ビルド・ECRへのpushが必要になりますが、タスク定義だけなら、マネジメントコンソールからすぐに修正可能です。
そうを考えると、固定化する設定はDockerfileで、環境ごとに柔軟に設定する項目はタスク定義で というのが原則になると思います。
上記の上で、実運用を考えると、以下の2つの考え方ができます。
- とりあえずDockerfileにデフォルト値を書いておいて、必要に応じてタスク定義でも書けばヨシ
- Dockerfileとタスク定義で、それぞれで定義する項目をきっちり線引きする(タスク定義によるデフォルト値上書きはしない)
どちらの考え方もアリだと思いますが、いずれにせよ組織内でのルールを決めておくことが大事です。
その検討の中で役に立てばいいなという情報と私なりの考察を、以下に残しておきます。
定義場所 | 推奨度 | 理由 |
---|---|---|
Dockerfile | △ | 環境ごとの切替ができない。(むしろ固定させたい値についてはDockerfileでもいいかも) |
タスク定義 | ○ 推奨 | デプロイ時に本番・ステージング・開発(Prod/Stg/Devなど)を指定して、簡単にアプリの動作を切り替えることができる。Secrets Manager/SSMとの連携も可能。CI/CDパイプラインで変数を差し込める柔軟性あり。 |
秘密鍵やDB接続文字列などはDockerfileに書かず、タスク定義で設定するのが原則です。
Dockerfileの ENV
は、開発・ビルド時の設定用、あるいはデフォルト値程度に使うという考えで良いと思います。
定義場所 | 推奨度 | 理由 |
---|---|---|
Dockerfile | △ | イメージに一体化したヘルスチェックで、どこで動かしても共通。ローカル開発で有効だが、ECSのオーケストレーションとは無関係。 |
タスク定義 | ○ 推奨 | ECSのオーケストレーションと連動。間隔・リトライなど柔軟に変更可。 |
ECSのヘルスチェックを利用することで、ステータスが「UNHEALTHY」なタスクを停止し、自動で新しいものに置き換えることが可能になります。
せっかくECSを使うなら、こちらを利用したほうが良いでしょう。
AWSのブログでは、最初にDockerfile上の HEALTHCHECK
でヘルスチェックコマンドの正しさを確認したあと、同じ設定をタスク定義に仕込むことが推奨されています。
コンテナインスタンスをローカルでテストして、コンテナのヘルスチェックに合格することを確認する
コンテナインスタンスを Amazon ECS にプロビジョニングする前に、期待どおりに動作することを確認します。Docker Docs のウェブサイトにある HEALTHCHECK を使用してコンテナをテストします。コンテナが Dockerfile のヘルスチェックに合格することを確認します。次に、タスク定義でヘルスチェックの設定を指定し、Amazon ECS コンテナエージェントがヘルスチェックを監視、レポートできるようにします。注: Docker ヘルスチェックがコンテナイメージに埋め込まれているがコンテナ定義で指定されていない場合、Amazon ECS ではモニタリングされません。コンテナ定義で指定されているヘルスチェックのパラメータは、コンテナイメージ内に存在する Docker ヘルスチェックを上書きします。
(出典)Amazon ECS タスクがコンテナヘルスチェックに合格できない場合に、トラブルシューティングする方法を教えてください。
用途 | 定義場所 | |
---|---|---|
ENTRYPOINT |
コンテナ起動時に必ず実行すべきコマンド | 変更されにくい処理のため、Dockerfileでの定義を推奨。処理をシェルスクリプトとしてまとめて、Dockerfileと一緒にバージョン管理するのが良い。 |
CMD |
デフォルトの引数またはコマンド(ENTRYPOINT の引数として使うことが多い) |
変更が少なければDockerfile、変更が多ければECSタスク定義で。とりあえずデフォルト値をDockerfileに仕込むのも◎ |
繰り返しになりますが、固定化する設定はDockerfileで、環境ごとに柔軟に設定する項目はタスク定義で という原則に照らし合わせて考えていただければと思います。
以下、一例を示します。
-
ENTRYPOINT
はアプリケーション本体の実行など、変更されることがない処理(例:ENTRYPOINT ["python", "app.py"]
)として設定。 -
CMD
はデフォルト引数や動作モード(例:CMD ["--serve"]
)として設定。
ENTRYPOINT ["python", "app.py"]
CMD ["--serve"]
ECSタスク定義側で CMD を ["--debug"]
にオーバーライドして、一時的なトラブルシューティングなどに利用することも可能です。
以上、DockerfileとECSタスク定義の使い分けについて考えてみました。
「各種設定がどこで、どのように定義されているか」のルールが明確だと、トラブル時の調査・再現性・チーム内の認識合わせがとてもスムーズになります。
この記事を参考に、皆さんの組織で最適なルールを検討していただければ幸いです。
ここに記載した内容は私個人の意見なので、他にご意見があれば、積極的にコメントいただけますと幸いです!
よろしくお願いいたします!
参考にさせていただきました。
ありがとうございました。
Views: 0