AWSコンテナ設計・構築[本格]入門のまとめ
コンテナの概要
-
他のプロセスとは隔離された状態でOS上にソフトウェアを実行する技術
- 隔離がポイントで、コンテナ上で実行されたソフトウェアは単に一つのプロセスとして稼働しているにも関わらずコンテナ内のソフトウェアから見ると独立したOS環境を占有しているように見える
-
コンテナ技術ではOSとカーネルは共有し、プロセスを分離する仕組み
-
そのため、コンテナのプロセスごとにプロセッサやメモリ等のコンピューティングリソースが割り当てられる
コンテナ利用のメリット
- 環境依存からの解放
- アプリケーションの稼働に必要なランタイムやライブラリをパッケージとしてひとまとまりにでき、アプリケーションの依存関係をコンテナ内で完結させることができる
- コンテナを利用したアプリケーションではデプロイ及び実行の単位が依存関係を含めたコンテナになるので、一度ビルドしたイメージを異なる環境(開発環境、ステージング環境、プロダクション環境等)で使ってもアプリケーションとしての同一性が担保でき、環境ごとの差異に悩まされなくて済む
- 環境構築やテストに関する時間の削減
- 環境依存からの解放と被る部分はあるが、再現性とポータビリティによる生産性の向上もメリットとしてあげられる
- 前述のとおりコンテナという単位でパッケージに実行環境やライブラリが含まれるので、一度定義しておけばローカルでも本番でもコマンド一つで同じ環境が再現できる
- リソース効率
- コンテナではOSから見れば1つのプロセスが稼働している扱いになる
- そのため、コンテナ側ではゲストOSやハードウェアのエミュレーションが不要となり、仮想化と比較してリソースの消費が少なく抑えられる
- アプリケーションの起動も高速
Dockerとは
Dockerはコンテナのライフサイクルを管理するためのプラットフォーム。
Dockerを利用することで、アプリをイメージとしてビルドしたり、イメージの取得、保存、起動などが簡単に行える。
Dockerの登場人物
Dockerの基本操作
オーケストレータとは
ビジネスが成長し、多数のコンテナ連携が求められる場合には、単一ホストではなく複数ホストから構成されたクラスター構成を使うことになる。
クラスター構成の場合には分散ホスト環境上のコンテナに対してリクエストの負荷分散やダウンタイムを再消化するアップデート方法を考える必要が出てくる。
コンテナ技術の導入のための考慮ポイント
- コンテナを前提としたアプリケーション開発のあり方
- 自然と分散システム構成に近づく。そのため、コンテナ間の疎結合性や移植性を考慮した方式を検討しなければならない。
- 具体的な方法論としてThe Twelve-Factor Appがあるので、クラウドネイティブな構成への親和性が高まる
- コンテナ設計・運用
- 開発チームにおける役割分担
コンテナ設計に必要なAWSの基礎知識
コントロールプレーン
コンテナを管理する機能としてAWSには以下2種類のサービスがある。
- ECS
- EKS
データプレーン
コンテナが実際に稼働する環境
- EC2
- Fargate
リポジトリ
- ECR
その他
内部的にコンテナが利用されているサービス
- AWS Lambda
- AWS App Runner
アーキテクチャの構成例
- ECS on EC2
- ECS on Fargate
- EKS on EC2
- EKS on Fargate
各アーキテクチャに適応したユースケース
ブロックチェーンを利用するフルノード
Ethereumを前提にすると、接続するブロックチェーンの全てのブロックを保持するため、大容量のデータをローカルに保持する必要性がある。
ストレージ容量としてはEC2とFargateでそれぞれ以下が最大の容量であるため、データプレーンとしてはより多くのデータを保持できるEC2を採用する方がよい。
- EC2
- 最大16TB
- Fargate
- 最大200GB
コントロールプレーンとしてはEKSとECSのどちらでも運用可能
機械学習のアプリケーション
GPUを使用する前提の場合、Fargateは制約としてGPUに未対応になっている。
そのため、データプレーンとしてはEC2を採用する方がよい。
コントロールプレーンはECSとEKSのどちらでも良いが、データサイエンティストなどインフラにそれほど強くないメンバーが多いならEKSよりもECSを使う方が学習コストの面で良い。
ただ、AWS以外のクラウドで動かすことも視野に入れるならEKSを選択した方がいいかも。
高いリソース集約率を実現したい場合
EC2の場合、処理ごとに異なるインスタンスタイプのEC2を立ち上げて処理を実行するのは大変。
Fargateなら処理に応じてCPUやメモリの要件を指定して実行することが可能で、リソースを無駄なく活用することができるため、リソース集約率を求めるならデータプレーンとしてはFargateの方が向いている。
コンテナを利用したAWSアーキテクチャ
設計に関して考慮すべきポイントやベストプラクティスを全体的に把握することで考慮の抜け漏れを防ぐ他、効率的なシステム設計につながる。
Well-Architectedフレームワークの活用
5つの柱が定義されており、これに基づくことで前述のとおり考慮漏れなどを防ぐことができる。
- 運用上の優秀性
- セキュリティ
- 信頼性
- パフォーマンス効率
- コスト最適化
運用設計
運用上の優秀性の観点から以下のような設計上の検討事項が挙げられている。
- どのようにシステムの状態を把握するか
- どのように不具合の修正を容易にするか
- どのようにデプロイのリスクを軽減するか
モニタリングとオブザーバビリティの重要性
システム内部の状態を把握することは健全なサービスを提供する上で重要だが、システムが正常であると判断するにはデータが必要。
システム内で定めた状態を確認し続けることをモニタリングという。
モニタリングの主な目的はシステムの可溶性を維持するために問題発生に気づくこと。
一方で、発生原因を調査するにはより詳細にトランザクションの流れなどを追う必要がある。
AWSにおけるコンテナを利用したアプリでは粒度の小さいアプリケーションやAWS各種サービスが相互に連携し合う分散的なシステム構成となることが多くなる。
そうした分散的なシステム構成では影響範囲の把握や原因の特定が難しくなる。
- トレース
- コンポーネント間やアプリケーション内部の処理内容を追うための情報
- オブザーバビリティ
- システム全体を俯瞰しながら内部状態まで必要に応じて深掘りできる状態のこと
オブザーバビリティを獲得するためには以下3つの要素が必要になり、AWSのサービスが活用できる。
- メトリクス
- トレース
- ログ
ロギング設計
- CloudWatch Logs
- File Lens
2つのサービスの使い分け
ECSタスク定義ではコンテナごとに指定するログ出力先は1つだけ。
エラーログはCloudWatch Logs、アクセスログはS3に保存したい場合、
- CloudWatch Logsに全てのログを転送し、CloudWatch LogsからS3にエクスポート
- CloudWatch Logsはログを取り込んだタイミングで料金が発生するため、費用がかかる(月200GBで$152)
Fluent BitはCloudWatch LogsとS3への同時ログ転送や片方のみへの転送に対応しているため、FireLensを活用することがおすすめ。
メトリクス設計
トレース設計
CI/CD設計
CI/CDの恩恵
アプリケーションを稼働させるにはビルド、テスト、デプロイといった手順が必要になる。
- ビジネスのアジリティを高めるには開発サイクルを早めることが重要
-同じ手順になりがちなビルドやテスト、デプロイを自動化することにより開発サイクルを高速化できる(顧客に早く成果を届けられる)- この自動化の手段として登場するのがCI/CD
- 開発ライフサイクルで必要な作業プラクティスをパイプラインとして定義することで
- また、品質改善の効率化も見込める
コンテナとCI/CD
コンテナの特性である優れたポータビリティや再現性がCI/CDと相性が良い。
開発環境、ステージング環境など異なる環境ごとにシステム構成が違うケースが考えられるが、
Bastion設計
セキュリティ設計
責任共有モデルの理解
責任共有モデルに基づいて利用者側でセキュリティ対策を行う箇所を判断する。
例えば以下2つの構成それぞれでAWS側で対策すべき範囲と利用者側で管理すべき範囲は変わる。
- ECS + EC2
- ECS + Fargate
コンテナ開発のセキュリティベストプラクティス
アメリカ国立標準技術研究所(NIST)がSP800-190というセキュリティのガイダンスを公開しており、これがコンテナのセキュリティに関する基準として使える。
具体的には以下5つの観点でセキュリティ上の懸念点と対策の推奨事項を提供している。
- イメージ
- レジストリ
- オーケストレータ
- コンテナ
- ホスト
これについても責任共有モデルを利用することで、どの点に対して対策をすればいいかが明確になる。
イメージ
イメージの脆弱性への対策
-
ECRによる脆弱性スキャン
-
Trivyによる脆弱性スキャン
- OSパッケージだけでなく、PythonやNode.ja等、アプリケーションの依存関係もスキャン対象となる点が特徴
-
継続的なスキャンの実現
- 時間が経てばイメージ内のライブラリ等も古くなるのでCI/CDに組み込んで継続的に実施するのが有効
- CI/CDに組み込んだとしても実行タイミングも重要で、プッシュ時のみのスキャンでは開発やリリースが頻繁に行われないアプリでは気付くのが遅れる。開発サイクルによっては定期的なスキャンの実行が推奨される。
-
イメージ設定の不具合への対策
- Dockerfileは開発者が作成するが、セキュリティ的に好ましくない設定内容になってしまう可能性もある
- Dockerのベストプラクティスに準じているかガイドライン等はあるが全てを開発者がチェックするのは大変
- OSSのDockleなどを使って自動的にチェックを実施できる
-
埋め込まれたマルウェアへの対策
- 提供元が信頼できるベースイメージの利用
- GuardDutyの活用
-
埋め込まれた平文の秘密情報への対策
- データベースへの接続情報など秘密情報をソースコードやイメージ内に埋め込んでしまうと危険なので、イメージ外の安全な領域に格納し、コンテナを実行する際に同的に提供
信頼性設計
パフォーマンス設計
パフォーマンス設計の考え方
- 高度なテクノロジーの民主化
- わずか数分でグローバル展開する
適切なリソース設計
- ECS/Fargateではスケールアップとスケールアウト双方の戦略が採用可能
- スケーラビリティが高いスケールアウト構成が推奨される
- スケールアップは割り当て可能なリソース上限に到達しやすい
- パフォーマンス効率だけでなく、可用性と耐障害性が向上する
- スケーラビリティが高いスケールアウト構成が推奨される
スケールアウト戦略の実装方法
以下二点の考慮が必要。
- サービスクォータへの考慮
- IPアドレス枯渇への考慮
Application Auto Scalingの活用
CloudWatchアラームで定めたメトリクスの閾値にしたがってスケールアウトやスケールインを実行できる。
- ステップアップスケーリングポリシー
- スケールアウトやスケールインの実行条件にステップ(段階)を設けることで段階的にスケールアクションを実行できる
- ターゲット追跡スケーリングポリシー
- 指定したメトリクスのターゲット値を維持するようにスケールアウトやスケールインを実行する。
- AWS側で自動で調整を行ってくれるものであり、ステップアップスケーリングポリシーと比較してよりマネージドで管理が楽になる
- ただし、以下のポイントを抑えておく必要がある
- メトリクスがターゲット値を数値的に超えている場合のみスケールアウトする
- スケールアウトは高速に動作するが、スケールインは緩やかに実行される
ポリシーについては上記の特性があり、まずはチューニング箇所が少ないターゲット追跡スケーリングポリシーを採用するのがおすすめ。
コスト最適化設計
Well-Architectedフレームワークのコストか最適化における設計原則
設計原則 | |
---|---|
クラウド財務管理を実践する | --- |
消費モデルを導入する | --- |
全体的な効率を測定する | --- |
差別化に繋がらない高負荷の作業に費用をかけるのをやめる | --- |
費用を分析し帰属関係を明らかにする | --- |
Fargateにおけるコストの基本的な考え方
他の従量課金のものと同様にECSタスクもコンピューティングリソースとタスク数に応じた従量課金なので、アプリケーションを稼働させるのに必要十分なリソース量を定めることが基本的な考え方になる。
適切なコスト実現のためのポイント
Compute Savings Plansの活用
Compute Savings Planとは1年または3年の期間で指定したリソースの使用を事前にコミットすることで割引料金が適用される仕組み。
サービス提供である程度の稼働が見込まれる場合にはこの仕組みを活用することで料金削減が見込める。
ECRコンテナイメージのメンテナンス
ECRの料金は保存されるコンテナイメージのサイズに比例してかかるので、適切な管理を行うことで料金を抑えることができる。
開発・ステージング環境のECSタスク稼働時間帯の調整
開発、ステージング環境など、本番と同様の環境を維持し続ける必要がない環境では以下の対応によりコスト最適化をすることができる。
- 開発環境について、夜間など、利用していない時間帯でタスクを停止させることで料金を削減できる
- 開発環境について、ECSタスクに割り当てるリソースを最小限にすることでコストを削減できる
Fargate Spotの活用
コンテナイメージサイズの削減
- ネットワークサイズ
- コンテナイメージの取得
- X-Ray等のサイドカー構成
スケールインやスケールアウトが頻繁に発生する環境だと特に料金がかかる