【テクニカル・上級編】Datadog Container Image Vulnerability ManagementによるKubernetesコンテナ脆弱性スキャンの実務運用 – 運用監視・オブザーバビリティ活用バイブル

コンテナ脆弱性スキャンを「儀式」から「自律防御システム」へ昇華させる:Datadog Container Image Vulnerability Managementの極限活用

世の多くのチームは、セキュリティスキャナーを導入した瞬間に「安全になった」という幻想に酔う。CI/CDパイプラインの片隅に重いスキャンタスクをねじ込み、ビルドの度に数千件の「Low / Medium」アラートを出力させ、開発者のメールボックスを埋め尽くす――。
これはセキュリティではない。ただのノイズ製造機であり、エンジニアの認知負荷を高めるだけの有害な儀式だ。

真のオブザーバビリティ・アーキテクトであれば、脆弱性管理を「開発の足かせ」ではなく、本番K8sクラスターのランタイム文脈(Runtime Context)と完全に同期した自律防御機構として構築しなければならない。

今回は、Datadog Cloud Security Platformの核心である Container Image Vulnerability Management を骨の髄まで掌握し、CI/CDから本番K8sクラスターに至るまで無駄なノイズを排除した極限の自動化とパフォーマンス最適化のノウハウを叩き込む。

—

1. 内部アーキテクチャの理解:なぜDatadogは軽量なのか

多くの脆弱性スキャナーは、イメージ全体を巨大なモノリスとして解析するため、エージェント自体のメモリ消費が激しく、K8sノードのリソースを圧迫する。

Datadogのアーキテクチャの優位性は、Datadog Cluster AgentおよびNode Agent(DaemonSet)とのインテグレーションによる「オフロード型・インベントリ相関スキャン」にある。

  • SBOM(Software Bill of Materials)の自動抽出: ランタイムで稼働するコンテナのレイヤーやパッケージ情報を、Cluster AgentがK8s APIサーバー経由で効率的に収集。
  • 脆弱性データベース(VDB)のクラウド側マッチング: 重いCVEデータベースとの照合処理はDatadogのバックエンド(SaaS側)で行われ、K8sクラスター側のCPU/メモリフットプリントを極限まで抑制。
  • ランタイム文脈の付与: 「その脆弱性を持つイメージが、実際にどのDeploymentで、どのnamespaceで、どのレプリカ数で稼働しているか」というコンテキストがリアルタイムで結合される。

このアーキテクチャにより、「CVEはあるが、トラフィックが到達しない非本番の停止中ポッド」のような無駄なアラートに夜中叩き起こされる悲劇を根絶できる。

—

2. CI/CDパイプライン統合:ビルドを止めずにリスクを遮断する

CI/CDフェーズでのスキャンは、「デプロイのブロッカー」として機能させると開発速度が死ぬ。目指すべきは、「ビルド時は非同期でSBOMをDatadogへ送り、重大度に応じたポリシー評価をゲートウェイで行う」非同期・宣言型のパイプラインだ。

以下に、GitHub Actionsを用いた、Datadog CLI (`datadog-ci`) による高速スキャンと、脆弱性評価の極限最適化設定を示す。

name: Container Image Security Gate

on:
push:
branches: [ “main” ]

jobs:
scan-and-upload:
runs-on: ubuntu-latest
steps:

  • name: Checkout code

uses: actions/checkout@v4

  • name: Set up Docker Buildx

uses: docker/setup-buildx-action@v3

  • name: Build and push image

uses: docker/build-push-action@v5
with:
push: true
tags: 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/my-service:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

  • name: Install Datadog CI CLI

run: |
npm install -g @datadog/datadog-ci

  • name: Scan Image and Evaluate Vulnerabilities

