上級 20分 Lesson 21

コンテナセキュリティ — コンテナだからって安全じゃない

ECSタスクロール、EKS IRSA、ECRスキャンを講義形式で解説

AWS ECS EKS SCS-C03 Security

みなさん、おはようございます。今日は、コンテナのセキュリティについて。

「コンテナ」と聞くと、「軽量」「隔離」「安全」というイメージを持つ人が多いでしょう。ですが、その認識は不正確です。実は、コンテナだからこそ発生する特有のセキュリティ課題があります。

イメージの脆弱性、ランタイムのアクセス制御、ネットワーク隔離。ECS や EKS での運用では、これらすべてに対応する必要があります。

コンテナとセキュリティ課題

では、具体的に何が問題か。

  1. イメージの安全性:Docker イメージの中に、脆弱性のあるライブラリが入ってないか?
  2. ランタイムのアクセス制御:実行中のコンテナが、何にアクセスできるのか?
  3. ネットワーク隔離:複数のコンテナが走ってるとき、互いに通信しちゃったら?

——こんなことがあるわけです。

では、これをどう守るか。

ECS での IAM ロール — 「実行ロール vs タスクロール」

AWS で最も一般的なコンテナサービス ECS(Elastic Container Service)では、コンテナを「タスク」と呼びます。Web アプリケーション、バックグラウンドジョブなど、各種ワークロードがタスクとして実行されます。

重要なのは、ECS タスクには 2 つの異なる IAM ロールがあるということです。これを理解していないと、権限設定で落とし穴にはまります。

実行ロール(Task Execution Role)は、ECS エージェント(コンテナオーケストレーターの一部)が使うロールです。役割は、ECR からコンテナイメージをプルする、CloudWatch Logs にログを送信する、Secrets Manager から秘密情報を取得する、といったタスク起動に必要な操作です。

タスクロール(Task Role)は、コンテナ内で実行されるアプリケーション自体が使うロールです。S3 にアクセスする、DynamoDB に書き込む、SQS からメッセージを読む、といったアプリケーション本体の仕事に必要な権限です。

この分離がポイントです。実行ロールはインフラレベルの操作のみを許可し、タスクロールはアプリケーションレベルのビジネスロジック操作のみを許可することで、最小権限の原則が実現されます。

実装例

では、具体的に。

あなたが Web アプリケーションをコンテナ化します。

その Web アプリ——S3 から画像ファイルを読むとします。

では、IAM 設定は——

実行ロールには、ECRからイメージをダウンロードするための権限(GetDownloadUrlForLayer、BatchGetImage)、CloudWatch Logsにログを出力するための権限(CreateLogGroup、CreateLogStream、PutLogEvents)、そしてSecrets Managerから秘密情報を取得する権限が必要です。一方、タスクロールには、S3から特定のバケットに限定してGetObjectする権限だけが必要です。

こうして——実行ロールはね、「ECS の基盤を支える権限」で。

タスクロールはね、「アプリケーション自体の仕事」を担うわけです。

EKS と IRSA — 「Pod 単位の IAM ロール」

では、次のレベルに進みます。

EKS(Elastic Kubernetes Service)です。

Kubernetes を AWS で動かすときに使うサービスですね。

EKS の場合——セキュリティはもっと複雑になります。

なぜなら——Kubernetes はね、複数の Pod(コンテナのグループ)が1つのノード(EC2 インスタンス)で走るから。

では、各 Pod が異なる AWS リソースにアクセスしたいとき——どうするのか?

従来のやり方なら——ノード全体に1つの IAM ロールをアタッチして、全部の Pod がそれを共有する。

でもね——それ、セキュリティ的には最悪なんですよ。

「Pod A は S3 にアクセスしたいけど、Pod B は DynamoDB にアクセスしたい」

——こういう場合に、ノード全体に「S3 + DynamoDB」両方の権限をアタッチすると——Pod A が間違って DynamoDB に触っちゃう可能性がある。

では、どうする?

IRSA(IAM Roles for Service Accounts)です。

これはね——Kubernetes の「Service Account」という仕組みと、AWS IAM ロールを結びつけるメカニズムです。

IRSA の仕組み

具体的には——

  1. Kubernetes のネームスペース内に「Service Account」を作成する
  2. その Service Account に、IAM ロールを紐付ける(IRSA によって)
  3. Pod を起動するときに「このサービスアカウントを使え」と指定する
  4. Pod が AWS リソースにアクセスするときに、そのロールが使われる

背後では——OpenID Connect(OIDC)という仕組みが働いてます。

でも、ユーザーとしては——「Service Account に IAM ロールを紐付ける」という簡単な操作をするだけです。

結果

では、何が実現されるか?

Pod A:Service Account A を使う → IAM ロール A(S3 のみ) Pod B:Service Account B を使う → IAM ロール B(DynamoDB のみ)

こうして——Pod 単位での最小権限が実現されるわけです。

IRSA = Pod 単位で IAM ロールを割り当てる。Kubernetes らしいセキュリティ。

Pod Identity(新しい選択肢)

あ、ちょっと補足があります。

AWS が最近、Pod Identity という——IRSA の進化版を出しました。

IRSA は OIDC を使ってるんですけど——Pod Identity はね——もっと直接的に Pod に IAM ロールを割り当てる仕組みです。

EKS 1.29 以降で推奨されるやり方になってます。

でも、試験的には——IRSA を理解してれば大丈夫です。

