電通総研 テックブログ

電通総研が運営する技術ブログ

コンテナイメージ運用を振り返る

XI本部 クラウドイノベーションセンター所属、2年目の米田です。 今回は、AWSサービス上でのコンテナイメージの運用と、それをより効率的に実現するFutureVulsについて、基礎的な部分を中心に共有させていただきます。
本ブログは、10月下旬にあった社内向けの勉強会にて発表させていただいた内容を含んだものになっており、少し振り返りながら改めてまとめさせていただきました。
勉強会当日は100名以上の参加者となり、そのような場での発表は私自身とても良い経験でした。勉強会にご参加いただいた方、コメントいただいた方、取りまとめていただいた方、そしてフューチャー社の皆様、改めてありがとうございました。

はじめに

普段、皆さんはどのような方法でアプリケーションを開発・実行されていますでしょうか。
クラウド上でアプリケーションを起動する方法にはさまざまな選択肢があります。仮想マシン上で直接実行する方法、PaaS を利用する方法、サーバレスアーキテクチャなど、用途や規模に応じて複数のアプローチが存在します。

その中でも、近年特に多く利用されているのが コンテナサービス です。
コンテナは、アプリケーションとその実行に必要なライブラリや設定をまとめて扱えるため、開発環境と本番環境の差異が生まれにくく、デプロイやスケーリングを容易に行えるという特徴があります。また、移行性の高さも大きなメリットかと思います。別環境への移行や、新しい環境の構築時などで効率的に作業を進めることができ、個人的にはこのあたりは非常に有用だと感じています。

AWSではコンテナを扱うのに特化したさまざまなサービスが用意されており、それぞれの特性を理解して適切に使い分けることが重要です。ここではその代表的なものを取り上げます。

コンテナ制御

AWS でコンテナオーケストレーションを検討する際、代表的な選択肢として Amazon EKS と Amazon ECS の 2 つのサービスが挙げられます。
Amazon EKS は、Kubernetes をマネージドサービスとして提供するもので、Kubernetes のエコシステムや標準的な運用手法をそのまま利用できる点が特徴です。一方、Amazon ECS は AWS 独自のコンテナオーケストレーションサービスであり、Kubernetes を直接意識することなく、AWS に最適化された形でコンテナを管理・実行することができます。そのため、ECS は比較的シンプルな構成でコンテナを扱えるという利点があります。

また、これらのコンテナサービスでは、コンテナをどこで起動するか という点も重要な要素になります。AWS では主に、Amazon EC2AWS Fargate といった起動方式が利用されます。
Amazon EC2 を利用する場合は、仮想マシン上でコンテナを実行するためインスタンスのスペックや台数を自分で管理する必要がありますが、その分柔軟な構成が可能です。一方、AWS Fargate はサーバレスな起動方式であり、インスタンス管理を意識することなく、必要なリソースを指定するだけでコンテナを実行できます。
以下で、EC2 と AWS Fargate について簡単に整理してみました。

項目 Amazon EC2 AWS Fargate
起動方式 仮想マシン上でコンテナを実行 サーバレスでコンテナを実行
インスタンス管理 必要 不要
OS管理 必要 不要
スケーリング 自前設定 自動
課金方式 インスタンス単位 vCPU / メモリ使用量
自由度 高い ある程度制約あり

また、ご存じの方も多いかもしれませんが、AWS Lambda でもコンテナイメージを利用してアプリケーションを実行することができます。(コンテナLambdaと呼ぶこととします)
AWS Lambda は FaaS(Function as a Service)に分類されるサービスで、従来は ZIP ファイル形式でアプリケーションコードをデプロイする方法が一般的でした。この方式は手軽である一方、デプロイ可能なファイルサイズに制限(最大250MB)があり、ライブラリや依存関係が多いアプリケーションでは制約になることがあります。
一方で、Lambda では コンテナイメージを用いたデプロイ にも対応しており、この場合は10 GB までのサイズのイメージをデプロイすることができます。さらにLambda web adapterの登場により、従来は ECS や EC2 上で動かすことが一般的だった Web アプリケーションを、ほぼそのままの構成で Lambda 上に載せることが可能になりました。さらにコンテナサービスの幅が広がりました。

コンテナイメージ管理

上記のように、AWS にはコンテナを制御・起動するためのさまざまなサービスが存在しますが、それらを支える重要なコンポーネントとして Amazon Elastic Container Registry(ECR) が用意されています。
Amazon ECR は、主にDocker コンテナイメージを管理するためのマネージドレジストリサービスであり、Amazon ECS、Amazon EKS、AWS Lambda(コンテナイメージ) など、AWS の主要なコンテナ関連サービスと高い互換性を持っています。これにより、同じコンテナイメージを複数のサービス間で再利用しながら、安全かつ一元的に管理することが可能です。
そんなAmazon ECR には、いろいろ面白い機能がありそうですので、また別の記事で詳しく紹介させていただきます。今回は一部分のみ抜粋して紹介します。

リポジトリの種別