env:
DD_API_KEY: ${{ secrets.DD_API_KEY }}
DD_SITE: “datadoghq.com”
run: |
# イメージをプルせずに、ローカルのDocker Daemon経由または直接レジストリからスキャン
# fail-onを設定することで、Criticalな脆弱性が検知された場合のみパイプラインを破壊する
datadog-ci image scan \
–service=”my-service” \
–env=”production” \
–tags=”git.sha:${{ github.sha }},team:core-infra” \
–fail-on-critical=true \
–fail-on-high=false \
999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/my-service:${{ github.sha }}

アーキテクチャの急所

ここであえて `–fail-on-high=false` としている点に注目してほしい。High脆弱性は日々無限に発見される。これらをすべてCI/CDのブロック対象にすると、開発チームは脆弱性対応に追われて機能開発が止まる。
High以下の脆弱性は、後述する「K8sランタイム側のアラートと優先順位付け」に任せ、CI/CDでは「リモートコード実行(RCE)につながる致命的なCritical脆弱性のみ」を物理的に遮断する。これがスループットを落とさないための鉄則だ。

—

3. 本番K8sクラスター:ランタイム文脈による「真の優先順位付け」

本番環境にデプロイされた後、真の脆弱性管理が始まる。Datadogの真骨頂は、「K8sの稼働状況(Runtime)と脆弱性をマッピングした脆弱性管理ダッシュボード」にある。

トリアージの黄金律:Exposed(外部公開)か否か

すべてのCVEが同じ重みを持つわけではない。以下の条件が揃った脆弱性こそが、今すぐ対応すべき「真の脅威」である。

1. Severityが Critical または High
2. インターネットから直接アクセス可能なIngress/Gatewayの配下にあるポッドで稼働している
3. パッケージが実際にメモリ上にロードされ、実行パスに含まれている

Datadog Security Signalsを活用し、この条件に合致したものだけをPagerDuty等のオンコールにルーティングするカスタムシグナルルールを定義する。

—

4. 独自自動化:Datadog Security APIを用いた「自動トリアージ&Slack通知ボット」

標準のアラート機能だけでは物足りない現場のエンジニアへ向け、Datadog APIを叩き、未対応の脆弱性情報を独自のビジネスロジックでフィルタリングしてSlackへ高密度通知、あるいは自動チケット起票を行うPythonスクリプトを授けよう。

このスクリプトは、Datadog Vulnerabilities APIからデータを抽出し、「本番環境で稼働しており、かつ修正パッチが存在するCritical脆弱性」のみを抽出する。

import os
import requests
from typing import Dict, Any, List

環境変数からの設定読み込み
DD_API_KEY = os.getenv(“DD_API_KEY”)
DD_APP_KEY = os.getenv(“DD_APP_KEY”)
DD_SITE = os.getenv(“DD_SITE”, “datadoghq.com”)
SLACK_WEBHOOK_URL = os.getenv(“SLACK_WEBHOOK_URL”)

HEADERS = {
“Accept”: “application/json”,
“DD-API-KEY”: DD_API_KEY,
“DD-APPLICATION-KEY”: DD_APP_KEY,
}

def fetch_critical_vulnerabilities() -> List[Dict[str, Any]]:
“””
Datadog Vulnerability APIを叩き、本番環境におけるCriticalかつ修正可能な脆弱性を取得
“””
url = f”https://api.{DD_SITE}/api/v2/security_monitoring/vulnerabilities”

# フィルタークエリ:本番環境かつCritical、修正パッチあり
params = {
“filter[severity]”: “CRITICAL”,
“filter[env]”: “production”,
“filter[fixable]”: “true”
}

response = requests.get(url, headers=HEADERS, params=params)
if response.status_code != 200:
raise RuntimeError(f”Failed to fetch vulnerabilities: {response.status_code} – {response.text}”)

return response.json().get(“data”, [])

def format_and_notify_slack(vulns: List[Dict[str, Any]]) -> None:
“””
抽出した脆弱性情報をエンジニアが即座に行動できる形式にフォーマットしてSlackへ送信
“””
if not vulns:
print(“No critical vulnerabilities found in production matching criteria.”)
return