ECR スキャン — 「イメージの脆弱性検査」

では、次のテーマ。

コンテナイメージ自体の安全性です。

あなたが Docker イメージを——ECR(Elastic Container Registry)にプッシュするとします。

その中にね——脆弱性のあるライブラリが混じってたら——どうなるか?

そのイメージをベースに、本番環境でコンテナを起動する。

脆弱性があるから——攻撃者に侵入されちゃう。

では、これを防ぐには?

ECR Image Scanning です。

これはね——ECR にプッシュされたイメージに対して——自動的に脆弱性スキャンを実行するやつです。

スキャンのプロセス

まずDockerイメージをECRにプッシュします。するとECRが自動的にスキャンを開始して、既知の脆弱性データベース、つまりCVEと比較します。脆弱性が見つかったら報告されて、深刻度別に分類されます。クリティカル、ハイ、ミディアム、ロー、インフォメーショナルの5段階です。

——こういう流れです。

で、見つかった脆弱性は——ECR のコンソールに表示されます。

「このイメージに CRITICAL の脆弱性が 3 個、HIGH が 5 個ある」——こんな感じで。

スキャン結果を基に、デプロイを制御

では、脆弱性が見つかったら——デプロイすべきじゃないですよね。

ここで登場するのが——ECR Scan Results Filtering とか、デプロイメント時のポリシー制御です。

例えば——

「CRITICAL の脆弱性が 1 個以上あるイメージは、本番にデプロイさせない」

——こういうルールを設定できるわけです。

CI/CD パイプラインで——

まずDockerイメージをビルドして、ECRにプッシュします。ECRが自動でスキャンして、スキャン結果を確認します。脆弱性がなければEKSにデプロイ。脆弱性があればデプロイ中止。

——こういう流れができるわけです。

ECR Scan = イメージの脆弱性チェック。本番デプロイ前の最後の砦。

CVE とスキャン精度

ちょっと注意があります。

ECR のスキャンはね——既知の脆弱性(CVE)をチェックします。

つまり——CVE データベースに登録されていない、最新の脆弱性は——検出されないんです。

なので、ECR Scan はね——「完全な安全」を保証するものじゃなくて——「既知の危ない脆弱性は避ける」くらいのレベルです。

それでも——やらないより、やったほうが圧倒的にマシです。

Fargate vs EC2 — 「セキュリティの視点から」

ちょっと寄り道をします。

ECS でコンテナを走すとき——2つの選択肢がある。

Fargate:AWS が管理する、サーバーレスコンテナサービス EC2:自分で EC2 インスタンスを管理

セキュリティの観点から——何が違うか?

Fargate の利点

インスタンスを管理しない:

EC2 インスタンスのセキュリティアップデート、パッチ管理——全部を AWS がやってくれます。

つまり——「サーバーのセキュリティ」という概念が消えるわけです。

コンテナイメージだけに集中できる。

隔離性が高い:

Fargate では——基本的に、複数のユーザーのコンテナが同じインスタンスで走りません。

つまり——「隣の Pod が自分の Pod をハッキングする」ってリスクが低い。

EC2 の利点

コスト:

Fargate は割高です。EC2 を自分で管理したほうが——安いことが多い。

カスタマイズ:

EC2 なら——インスタンスタイプ、EBS ボリュームサイズ、ネットワーク設定——自由にカスタマイズできます。

では——セキュリティとコストのトレードオフをどう考えるか?

一般的なガイドライン:

本番環境:Fargate を使う(セキュリティ > コスト) 開発・ステージング:EC2 を使う(コスト < セキュリティ) 機密性が高いワークロード:Fargate 必須

ネットワークセキュリティ — 「Pod 間通信の制御」

では、最後のテーマ。

EKS でね——複数の Pod が走ってるとき——Pod 間の通信をどう制御するか?

例えば——

「Web Pod は通信を受け付ける。Database Pod も Web Pod と通信する。でも、Web Pod 同士は通信しない」

——こういう要件ですね。

ネットワークポリシー

Kubernetes には——Network Policy という仕組みがあります。

これはね——Pod 間のトラフィックを制御するファイアウォールみたいなものです。

例えば——

YAML形式のネットワークポリシーで、tierがdatabaseというラベルを持つPodへのアクセスは、tierがappというラベルを持つPodからのアクセスのみを許可し、プロトコルはTCP、ポートは5432に限定するという定義ができます。

そうするとね——自動的にね、ネットワークルールが適用される。

Database Pod には——App label を持つ Pod からの通信だけが来る。他からの通信は全部ブロック。

Network Policy = Kubernetes 内部のファイアウォール。Pod 間通信を制御。

実務的なセキュリティチェックリスト

では、まとめます。

ECS / EKS でコンテナセキュリティを実装するなら——

  1. 実行ロール / タスクロール を正しく分離:起動権限と実行権限を分ける
  2. IRSA を使用(EKS の場合):Pod 単位での最小権限
  3. ECR Scan を有効化:デプロイ前に脆弱性チェック
  4. 本番環境なら Fargate を検討:セキュリティ重視の場合
  5. Network Policy を定義(EKS の場合):Pod 間通信を最小化

これらが——全部統合されるとき——

コンテナは、仮想マシン以上のセキュリティを得るわけです。

隔離性、最小権限、監査可能性——これらが全部、Kubernetes の仕組みの中に組み込まれるから。

では、次のテーマに行きましょう。