Amazon Elastic Container Registry(ECR)には、プライベートリポジトリ と パブリックリポジトリ の 2 種類が用意されています。どちらもコンテナイメージを管理するためのサービスですが、用途や設計思想には明確な違いがあります。
以下自分の理解です。

  • プライベートリポジトリ
    AWS アカウント内でのみ利用できるコンテナイメージの保管場所で、社内向けアプリケーションや、外部に公開したくない独自のアプリケーションイメージを扱う場合には、プライベートリポジトリが適しています。

  • パブリックリポジトリ
    インターネット上に公開されたコンテナイメージを配布するための仕組み。AWS アカウントを持っていないユーザーでもイメージを取得できるため、OSS の配布やサンプルアプリケーションの公開などに向いています。

パブリックリポジトリであれば基本的に認証なしでイメージ取得が可能ですが、プライベートリポジトリでは認証が必要になります。実際に認証なしでプライベートリポジトリへpullを試みると、以下のように拒否されてしまいます。

$ docker pull <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/<対象リポジトリ>:tag
Error response from daemon: pull access denied for <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/<対象リポジトリ>, repository does not exist or may require 'docker login': denied: Your authorization token has expired. Reauthenticate and try again.

認証してトライしてみます。

# 認証
aws ecr get-login-password --region ap-northeast-1 \
| docker login \
--username AWS \
--password-stdin <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker pull <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/<対象リポジトリ>:tag
tag: Pulling from <対象リポジトリ>
11b72ab0c7e9: Pull complete 
940530de9b36: Pull complete 
711f628928ef: Pull complete 
75131756b8ac: Pull complete 
...

今度はうまく接続できてそうです。
CI/CDで認証ステージを組み込んであげれば、自動的にECRへログイン→ECRへのイメージプッシュが行えます。

自動継続的スキャン

コンテナは軽量で再利用しやすいという利点がある一方で、ベースイメージやライブラリをそのまま使い回すことが多く、知らないうちに脆弱性を含んだ状態で運用してしまうケースも少なくありません。そのため、コンテナイメージに含まれる脆弱性をどのように管理するかは、運用において避けて通れない課題となっています。

特に、複数のサービスで同じコンテナイメージを利用している場合、1 つの脆弱性が複数のシステムに影響を及ぼす可能性があります。こうしたリスクに対応するためには、単発のチェックに留まらず、継続的に脆弱性を把握し、適切に対応していく仕組みを整えることが重要です。

そこでAWS ではコンテナイメージの脆弱性を管理するための仕組みとして、プライベートレジストリを対象に基本スキャン拡張スキャン の 2 種類の脆弱性スキャン方式が用意されています。
基本スキャンでは、イメージのプッシュ時またはオンデマンドでのスキャンが可能であり、OSに含まれるパッケージの既知の脆弱性を検出することができます。こちらは基本的に無料で使用することができ、スキャン結果についてはECRのコンソール上から確認することができます。
スキャンには共通脆弱性識別子 (CVE) データベースを使用する2種類の設定があったようですが、Clairと呼ばれるオープンソース脆弱性データベースを用いたスキャンは廃止され、現在はAWSネイティブスキャンという方式がGAとなっている状態でした。利用するためにはオプトインが必要なようですね。

もう一つのスキャン方法は、拡張スキャンと呼ばれる方式です。こちらは有料になりますが、Amazon Inspector と統合され、より詳細な脆弱性検出が可能になります。また、スキャン対象もOSだけでなく、プログラミング言語のパッケージやライブラリにも対応するため、より網羅的に脆弱性管理が可能となります。オンデマンドではなく継続的なスキャンがサポートされる点も良いですね。
Inspector統合なこともあり、検出結果は以下画像のようにInspectorのダッシュボードから確認できます。大まかに脆弱性が検知されたかも確認できますし、画像にはありませんがスキャン結果詳細を確認することももちろん確認可能です。

拡張スキャンによる料金は、東京リージョンで以下のようになっているようです。

スキャンタイミング コスト
プッシュ時 対象イメージにつき $0.11
継続スキャン スキャンごとに $0.01

こうしてみると、そこまで高額なわけでもないので性能を考えると拡張スキャンを採用しておくのが良いのかなと思います。

脆弱性管理

Amazon Inspector のみを利用した脆弱性管理も有効な選択肢ですが、コンテナイメージの数が増えてきたり、複数チーム・複数サービスで同時に運用している場合、「検知したあと、どう管理・運用するか」 という点も重要になってくると思います。
こうした中、脆弱性管理ツールの「FutureVuls」を用いることでECR上のイメージの脆弱性管理をより効率化することができます。

詳細な設定方法については公式ドキュメントを参照いただければと思いますが、おおまかな流れは以下になります。

  • FutureVuls で AWS 連携の設定を実施
  • FutureVulsで脆弱性管理対象とする ECR リポジトリを選択
  • 以降、AWS 側で実行されるスキャン結果を定期的に FutureVuls に取り込み、脆弱性・タスクとして管理

(公式) help.vuls.biz

