今後定期実行するスキャンジョブをスケジュールする
(トップページはこちら) - (アプリケーションのセキュリティを始める)
コンテナ化されたアプリケーションのセキュリティは、開発ライフサイクル全体を通じて継続的に管理する必要があります。本記事では、GitLabのコンテナセキュリティ機能を段階的に導入し、開発から運用まで一貫したセキュリティ体制を構築する実践的な方法を解説します。
1. まず知っておくべきこと:3つのスキャン方式の使い分け
GitLabは、コンテナセキュリティを3つの異なるタイミングでスキャンします。それぞれの特徴を理解し、適切に組み合わせることが重要です。
1.1 機能比較表
| 機能 | パイプラインスキャン | スキャン実行ポリシー | Operational Container Scanning |
|---|---|---|---|
| 実行タイミング | CI/CDパイプライン実行時 | ポリシーで定義したタイミング | Kubernetesクラスタ内で定期実行 |
| スキャン対象 | ビルドしたイメージ | ビルドしたイメージ | 稼働中のコンテナイメージ |
| 主な用途 | 開発段階での早期検出 | 組織全体への強制適用 | 本番環境の継続監視 |
| 設定場所 | .gitlab-ci.yml |
セキュリティポリシープロジェクト | GitLab Agent設定 |
| 必要な権限 | Developer以上 | Maintainer以上 | Maintainer以上 |
| Tier | Free以上 | Ultimate | Ultimate |
| 想定スキャン時間 | 2-5分 | 2-5分 | 5-15分(クラスタ規模による) |
1.2 使い分けの基準
2. 段階的導入ガイド:3ステップで始める
ステップ1:単一プロジェクトでパイプラインスキャンを試す(所要時間:15分)
まずは1つのプロジェクトで基本的なコンテナスキャンを体験しましょう。
2.1.1 最小構成での開始
.gitlab-ci.ymlに以下を追加します。
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
これだけで、パイプライン実行時に自動的にコンテナスキャンが実行されます。
2.1.2 スキャン結果の確認
パイプライン実行後、以下の場所で結果を確認できます。
- パイプライン > Security タブ: 検出された脆弱性の一覧
- マージリクエスト: 新規に検出された脆弱性のみ表示
- Secure > Vulnerability Report: プロジェクト全体の脆弱性状況
2.1.3 よくある初回の問題と対策
問題1: スキャンジョブが失敗する
ERROR: Job failed: exit code 1
原因: testステージが存在しない
解決策:
stages:
- build
- test # このステージを追加
- deploy
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
問題2: 大量の脆弱性が検出されて圧倒される
解決策: まずは重大度の高いものだけに絞る
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
container_scanning:
variables:
CS_SEVERITY_THRESHOLD: "HIGH" # HIGHとCRITICALのみ報告
問題3: ベースイメージが古くて脆弱性だらけ
解決策: EOL検出を有効化して、まずOSの更新から始める
container_scanning:
variables:
CS_REPORT_OS_EOL: "true"
CS_REPORT_OS_EOL_SEVERITY: "High"
ステップ2:スキャン実行ポリシーで組織全体に展開(所要時間:30分)
単一プロジェクトで成功したら、組織全体に展開します。
2.2.1 セキュリティポリシープロジェクトの作成
- グループレベルで新規プロジェクトを作成(例:
security-policies) - Secure > Policiesに移動
- New policyをクリック
2.2.2 段階的なポリシー展開戦略
フェーズ1: パイロット運用(1-2週間)
まずは少数のプロジェクトで試します。
scan_execution_policy:
- name: "パイロット:コンテナスキャン"
description: "選定したプロジェクトでのみ実行"
enabled: true
rules:
- type: pipeline
branch_type: default
actions:
- scan: container_scanning
variables:
CS_SEVERITY_THRESHOLD: "HIGH"
policy_scope:
projects:
- id: 123 # パイロットプロジェクトのID
- id: 456
フェーズ2: グループ全体への展開(1ヶ月)
パイロットで問題がなければ、グループ全体に展開します。
scan_execution_policy:
- name: "全プロジェクト:コンテナスキャン"
description: "デフォルトブランチへのプッシュ時に実行"
enabled: true
rules:
- type: pipeline
branch_type: default
actions:
- scan: container_scanning
variables:
CS_SEVERITY_THRESHOLD: "MEDIUM"
policy_scope:
compliance_frameworks:
- name: "本番環境" # コンプライアンスフレームワークで絞り込み
フェーズ3: マージリクエストでのスキャン追加
scan_execution_policy:
- name: "MRセキュリティスキャン"
description: "マージリクエスト作成時にスキャン"
enabled: true
rules:
- type: pipeline
branch_type: target_default
pipeline_sources:
- merge_request_event
actions:
- scan: container_scanning
variables:
AST_ENABLE_MR_PIPELINES: "true"
CS_SEVERITY_THRESHOLD: "MEDIUM"
2.2.3 スケジュールスキャンの設定
定期的なスキャンで、新規脆弱性を継続的に検出します。
scan_execution_policy:
- name: "週次セキュリティスキャン"
description: "毎週日曜日の深夜にスキャン"
enabled: true
rules:
- type: schedule
branches:
- main
cadence: "0 2 * * 0" # 毎週日曜日 02:00 (UTC)
timezone: "Asia/Tokyo"
time_window:
value: 3600 # 1時間以内にランダムに実行
distribution: random
actions:
- scan: container_scanning
- scan: secret_detection
スケジュールスキャンの注意点:
- リソース負荷: 多数のプロジェクトで同時実行されるため、ランナーのキャパシティを確認
- 時間帯: 業務時間外に設定し、開発への影響を最小化
- time_window: ランダム分散により、ランナーへの負荷を平準化
ステップ3:本番環境でOCSを導入(所要時間:1時間)
最後に、本番環境で稼働中のコンテナを継続的に監視します。
2.3.1 前提条件の確認
- GitLab Agent for Kubernetesがインストール済み
- エージェントのバージョンが16.9以降(Trivy K8s Wrapper対応)
- クラスタへのMaintainer権限
2.3.2 エージェント設定ファイルの編集
プロジェクトの.gitlab/agents/<agent-name>/config.yamlを編集します。
最小構成:
container_scanning:
cadence: '0 0 * * *' # 毎日深夜0時(UTC)
vulnerability_report:
namespaces:
- production
推奨構成(本番環境):
container_scanning:
cadence: '0 */6 * * *' # 6時間ごと
vulnerability_report:
namespaces:
- production
resource_types:
- Deployment
- StatefulSet
- DaemonSet
severity_threshold: "HIGH"
resource_requirements:
requests:
cpu: '0.2'
memory: 200Mi
ephemeral_storage: 2Gi
limits:
cpu: '0.7'
memory: 700Mi
ephemeral_storage: 4Gi
scanner_timeout: "600s"
report_max_size: "100000000" # 100 MB
2.3.3 スキャン実行ポリシーでの設定(推奨)
エージェント設定よりもポリシーでの管理を推奨します。理由は以下の通りです。
- 一元管理: 複数クラスタの設定を1箇所で管理
- 変更の追跡: ポリシー変更がマージリクエストで記録される
- 権限管理: ポリシープロジェクトへのアクセス制御で管理
- name: "本番クラスタの継続監視"
enabled: true
rules:
- type: schedule
cadence: '0 */6 * * *'
agents:
production-cluster-agent:
namespaces:
- 'production'
- 'production-critical'
actions:
- scan: container_scanning
2.3.4 マルチクラスタ環境での設定
重要: 各クラスタに対して個別のプロジェクトを作成してください。
推奨構成:
なぜ個別プロジェクトが必要か:
OCSは、前回のスキャンと今回のスキャンを比較して、消えた脆弱性を自動的に解決済みにします。複数クラスタを同一プロジェクトで管理すると、以下の問題が発生します。
各環境の設定例:
# 本番クラスタ(高頻度・高重大度のみ)
- name: "本番クラスタ監視"
enabled: true
rules:
- type: schedule
cadence: '0 */6 * * *' # 6時間ごと
agents:
production-agent:
namespaces:
- 'production'
actions:
- scan: container_scanning
# ステージングクラスタ(中頻度・中重大度)
- name: "ステージングクラスタ監視"
enabled: true
rules:
- type: schedule
cadence: '0 0 * * *' # 毎日1回
agents:
staging-agent:
namespaces:
- 'staging'
actions:
- scan: container_scanning
# 開発クラスタ(低頻度・全重大度)
- name: "開発クラスタ監視"
enabled: true
rules:
- type: schedule
cadence: '0 0 * * 1' # 毎週月曜日
agents:
development-agent:
namespaces:
- 'development'
actions:
- scan: container_scanning
3. 実践的な設定パターン
3.1 環境別の推奨設定
3.1.1 開発環境
目的: 開発者への教育と早期発見
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
container_scanning:
variables:
# すべての脆弱性を報告(学習目的)
CS_SEVERITY_THRESHOLD: "UNKNOWN"
# 言語固有のパッケージもスキャン
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "false"
# EOL OS検出
CS_REPORT_OS_EOL: "true"
# 詳細ログ出力
SECURE_LOG_LEVEL: "debug"
allow_failure: true # 開発段階では失敗を許容
3.1.2 ステージング環境
目的: 本番環境への移行前の最終チェック
scan_execution_policy:
- name: "ステージング環境スキャン"
enabled: true
rules:
- type: pipeline
branches:
- staging
- release/*
actions:
- scan: container_scanning
variables:
CS_SEVERITY_THRESHOLD: "MEDIUM"
CS_REPORT_OS_EOL: "true"
- scan: secret_detection
3.1.3 本番環境
目的: 重大な脆弱性のみを厳格に管理
scan_execution_policy:
- name: "本番環境スキャン"
enabled: true
rules:
- type: pipeline
branch_type: default
actions:
- scan: container_scanning
variables:
CS_SEVERITY_THRESHOLD: "HIGH"
CS_IGNORE_UNFIXED: "false" # 修正不可能な脆弱性も報告
CS_REPORT_OS_EOL: "true"
CS_REPORT_OS_EOL_SEVERITY: "Critical"
skip_ci:
allowed: false # skip-ciを完全に禁止
3.2 特殊なケースへの対応
3.2.1 プライベートレジストリのスキャン
基本的な認証:
container_scanning:
variables:
CS_IMAGE: "private-registry.example.com/myapp:latest"
CS_REGISTRY_USER: $PRIVATE_REGISTRY_USER
CS_REGISTRY_PASSWORD: $PRIVATE_REGISTRY_PASSWORD
AWS ECRの場合:
container_scanning:
before_script:
- apk add --no-cache aws-cli
- export AWS_ECR_PASSWORD=$(aws ecr get-login-password --region ap-northeast-1)
variables:
CS_IMAGE: "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest"
CS_REGISTRY_USER: AWS
CS_REGISTRY_PASSWORD: "$AWS_ECR_PASSWORD"
AWS_DEFAULT_REGION: ap-northeast-1
Google Container Registryの場合:
container_scanning:
variables:
CS_IMAGE: "gcr.io/my-project/myapp:latest"
CS_REGISTRY_USER: _json_key
CS_REGISTRY_PASSWORD: "$GCP_SERVICE_ACCOUNT_KEY"
3.2.2 マルチアーキテクチャイメージのスキャン
container_scanning:
# ARM64ランナーを使用
tags: ["saas-linux-small-arm64"]
variables:
TRIVY_PLATFORM: "linux/arm64"
CS_IMAGE: "myregistry.com/myapp:latest"
3.2.3 tarアーカイブのスキャン
CI/CDジョブでビルドしたイメージをレジストリにプッシュせずにスキャンする場合:
build_image:
stage: build
script:
- docker build . -t myapp:latest
- docker save myapp:latest -o myapp.tar
artifacts:
paths:
- myapp.tar
container_scanning:
variables:
CS_IMAGE: "archive://myapp.tar"
GIT_STRATEGY: fetch # アーティファクトにアクセスするため
dependencies:
- build_image
3.3 オフライン環境での運用
3.3.1 スキャナーイメージのミラーリング自動化
stages:
- mirror
- scan
# 定期的にスキャナーイメージを更新
mirror_scanner:
stage: mirror
image: docker:cli
services:
- docker:dind
script:
- docker pull registry.gitlab.com/security-products/container-scanning:8
- docker tag registry.gitlab.com/security-products/container-scanning:8
internal-registry.example.com/security/container-scanning:8
- echo "$INTERNAL_REGISTRY_PASSWORD" | docker login internal-registry.example.com
-u $INTERNAL_REGISTRY_USER --password-stdin
- docker push internal-registry.example.com/security/container-scanning:8
only:
- schedules # スケジュールパイプラインでのみ実行
# Trivy Java DBのミラーリング
mirror_trivy_java_db:
stage: mirror
image:
name: ghcr.io/oras-project/oras:v1.1.0
entrypoint: [""]
script:
- oras login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- oras pull ghcr.io/aquasecurity/trivy-java-db:1
- oras push internal-registry.example.com/trivy-java-db:1
--config /dev/null:application/vnd.aquasec.trivy.config.v1+json
javadb.tar.gz:application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip
only:
- schedules
# 実際のスキャン
container_scanning:
stage: scan
image: internal-registry.example.com/security/container-scanning:8
variables:
CS_TRIVY_JAVA_DB: internal-registry.example.com/trivy-java-db
CS_DOCKER_INSECURE: "true"
ADDITIONAL_CA_CERT_BUNDLE: |
-----BEGIN CERTIFICATE-----
MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
...
-----END CERTIFICATE-----
3.3.2 Container Scanning for Registryのオフライン設定
OCSはエージェント設定ファイルで制御できないため、UI経由でCI/CD変数を設定します。
- プロジェクトのSettings > CI/CD > Variablesに移動
- 以下の変数を追加:
| Key | Value | Protected | Masked |
|---|---|---|---|
CS_ANALYZER_IMAGE |
internal-registry.example.com/security/container-scanning:8 |
✓ | - |
CS_TRIVY_JAVA_DB |
internal-registry.example.com/trivy-java-db |
✓ | - |
4. 脆弱性管理のベストプラクティス
4.1 重大度に基づくワークフロー
4.2 脆弱性の許可リスト管理
プロジェクトルートにvulnerability-allowlist.ymlを配置します。
# グローバル許可リスト(全イメージに適用)
generalallowlist:
CVE-2019-8696: # 理由: 本番環境では影響なし(開発ツールのみ)
CVE-2014-8166: cups # 理由: プリンタ機能を使用していない
CVE-2017-18248: # 理由: 修正版が存在せず、回避策を実装済み
# イメージ固有の許可リスト
images:
# 本番イメージ
registry.gitlab.com/myorg/production-app@sha256:
CVE-2018-4180: # 理由: ベンダー確認済みの誤検知
# レガシーイメージ(段階的に廃止予定)
internal-registry.example.com/legacy-app:
CVE-2015-1419: libxml2 # 理由: 2025年Q2に新イメージへ移行予定
CVE-2015-1447: # 理由: 同上
許可リスト管理のルール:
- 必ずコメントで理由を記載: なぜ許可するのかを明記
- 定期的にレビュー: 四半期ごとに見直し
- 期限を設定: 一時的な許可には期限を明記
- 承認プロセス: 許可リスト追加はコードレビュー必須
4.3 自動修復の活用
GitLab Ultimateでは、一部の脆弱性に対して自動修復案を提供します。
有効化の設定:
include:
- template: Jobs/Container-Scanning.gitlab-ci.yml
container_scanning:
variables:
GIT_STRATEGY: fetch # Dockerfileへのアクセスに必要
CS_DOCKERFILE_PATH: "Dockerfile" # Dockerfileのパス
自動修復が提案される例:
- ベースイメージのバージョンアップ
- パッケージマネージャーでの依存関係更新
- 設定ファイルの修正
修復案の適用手順:
- Vulnerability Reportで脆弱性を選択
- Create merge requestボタンをクリック
- 自動生成されたMRをレビュー
- テストが通過したらマージ
4.4 継続的な脆弱性スキャン(Container Scanning for Registry)
有効化手順:
- プロジェクトのSecure > Security configurationに移動
- Container Scanning For Registryセクションでトグルをオン
動作の仕組み:
制限事項:
- 1日あたり50スキャン/プロジェクト
- 空のプロジェクトでは動作しない(最低1コミット必要)
- 新規脆弱性のみ報告(既存の脆弱性は初回スキャン時のみ)
5. トラブルシューティングと最適化
5.1 パフォーマンス問題
5.1.1 スキャン時間が長い
症状: スキャンに10分以上かかる
原因と対策:
| 原因 | 対策 | 期待効果 |
|---|---|---|
| イメージサイズが大きい | マルチステージビルドで最終イメージを軽量化 | 50-70%削減 |
| 言語固有スキャンが有効 | CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "true" |
30-40%削減 |
| ランナーのリソース不足 | 専用ランナーを用意 | 40-60%削減 |
最適化例:
# 軽量化されたDockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/main.js"]
# スキャン設定の最適化
container_scanning:
variables:
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "true" # OSパッケージのみ
CS_SEVERITY_THRESHOLD: "MEDIUM" # 低重大度を除外
TRIVY_TIMEOUT: "10m0s" # タイムアウトを延長
5.1.2 OCSでOOMKilledエラー
症状: Error running Trivy scan. Container terminated reason: OOMKilled
原因: スキャン対象が多すぎる、またはイメージが大きすぎる
段階的な対策:
レベル1: メモリ制限を緩和
container_scanning:
resource_requirements:
requests:
memory: 500Mi
ephemeral_storage: 2Gi
limits:
memory: 2Gi
ephemeral_storage: 5Gi
レベル2: スキャン対象を絞る
container_scanning:
vulnerability_report:
namespaces:
- production # 重要なNamespaceのみ
resource_types:
- Deployment # Podは除外(Deploymentに含まれるため)
- StatefulSet
レベル3: スキャンを分割
# 本番クラスタ - 重要Namespace
- name: "本番クラスタ - 重要"
enabled: true
rules:
- type: schedule
cadence: '0 */6 * * *'
agents:
production-agent:
namespaces:
- 'production-critical'
actions:
- scan: container_scanning
# 本番クラスタ - その他Namespace
- name: "本番クラスタ - その他"
enabled: true
rules:
- type: schedule
cadence: '0 0 * * *' # 頻度を下げる
agents:
production-agent:
namespaces:
- 'production-standard'
actions:
- scan: container_scanning
5.1.3 スキャンタイムアウト
症状: Error running Trivy scan due to context timeout
対策:
container_scanning:
scanner_timeout: "1800s" # 30分(デフォルト: 5分)
report_max_size: "300000000" # 300 MB(デフォルト: 100 MB)
5.2 よくある設定ミス
5.2.1 パイプラインが作成されない
症状: スキャン実行ポリシーを設定したが、パイプラインが実行されない
原因: workflow:rulesでパイプラインがフィルタされている
問題のある設定:
# .gitlab-ci.yml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never # すべてのpushパイプラインをブロック
修正:
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "security_orchestration_policy"
# ポリシーによるパイプラインは許可
- if: $CI_PIPELINE_SOURCE == "push"
when: never
5.2.2 マージリクエストでスキャンが実行されない
症状: MRパイプラインでコンテナスキャンがスキップされる
原因: AST_ENABLE_MR_PIPELINESが設定されていない
修正:
container_scanning:
variables:
AST_ENABLE_MR_PIPELINES: "true"
5.2.3 プライベートレジストリで認証エラー
症状: unexpected status code 401 Unauthorized
AWS ECRの場合の追加設定:
container_scanning:
before_script:
- apk add --no-cache aws-cli
- export AWS_ECR_PASSWORD=$(aws ecr get-login-password --region ap-northeast-1)
variables:
CS_IMAGE: "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest"
CS_REGISTRY_USER: AWS
CS_REGISTRY_PASSWORD: "$AWS_ECR_PASSWORD"
AWS_DEFAULT_REGION: ap-northeast-1 # これが抜けていることが多い
5.3 脆弱性データベース関連
5.3.1 古いデータベースエラー
症状: the vulnerability database was built 6 days ago (max allowed age is 5 days)
原因: ミラーリングしたイメージが更新されていない
対策: 定期的な自動更新を設定
# スケジュールパイプラインで毎日実行
update_scanner:
stage: mirror
image: docker:cli
services:
- docker:dind
script:
- docker pull registry.gitlab.com/security-products/container-scanning:8
- docker tag registry.gitlab.com/security-products/container-scanning:8
internal-registry.example.com/security/container-scanning:8
- docker push internal-registry.example.com/security/container-scanning:8
only:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
5.3.2 Trivy Java DBが見つからない
症状: Javaアプリケーションの脆弱性が検出されない
対策: Trivy Java DBのミラーリングを確認
container_scanning:
variables:
CS_TRIVY_JAVA_DB: "internal-registry.example.com/trivy-java-db"
# タグ `:1` は自動的に追加されるため不要
6. 実際の導入事例とROI
6.1 段階的導入のタイムライン
小規模組織(10-50プロジェクト)の例:
| フェーズ | 期間 | 活動 | 成果 |
|---|---|---|---|
| 準備 | 1週間 | - パイロットプロジェクト選定 - 基本設定のテスト |
- 設定テンプレート作成 - 初期の脆弱性ベースライン |
| パイロット | 2週間 | - 3-5プロジェクトで試験運用 - 開発者へのトレーニング |
- 検出された脆弱性の80%を修正 - 運用手順の確立 |
| 展開 | 1ヶ月 | - 全プロジェクトへポリシー適用 - 週次レビュー会議 |
- 組織全体でスキャン実施 - 平均スキャン時間: 3分 |
| 最適化 | 継続 | - OCS導入 - 許可リスト整備 |
- 本番環境の継続監視 - 誤検知率: 5%以下 |
大規模組織(100+プロジェクト)の例:
| フェーズ | 期間 | 活動 | 成果 |
|---|---|---|---|
| 準備 | 2週間 | - 専用ランナーの準備 - セキュリティポリシープロジェクト作成 |
- インフラ整備完了 - ガイドライン策定 |
| パイロット | 1ヶ月 | - 部門ごとに段階的展開 - チャンピオン育成 |
- 部門別の成功事例 - FAQ作成 |
| 展開 | 3ヶ月 | - グループ単位でポリシー適用 - 月次レポート |
- 全プロジェクトカバー率: 95% - 重大脆弱性の平均修正時間: 3日 |
| 最適化 | 継続 | - マルチクラスタOCS - 自動修復の活用 |
- 本番環境の24時間監視 - セキュリティインシデント: 0件 |
6.2 期待される効果
定量的効果:
- 脆弱性検出率: 従来の手動レビューと比較して300-500%向上
- 修正時間: 平均2週間 → 3日(85%削減)
- セキュリティインシデント: 年間5-10件 → 0-1件
- コンプライアンス監査: 準備時間を70%削減
定性的効果:
- 開発者のセキュリティ意識向上
- 組織全体での統一されたセキュリティ基準
- 監査対応の効率化
- 顧客への信頼性向上
6.3 コスト試算
初期コスト(小規模組織):
- GitLab Ultimate: 約$99/ユーザー/月 × 10ユーザー = $990/月
- 専用ランナー: 不要(共有ランナーで十分)
- トレーニング: 社内で実施(工数: 40時間)
- 合計: 約$1,000/月 + 初期工数
運用コスト:
- ランナー実行時間: 約100分/日 × $0.008/分 = $24/月
- ストレージ: 約10GB × $0.10/GB = $1/月
- 運用工数: 週2時間(脆弱性レビュー)
- 合計: 約$25/月 + 運用工数
ROI計算:
セキュリティインシデント1件あたりの平均コスト: $50,000
年間削減インシデント数: 5件
年間削減額: $250,000
投資額: $12,000/年(ライセンス) + $300/年(ランナー) = $12,300
ROI: 約1,933%
7. まとめと次のステップ
7.1 重要なポイント
- 段階的に導入する: いきなり全機能を有効化せず、パイプラインスキャン → ポリシー → OCSの順で導入
- 環境ごとに設定を変える: 開発・ステージング・本番で重大度閾値やスキャン頻度を調整
- マルチクラスタは個別プロジェクトで管理: OCSの脆弱性解決ロジックを正しく機能させるため
- 許可リストは慎重に管理: 必ず理由を記載し、定期的にレビュー
- オフライン環境でも実現可能: スキャナーイメージとデータベースのミラーリングで対応
7.2 次のステップ
今すぐ始められること:
-
1つのプロジェクトで試す(所要時間: 15分)
include: - template: Jobs/Container-Scanning.gitlab-ci.yml -
スキャン結果を確認する
- パイプライン > Securityタブ
- 検出された脆弱性の重大度を確認
-
重大度の高い脆弱性から修正する
- CRITICAL/HIGHを優先
- 自動修復案があれば活用
1週間後:
-
スキャン実行ポリシーを作成する
- セキュリティポリシープロジェクトを作成
- パイロットプロジェクトでテスト
-
開発チームにトレーニングを実施する
- 脆弱性の見方
- 修正方法
- 許可リストの使い方
1ヶ月後:
-
組織全体に展開する
- グループレベルでポリシーを適用
- 週次レビュー会議を開始
-
OCSを導入する
- 本番クラスタから開始
- 段階的に他の環境にも展開
コンテナセキュリティは、一度設定すれば終わりではありません。継続的な監視と改善が重要です。GitLabの包括的なセキュリティ機能を活用し、開発から運用まで一貫したセキュリティ体制を構築しましょう。