blocks = [
{
“type”: “section”,
“text”: {
“type”: “mrkdwn”,
“text”: f”🚨 [Urgent] 本番環境で対応必要なCritical脆弱性が検知されました ({len(vulns)}件)”
}
},
{“type”: “divider”}
]

for vuln in vulns[:5]: # 上位5件に絞る
attrs = vuln.get(“attributes”, {})
cve_id = attrs.get(“vulnerability”, {}).get(“name”, “Unknown CVE”)
pkg_name = attrs.get(“affected_package”, {}).get(“name”, “Unknown Package”)
image_name = attrs.get(“resource”, {}).get(“name”, “Unknown Image”)

blocks.append({
“type”: “section”,
“text”: {
“type”: “mrkdwn”,
“text”: f”CVE: `{cve_id}`\nPackage: `{pkg_name}`\nImage: `{image_name}`\nAction: 即時パッチ適用またはイメージ再ビルドが必要です。”
}
})

payload = {“blocks”: blocks}
res = requests.post(SLACK_WEBHOOK_URL, json=payload)
if res.status_code != 200:
print(f”Failed to send Slack notification: {res.text}”)

if __name__ == “__main__”:
try:
critical_vulns = fetch_critical_vulnerabilities()
format_and_notify_slack(critical_vulns)
except Exception as e:
print(f”Error executing vulnerability automation script: {e}”)
exit(1)

このスクリプトをKubernetesの `CronJob` として週1回、あるいはGitHub Actionsの定期実行(Scheduled Workflow)として組み込むことで、人間がDatadogのUIをポチポチと巡回する無駄な時間をゼロにし、機械的なトリアージ体制が完成する。

—

5. パフォーマンスとリソース最適化の極意(ノイズの完全排除)

最後に、大規模Kubernetesクラスター(数千ポッド規模)でDatadog Container Image Vulnerability Managementを運用する際、必ず直面するパフォーマンス課題と、その処方箋を記す。

ハック1: スキャン対象イメージのスコープ絞り込み

すべてのサードパーティ製サイドカーやベースイメージのベースOS部分まで個別にアラートを出されると、ログが溢れ返る。
Datadog Agentのコンフィグレーション(`datadog.yaml` または HelmチャートのValues)において、不要なNamespaceや一時的なジョブ用ポッドをスキャン対象外に明示的に除外せよ。

Helm values.yaml の抜粋例
datadog:
securityAgent:
compliance:
enabled: true
sbom:
containerImage:
enabled: true
# スキャン対象から除外するnamespaceの指定(例: 監視系や一時ジョブ領域)
excludeNamespaces:

  • kube-system
  • datadog
  • temp-jobs

ハック2: イメージプルの競合を防ぐキャッシュ戦略

CI/CDやクラスター内のノードでスキャンが頻発すると、コンテナレジストリ(AWS ECR, Google Artifact Registryなど)へのAPIリクエスト制限(Rate Limit)に抵触し、デプロイパイプライン全体がブロックされる。
Datadog Cluster Agentは賢明にもSBOMのキャッシュを保持するが、レジストリ側でも適切なイメージレイヤーキャッシュと、不要になった古いイメージのライフサイクルポリシー(Lifecycle Policy)を必ず併用すること。

—

結び:オブザーバビリティとは「文脈の支配」である

脆弱性管理の本質は、数あるCVEの数字を減らすことではない。
「いま、自社システムのどこにリスクが潜んでおり、それがビジネスの生死に直結するかどうか」を、正確なオブザーバビリティの文脈(Context)をもって瞬時に把握し、自動的に握りつぶすことだ。

Datadog Container Image Vulnerability Managementをここに記した設計思想でセットアップした瞬間から、あなたのK8sクラスターは、単にアプリを動かす器ではなく、自律的に脅威を識別し、無駄なノイズを発しない「要塞」へと変貌を遂げる。

さあ、ダッシュボードの赤いアラートの海を片付け、真に重要なシグナルだけに耳を澄ませよう。

タイトルとURLをコピーしました