Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JAWSPANKRATION2024-ECS Best Practice All on boa...

t-kikuchi
August 25, 2024

JAWSPANKRATION2024-ECS Best Practice All on board(japanese)

JAWSPANKRATION2024-ECS Best Practice All on board(japanese)

t-kikuchi

August 25, 2024
Tweet

More Decks by t-kikuchi

Other Decks in Technology

Transcript

  1. Self-Introduction 2 • 【Name】:Toshinori Kikuchi • 【Company Affiliation】:Classmethod, Inc. •

    【AWS Title】 ◦ 2024 Japan AWS Top Engineers ◦ 2024 Japan AWS All Certifications Engineers • 【Blog】 https://dev.classmethod.jp/author/tooti/ • 【X】 https://x.com/tttkkk215 • 【Favorite Technologies】 Containers, Terraform, Amazon EventBridge, AWS Step Functions
  2. 3 このセッションの対象者と目標 • 対象者 ◦ ECSを使い始めたばかりの方 ◦ ECSを使っているが、正しく使えてるかわからない。 ◦ ECSに移行し、次のステップを模索している。

    • 目標 ◦ ECSのベストプラクティスに沿ったシステム構築ができる ◦ 現行のECSに基づいて構築されたシステムの改善点を特定で きる
  3. 4 Amazon ECSのベストプラクティスとは? • AWSはECSのベストプラクティスとして以下のドキュメントを発行し ています。 ◦ Amazon ECS ベストプラクティス

    ■Amazon Elastic Container Service • AWS Service Delivery Program(Amazon ECS Delivery Partners)には、ECSのデリバリがベストプラクティスに沿っている かどうかを確認するためのチェックリストがあります。 • 私はこれらのドキュメントを基に独自のチェックリストを作成した。 ◦ https://github.com/ice1203/ecs-bestpractice-checklist
  4. 7 • 考慮すべき設計のポイント CI/CD • ソース管理 ◦ どのバージョン管理システムを使うか( GitHub、GitLabな ど)

    ◦ システムのどの単位でリポジトリを分けるか ◦ インフラとアプリケーションでリポジトリを分けるかどうか ◦ ブランチの保護方法(ブランチ保護ルールの使用など) • ブランチ戦略の確立 ◦ どのようなブランチ戦略を使うか( GitFlow、GitHub Flow、TrunkBaseなど) ◦ 環境の違いをどのように表現するか • パイプライン全体の設計 ◦ どのCI/CDツールを使うか(GitHub Actionsなど) ◦ プロセスの流れは? ◦ 各ステージの役割と目的を明確にする • トリガーを設定する ◦ どのような処理をトリガーするか ◦ 定期的な実行の有無(例:毎日のビルド) ◦ 手動トリガーオプションの提供 • テストの自動化 ◦ どのようなテストを行うのですか? ▪ 単体テストと統合テスト • IaCの選択 ◦ どのIaCを使うか ▪ AWS CDK ▪ テラフォーム ◦ ECSタスク定義、サービス管理方法 • 展開方法の選択 ◦ どのデプロイメント戦略? ▪ ブルー/グリーン・デプロイメント ▪ ローリングアップデート • ロールバック戦略 ◦ 自動ロールバックメカニズム ◦ 手動ロールバック・プロセスの確立 • セキュリティ・スキャン ◦ どのようなセキュリティスキャンを行いますか? ▪ コンテナ・イメージの脆弱性スキャン ▪ IaCコードのセキュリティ・スキャン • 監視と通知設定 ◦ デプロイの成功/失敗の通知 ◦ デプロイ中に監視するメトリクスの決定 など
  5. 9 CI/CD (IaC) • ecspresso ◦ ECSのサービスやタスク に関連するResourceの コード管理やデプロイの ためのツール

    ◦ tfstateファイルを読み込 んでリソース情報を参照 できる ◦ CloudFormation Outputs、Export値も読 める ◦ 最低限管理するファイル は3つだけ
  6. 10 • ecspressoでデプロイする際の注意点 ◦ ecspressoで管理できるのは、ECSのタスク定義とサービス定義 のみです。 ◦ ApplicationAutoScalingとCodeDeployは対象外です。 ◦ 初回は以下のように構築します。

    i. IaC(Terraformなど)でALB、ECSクラスタなどを作成 ii. ecspressoによるECSタスク定義、ECSサービス作成 iii. IaCでCodeDeployやAutoScalingを作成 ◦ 初回構築以降は、(基本的に)ecspressoとIaCは独立して更新で きます。 CI/CD (IaC)
  7. 11 • どのようなブランチ戦略を使うべきか? ◦ チームの規模やリリースサイクル、企業文化などによって適切 な形は異なるため、正解はありません。 ◦ コンテナ特有の検討事項として、環境間でコンテナイメージを 共有するかどうかがある。 ▪

    個人的には共有した方がいいと思う。 ◦ それぞれのタイミングで何をすべきかを考えたので、インフラ とアプリに分けて考えてみる CI/CD(ブランチ戦略) ブランチカット
  8. 15 * Image source: DevelopersIO, https://dev.classmethod.jp/articles/ecs-deploytype/ CI/CD(デプロイ) • ローリングアップデート ◦

    利点 ▪ シンプルであるため、設 計と構築が比較的容易 である。 ▪ シンプルな設計のため、 故障箇所が限定される (その結果、トラブル シューティングが容易に なる) ◦ デメリット ▪ 古い仕事と新しい仕事が 混在する瞬間がある
  9. CI/CD(デプロイ) 16 • ブルー/グリーンデプロイ ◦ 利点 ▪ アプリケーションを一度に切り替え られるので、新旧のタスクが混在し ない

    ◦ デメリット ▪ ロードバランサーが必要 ▪ 構成が複雑なため、設計・構築が 比較的難しく、新メンバーが理解す るのに時間がかかる。 ▪ 追加の設定ファイルを管理する必 要がある(CodeDeployの設定な ど)。 ▪ プロセスが複雑で、トラブルシュー ティングが難しくなる。 *画像ソース: DevelopersIO、https://dev.classmethod.jp/articles/ecs-deploytype/
  10. 17 CI/CD(デプロイ) ecspresso.yml • ecspressoを使うことで、B/G デプロイの管理要素も減らす ことができます。 ◦ appspec.yamlは基本的 に不要です。

    ◦ AutoScalingの停止コマ ンドが用意されているの で、CDプロセスにコマン ドを含めるだけで、デプロ イの前後にAutoScaling を停止したり再起動した りできます。 cluster: default service: test service_definition : ecs-service-def.json task_definition: ecs-task-def.json appspec: Hooks: - BeforeInstall: "LambdaFunctionToValidateBeforeInstall" - AfterInstall: "LambdaFunctionToValidateAfterTraffic" - AfterAllowTestTraffic : "LambdaFunctionToValidateAfterTestTrafficStarts" - BeforeAllowTraffic : "LambdaFunctionToValidateBeforeAllowingProductionTraffic" - AfterAllowTraffic: "LambdaFunctionToValidateAfterAllowingProductionTraffic"
  11. 18 • 考慮すべき設計の主要な側面とは? タスクの定義 • タスクサイズ ◦ アプリケーション要件に基づく CPUとメモリの適切な割り 当て

    ◦ リソース制限の設定 • コンテナ・イメージ ◦ 信頼できるリポジトリからの最新で安定したイメージの使 用 ◦ 多段階ビルドの使用 ◦ イメージサイズの最小化 ◦ グレースフル・シャットダウンの導入 ◦ 画像のタグ付け(LATESTタグの使用を避ける) • ストレージの設定 ◦ どのストレージを使うべきか? ◦ EFSによる永続データの統合 ◦ 一時ストレージの適切なサイジング • セキュリティの強化 ◦ タスクロールとタスク実行ロールの適切な構成 ◦ 最小権限の原則に基づく IAM ポリシーの適用 ◦ readOnlyRootFilesystem • ログ設定 ◦ CloudWatch ログ ◦ firelensを考える • 環境変数の管理 ◦ 機密情報の安全な管理( AWS Secrets Managerの使 用) • ヘルスチェックの実装 ◦ コンテナのヘルスチェックコマンドの定義 ◦ 適切なタイムアウトと間隔の設定 • コンプライアンスと監査 ◦ 必要なタグの適用 ◦ 監査要件に基づくログ設定 • ネットワーキングの最適化 ◦ ENIトランキングの設定(必要な場合) その他
  12. Task Definisions(TaskSize) 19 fields @timestamp, CpuUtilized, CpuReserved, CpuUtilized * 100

    / CpuReserved as CpuUtilization, MemoryUtilized, MemoryReserved, MemoryUtilized * 100 / MemoryReserved as MemoryUtilization | filter ContainerName = "xxxxx" and Type = "Container" and TaskId = "yyyyy" | sort @timestamp asc | limit 10000 | stats avg(CpuUtilization),avg(MemoryUtilization) by bin(1m) • 結論から言えば、稼働率をチェックし、パフォーマンステストなどで 調整するのがベストだ。 • 各コンテナの利用率を確認するには ◦ コンテナインサイトを有効にする ◦ Cloudwatch Logs Insightsで以下のクエリを実行する。
  13. 22 • コンテナ・レベル: 各コンテナのCPUおよびメモリの予約または制 限。 • ContainerInsightsは、コンテナレベルでCPUとメモリを設定しない と、コンテナごとの使用率を記録しないことに注意してください。 ◦ CPU:

    ▪ タスクレベルのCPU設定が利用可能な最大CPUを表してい るのに対して、コンテナレベルのCPU設定はCPU占有率で 重み付けされる。 ▪ この重み付けは、CPUが競合している場合にのみ有効であ る。 タスク定義(タスクサイズ)
  14. 23 • コンテナ・レベル: 各コンテナで使用可能なCPUとメモリの予約また は制限 ◦ メモリ ▪ ソフトリミットのみを指定する: 上限はタスクレベルで指定され

    た値(タスクに複数のコンテナがある場合、タスクレベルでメ モリ量を奪い合う)。 ▪ ソフトリミットとハードリミットを指定:ソフトリミットは予約、ハー ドリミットは上限を表す。 ▪ ハードリミットのみ指定:ハードリミットは予約と上限を表す タスク定義(TaskSize)
  15. 24 • Dockerfileのベストプラクティス ◦ マルチステージビルドの使用 ◦ 1コンテナ1プロセス ◦ ルートユーザーとして実行しない ◦

    コンテナはステートレス(状態を保持しない)。 ◦ コンテナ・イメージのサイズをできるだけ小さくする ◦ など ◦ 詳細はこちら。 ▪ https://docs.docker.jp/develop/develop-images/dockerfile _best-practices.html タスクの定義
  16. タスク定義 25 # ビルドステージ FROM node:22 AS builder WORKDIR /usr/src/app

    # package.jsonとpackage-lock.jsonはバインドマウントされているのでコピーする必要はない #COPY package*.json ./ # 依存関係をインストールする。 RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ --mount=type=cache,target=/root/.npm,sharing=locked \ npm ci --omit=dev # アプリケーションのソースコードをコピーする COPY . . # 実行ステージ FROM gcr.io/distroless/nodejs22-debian12 # ビルド段階からアプリケーション・ディレクトリをコピーする COPY --chown=nonroot:nonroot --from=builder /usr/src/app /usr/src/app USER nonroot WORKDIR /usr/src/app CMD [ "index.js" ]。 • 最近学んだこと ◦ RUN --mount=type=bind ▪ バインドマウント中にコマン ドを実行する ▪ 不要なCOPYを減らすこと ができる。 ◦ RUN --mount=type=cache ▪ キャッシュディレクトリをマ ウントする。 ▪ レイヤーキャッシュではな いので、依存パッケージに 変更があっても、最初から ダウンロードされることはな い。
  17. タスク定義 26 # php FROM php:7.4-fpm-alpine as app_php RUN apk

    add --no-cache git COPY --from=composer:latest /usr/bin/composer /usr/bin/composer WORKDIR /var/www/html COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-interaction --no-progress COPY . . CMD ["php-fpm"]. # NGINX FROM nginx:1.17-alpine AS app_nginx COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/ WORKDIR /var/www/html COPY --from=app_php /var/www/html/public public/ • 最近学んだこと ◦ docker build --target=~ . ▪ 中間ステージを成果物とし て生成することができま す。 ▪ 例えば、テスト用のステー ジを用意し、テスト時にそ のステージを --target とし て指定することができま す。 ▪ 多くのDockerfileを用意す る必要はないかもしれな い。
  18. • 画像のチェック ◦ 画像のチェック ▪ 脆弱性が含まれていないか ▪ Dockerfileの書き方に脆弱性はないか? ◦ チェックするタイミング

    ▪ ビルド時のチェック ▪ 定期的なチェックも重要 • Amazon Inspector 拡張スキャンは脆弱性DBにCVEが追 加されると自動的にスキャンする コンテナセキュリティ(レジストリ) 28
  19. 30 • ランタイムセキュリティ ◦ GuardDuty ランタイム監視 ▪ 2023/11アップデートで追加されたECSのランタイムモニタリ ング ▪

    AWSネイティブサービスが実行時に脅威を検知できるように なった ▪ 脅威を検出するだけだが、脅威が検出されたときに自動的に アクション(ECSタスク停止など)を取りたい場合は組み込む 必要がある コンテナ・セキュリティ
  20. コンテナのセキュリティ 32 • ランタイムセキュリティ ◦ GuardDuty ランタイム・モニタリング vs Sysdig Secure

    ▪ 対応ルール数 • 36 vs. 少なくとも150以上ある。 ▪ 検出速度 • 約2分(※1) vs. 数秒 ▪ ルールのカスタマイズ • 不可能 vs. 可能 1 実際にインシデントが発生してからGuardDutyにイベントとして登録されるまでの時間(筆者 計測)。
  21. 35 オブザーバビリティ • AWS Distro for OpenTelemetry(ADOT)とは? ◦ AWSがサポートするOpenTelemetry(OTel)ディス トリビューション

    ◦ OTelはCNCFプロジェクトの一つなので将来性も ある ◦ AWSサービスとの高い互換性 • 主なコンポーネントはSDKとコレクター • トレースだけでなく、ログやメトリクスも収集可能 • トレース情報は、X-Ray、CloudWatch、Prometheus などに送信できる。 • ECS Fargateの場合、コレクターはサイドカー・コンテ ナとして実装されている。 *画像ソース: One Observability Workshop,https://catalog.workshops.aws/observability/ja-JP/aws-managed-oss/adot/gowalk through
  22. 36 * For more information, see here. https://aws-otel.github.io/docs/getting-started/java-sdk/auto-instr • 実装方法

    ◦ AutoInstrumentationエージェントをサポートしている言語であれ ば簡単に実装できる。 ◦ Javaの例 i. アプリケーションのコンテナイメージに自動計測エージェント jarを含める ii. ECSタスク・ロールとECSタスク実行ロールにIAMポリシーを 追加 iii. 上記のコンテナイメージを含むECSタスク定義に、サイドカー コンテナとしてOTelコレクタを追加。 オブザーバビリティ
  23. オブザーバビリティ 37 FROM amazoncorretto:17-alpine WORKDIR /アプリ ADD https://github.com/aws-observability/aws-otel-java-instrumentation/releases/download/v1 .21.1/aws-opentelemetry-agent.jar /app/aws-opentelemetry-agent.jar

    ENV JAVA_TOOL_OPTIONS "-javaagent:/app/aws-opentelemetry-agent.jar" ARG JAR_FILE=build/libs/*.jar COPY --from=build /app/${JAR_FILE} ./app.jar # OpenTelemetryエージェントの設定 ENV OTEL_TRACES_SAMPLER "parentbased_traceidratio" env otel_traces_sampler_arg "0.3" ENV OTEL_PROPAGATORS "tracecontext,baggage,xray" ENV OTEL_RESOURCE_ATTRIBUTES "service.name=PetSearch" env otel_imr_export_interval "10000" env otel_exporter_otlp_endpoint "http://localhost:4317" ENTRYPOINT ["java","-jar","/app/app.jar"]。 環境変数についてはこちらをご参照ください。,https://opentelemetry.io/docs/languages/sdk-configuration/general/ • 環境変数でサンプリ ングレートや Observability Backendに表示され るサービス名などを 変更することができ ます。
  24. オブザーバビリティ 38 { "name" : "aws-otel-collector" 、 "image" : "public.ecr.aws/aws-observability/aws-otel-collector:v0

    .32.0" 、 "cpu" : 64 、 "メモリー" : 256 、 "links": []、 "portMappings" : []、 "essential" : true 、 "entryPoint": []、 "command": [ "--config" 、 "/etc/ecs/ecs-cloudwatch-xray.yaml" ], • コレクター docker イ メージにはデフォル トでいくつかの設定 ファイルが含まれて おり、コンテナを起 動する際に引数とし て設定ファイルを指 定することができる。
  25. • Amazon ECS best practices - Amazon Elastic Container Service

    • ECSのローリングアップデートとブルー/グリーンデプロイを比較してみた | DevelopersIO • Amazon ECS タスク定義の"タスクサイズのCPU"と”コンテナのCPUユニット”の違いを調べてみた - のぴぴのメモ • How Amazon ECS manages CPU and memory resources | Containers • AWS ECS コンテナ毎のメトリクスを取得する #CloudWatch - Qiita • https://github.com/phamthanhgiang/ECS-Fargate-hands-on/ • Dockerfile を書くベストプラクティス — Docker-docs-ja 24.0 ドキュメント • トレース|OpenTelemetry入門 40 bibliography