手順としては非常に簡単で、個人的にはUIも直感的でわかりやすいなと思っています。
FutureVuls にはECRイメージの脆弱性管理を支えるいくつかの機能があり、深ぼっていきたいところですが、ここでは重要な機能と、大変便利な機能を一つずつピックアップし紹介します。

自動トリアージ

FutureVuls の大きな特徴の一つが、SSVC(Stakeholder-Specific Vulnerability Categorization) というフレームワークに基づいた脆弱性管理を実現できる点です。FutureVuls ではこのフレームワークを用いてリスクを評価し、優先順位付けを行う、自動トリアージ機能を搭載しており、「out of cycle(重大な検出)」や「Immediate(緊急性の高い検出)」などと自動分類することで、セキュリティチームが比較的重要な脅威に迅速に対応できるようになります。
さらに脆弱性対応のタスク管理もFutureVulsにて実施可能で、対応ステータス等の把握が容易になります。
SSVCについて詳しく知りたい方はFutureVuls様のこちらの記事をご参照ください: www.vuls.biz

FutureVuls AI

FutureVuls には、脆弱性管理をさらに効率化するための機能としてFutureVuls AI が提供されています。

FutureVuls AI を簡単に紹介すると、検出された脆弱性に対して分かりやすいサマリを提示し、対応判断を支援してくれる AI アシスタントです。単に脆弱性を検知するだけでなく、「この脆弱性は何が問題で、どこに影響があるのか」を把握するまでの時間を大きく短縮してくれます。

脆弱性対応を行う際には、CVE 情報や各種アドバイザリを確認することが一般的ですが、これらの情報は 英語で記載されており、数ページに及ぶことも少なくありません。そのため、内容を正しく理解するまでに想像以上の時間がかかるケースもあります。
FutureVuls AI は、こうした 大量かつ専門的な情報を要約し、ポイントを整理して提示してくれるため、

  • 脆弱性の種類
  • 影響範囲の有無
  • 対応の必要性や優先度の判断材料

といった情報を、短時間で把握することが可能になります。

未然防止

AWS Inspector や FutureVuls を活用することで、脆弱性を効率的に検知・管理することは可能ですが、理想を言えば 「脆弱性が検知されない状態」を目指したい ところです。つまり、問題が発生してから対応するのではなく、そもそも脆弱性を含まないイメージを作るための仕組みづくりが重要になります。

その取り組みの一例として、ECR にコンテナイメージを push する前の段階で、依存関係のアップデートを自動で検知・提案してくれるツールを導入する方法があります。具体的には、GitHub 上で利用できる Renovate や Dependabot などの自動化ツールが代表的です。
これらのツールを導入すると、アプリケーションや Dockerfile で使用しているライブラリ、ベースイメージの新しいバージョンが公開された際に、変更内容を反映した Pull Request を自動で作成してくれます。開発者はその PR をレビューしてマージするだけでよく、手作業でバージョンチェックを行う必要がありません。

さらに、利用するコンテナイメージのベースとして Distroless イメージを採用することで、セキュリティリスクをより一層抑えることができます。Distroless イメージは、OS やシェルといった不要なコンポーネントを含まず、アプリケーションの実行に必要な最小限のライブラリのみで構成されたイメージです。そのため、攻撃対象となり得るパッケージの数を減らすことができ、結果として 脆弱性が検知される可能性そのものを低減できます。
このように、

  • 依存関係の自動アップデートによる「事前対策」
  • Distroless イメージの採用による「攻撃対象の最小化」

といった取り組みを組み合わせることで、コンテナイメージに含まれる脆弱性を大幅に削減し、より安全で持続可能なコンテナ運用を実現することが可能になります。

まとめ

今回は、コンテナイメージの管理方法として AWS が提供する Amazon Elastic Container Registry(ECR) を中心にご紹介しました。
ECS や EKS、Lambda など複数のコンテナ関連サービスと親和性が高く、イメージを一元的に管理できる点は、ECR の大きな強みと言えます。

また、実運用における脆弱性管理の観点では、FutureVuls を活用することで、検知から対応までをより効率的に実施できることをご紹介しました。
単にスキャン結果を確認するだけでなく、優先度に基づいた対応判断や、チケット管理・共有まで含めた運用を行うことで、継続的な脆弱性管理体制を構築しやすくなります。

勉強会の中でもコメントをいただきましたが、自動化できる部分は積極的に自動化し、可能な限り手動での設定や対応を減らしていくことは、今後ますます重要になっていくと感じています。今後は外部サービスとのさらなる連携も検討されているとのことで、より実践的な運用が実現できる点に期待が高まります。

参考

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/image-scanning.html
https://aws.amazon.com/jp/inspector/pricing/
https://help.vuls.biz/manual/scan/image/
https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/amazon-elastic-kubernetes-service.html
https://aws.amazon.com/jp/ecr/

私たちは一緒に働いてくれる仲間を募集しています!

電通総研 キャリア採用サイト 電通総研 新卒採用サイト

執筆:@yoneda.kosuke
レビュー:@taguchi.kazutoshi
Shodoで執筆されました