コンテナ開発環境パフォーマンス最適化実践:高速化テクニックの完全ガイド

コンテナ開発環境パフォーマンス最適化実践:高速化テクニックの完全ガイド

コンテナ化開発環境の基本的な構築ができたら、次に重要なのはパフォーマンスの最適化です。「ビルドに時間がかかりすぎる」「コンテナの起動が遅い」「ファイル同期が重い」といった問題は、開発効率を大幅に低下させます。

この記事では、実際のプロジェクトで即座に適用できる具体的な最適化テクニックを、測定可能な改善効果とともに詳しく解説します。小さな改善から抜本的な高速化まで、段階的にパフォーマンスを向上させる方法を習得できます。

パフォーマンス最適化の全体戦略

最適化対象の優先順位

1. ビルド時間の短縮(最重要)

  • Docker イメージビルドの高速化
  • キャッシュ効率の最大化
  • マルチステージビルドの最適化

2. 起動時間の短縮

  • コンテナ起動プロセスの最適化
  • 初期化処理の効率化
  • 依存関係の最適化

3. 実行時パフォーマンス

  • ファイルI/O の最適化
  • メモリ使用量の最適化
  • ネットワーク通信の効率化

4. リソース使用効率

  • ディスク使用量の削減
  • CPU使用率の最適化
  • メモリリーク対策

パフォーマンス測定の基本

最適化の効果を定量的に評価するための測定手法です:

#!/bin/bash
# scripts/performance-benchmark.sh - パフォーマンス測定スクリプト

echo "🚀 Container Performance Benchmark"
echo "=================================="

# ビルド時間測定
echo "📊 Build Time Measurement"
BUILD_START=$(date +%s)
docker build --no-cache -t benchmark-image . > /dev/null 2>&1
BUILD_END=$(date +%s)
BUILD_TIME=$((BUILD_END - BUILD_START))
echo "Build time: ${BUILD_TIME}s"

# 起動時間測定
echo "📊 Startup Time Measurement"
STARTUP_START=$(date +%s)
CONTAINER_ID=$(docker run -d -p 8000:8000 benchmark-image)
# アプリケーションが応答するまで待機
while ! curl -s http://localhost:8000/health > /dev/null 2>&1; do
    sleep 1
done
STARTUP_END=$(date +%s)
STARTUP_TIME=$((STARTUP_END - STARTUP_START))
echo "Startup time: ${STARTUP_TIME}s"

# イメージサイズ測定
IMAGE_SIZE=$(docker images benchmark-image --format "{{.Size}}")
echo "Image size: ${IMAGE_SIZE}"

# メモリ使用量測定
MEMORY_USAGE=$(docker stats --no-stream --format "{{.MemUsage}}" $CONTAINER_ID)
echo "Memory usage: ${MEMORY_USAGE}"

# クリーンアップ
docker stop $CONTAINER_ID > /dev/null
docker rm $CONTAINER_ID > /dev/null

echo ""
echo "✅ Benchmark completed!"
echo "=================================="
echo "Build Time: ${BUILD_TIME}s"
echo "Startup Time: ${STARTUP_TIME}s" 
echo "Image Size: ${IMAGE_SIZE}"
echo "Memory Usage: ${MEMORY_USAGE}"

ビルド時間最適化の実践テクニック

1. レイヤーキャッシュの最適化

Docker ビルドの最も効果的な高速化手法です:

最適化前のDockerfile(問題例):

# 非効率なDockerfile - ビルド時間: 5-10分
FROM python:3.11-slim

WORKDIR /app

# 問題: 全てのファイルを先にコピー
COPY . .

# 問題: 依存関係インストールが毎回実行される
RUN pip install -r requirements.txt

CMD ["python", "app.py"]

最適化後のDockerfile(改善例):

# 最適化されたDockerfile - ビルド時間: 30秒-2分
FROM python:3.11-slim as base

WORKDIR /app

# 1. システム依存関係を先にインストール(変更頻度低)
RUN apt-get update && apt-get install -y 
    build-essential 
    curl 
    && rm -rf /var/lib/apt/lists/* 
    && apt-get clean

# 2. Python依存関係ファイルのみ先にコピー
COPY requirements.txt pyproject.toml ./

# 3. 依存関係インストール(requirements.txt変更時のみ再実行)
RUN pip install --no-cache-dir -r requirements.txt

# 4. アプリケーションコードは最後にコピー
COPY src/ ./src/
COPY scripts/ ./scripts/

# 5. 実行権限設定
RUN chmod +x scripts/*.sh

# 6. 非rootユーザーで実行
RUN adduser --disabled-password --gecos '' appuser 
    && chown -R appuser:appuser /app
USER appuser

CMD ["python", "src/main.py"]

キャッシュ効率測定:

# キャッシュ効果の測定
echo "=== First Build (no cache) ==="
time docker build --no-cache -t app:v1 .

echo "=== Second Build (with cache) ==="
time docker build -t app:v2 .

echo "=== Code Change Build ==="
echo "# minor change" >> src/main.py
time docker build -t app:v3 .

echo "=== Dependency Change Build ==="
echo "requests==2.31.0" >> requirements.txt
time docker build -t app:v4 .

2. .dockerignore の効果的活用

ビルドコンテキストを最小化してビルド時間を短縮:

# .dockerignore - 効果的な除外設定
# 開発・テストファイル
**/__pycache__
**/*.pyc
**/*.pyo
**/*.pyd
**/.pytest_cache
**/test_*
**/tests/
**/*.test.js
**/coverage/
**/htmlcov/
**/.coverage
**/.nyc_output
**/jest.config.js

# 開発ツール設定
**/.vscode/
**/.idea/
**/.git/
**/.gitignore
**/README.md
**/CHANGELOG.md
**/*.md

# 依存関係キャッシュ
**/node_modules/
**/.npm/
**/.yarn/
**/.pnpm-store/
**/__pycache__/
**/.pip-cache/

# ビルド成果物
**/dist/
**/build/
**/target/
**/*.log
**/logs/

# OS固有ファイル
**/.DS_Store
**/Thumbs.db
**/*.tmp
**/*.temp

# 環境設定(機密情報)
**/.env
**/.env.local
**/.env.*.local
**/secrets/
**/*.key
**/*.pem

# 重い開発用ファイル
**/data/
**/datasets/
**/*.csv
**/*.sql
**/*.db
**/*.sqlite

# Docker関連(ネストしたDockerビルドを避ける)
**/Dockerfile*
**/docker-compose*.yml
**/.dockerignore

効果測定:

# .dockerignore前後の比較
echo "=== Without .dockerignore ==="
mv .dockerignore .dockerignore.bak
time docker build -t app:without-ignore .

echo "=== With .dockerignore ==="
mv .dockerignore.bak .dockerignore
time docker build -t app:with-ignore .

# ビルドコンテキストサイズ確認
docker build --progress=plain . 2>&1 | grep "transferring context"

3. マルチステージビルドの高速化

開発用と本番用で最適化されたビルドステージ:

# 高速化マルチステージビルド
#==============================================================================
# 共通ベースイメージ
#==============================================================================
FROM python:3.11-slim as base

# システム最適化
RUN apt-get update && apt-get install -y 
    # 最小限の必要パッケージのみ
    build-essential 
    curl 
    && rm -rf /var/lib/apt/lists/* 
    && apt-get clean 
    # pipの最適化
    && pip install --upgrade pip setuptools wheel

WORKDIR /app

#==============================================================================
# 依存関係ビルドステージ(重い処理を分離)
#==============================================================================
FROM base as dependencies

# Poetryを使用した依存関係管理
ENV POETRY_HOME="/opt/poetry"
ENV POETRY_PATH="$POETRY_HOME/bin" 
ENV PATH="$POETRY_PATH:$PATH"
RUN pip install poetry

# 依存関係ファイルのコピー
COPY pyproject.toml poetry.lock ./

# 依存関係の事前ビルド(wheelファイル生成)
RUN poetry config virtualenvs.create false 
    && poetry install --only main --no-dev 
    && poetry cache clear . --all

#==============================================================================
# 開発環境ステージ(高速起動重視)
#==============================================================================
FROM dependencies as development

# 開発用追加依存関係
RUN poetry install --with dev

# 開発用設定
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=development

# ホットリロード用設定
COPY . .
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "src.main:app", "--reload", "--host", "0.0.0.0"]

#==============================================================================
# 本番環境ステージ(最小サイズ重視)
#==============================================================================
FROM python:3.11-slim as production

# 最小限の実行環境
RUN apt-get update && apt-get install -y 
    # 実行時に必要な最小限のパッケージ
    libpq5 
    && rm -rf /var/lib/apt/lists/* 
    && apt-get clean

WORKDIR /app

# 依存関係ステージから必要ファイルのみコピー
COPY --from=dependencies /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=dependencies /usr/local/bin /usr/local/bin

# アプリケーションコードのコピー
COPY src/ ./src/
COPY scripts/entrypoint.prod.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

# セキュリティ設定
RUN adduser --disabled-password --gecos '' appuser 
    && chown -R appuser:appuser /app
USER appuser

# 本番最適化設定
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=production

EXPOSE 8000
ENTRYPOINT ["/entrypoint.sh"]
CMD ["gunicorn", "src.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]

4. BuildKit機能の活用

Docker BuildKitの先進機能でビルド時間を劇的に短縮:

# BuildKit有効化
export DOCKER_BUILDKIT=1

# 並列ビルド実行
docker buildx build 
  --platform linux/amd64,linux/arm64 
  --cache-from type=registry,ref=myapp:buildcache 
  --cache-to type=registry,ref=myapp:buildcache,mode=max 
  --push 
  -t myapp:latest .

高度なキャッシュ設定:

# syntax=docker/dockerfile:1.4
FROM python:3.11-slim

# BuildKitキャッシュマウント使用
RUN --mount=type=cache,target=/root/.cache/pip 
    --mount=type=cache,target=/var/cache/apt 
    apt-get update && 
    apt-get install -y build-essential && 
    pip install -r requirements.txt

秘密情報の安全な受け渡し:

# syntax=docker/dockerfile:1.4
FROM node:18

# シークレットマウント(ビルド履歴に残らない)
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc 
    npm install
# ビルド時の秘密情報指定
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" | docker buildx build 
  --secret id=npmrc,src=- 
  -t myapp:latest .

実行時パフォーマンス最適化

1. ファイルI/O最適化

開発時のファイル同期パフォーマンスを大幅に改善:

macOS/Windows での最適化設定:

# docker-compose.yml - ファイル同期最適化
services:
  app:
    build: .
    volumes:
      # コードファイル: cached(読み込み重視)
      - ./src:/app/src:cached
      - ./tests:/app/tests:cached

      # 設定ファイル: ro(読み取り専用)
      - ./config:/app/config:ro

      # ログ出力: delegated(書き込み重視)
      - ./logs:/app/logs:delegated

      # 依存関係: 名前付きボリューム(高速)
      - node_modules:/app/node_modules
      - pip_cache:/app/.pip_cache

      # 一時ファイル: tmpfs(メモリ)
      - type: tmpfs
        target: /app/tmp
        tmpfs:
          size: 100M

volumes:
  node_modules:
    driver: local
  pip_cache:
    driver: local

Linux での最適化設定:

# Linux環境での高速化
services:
  app:
    volumes:
      # bindマウント(Linux では高速)
      - type: bind
        source: ./src
        target: /app/src
        consistency: default

      # 大量ファイル処理用の最適化
      - type: volume
        source: build_cache
        target: /app/.build
        volume:
          driver: local
          driver_opts:
            type: none
            o: bind
            device: /tmp/build_cache

volumes:
  build_cache:
    driver: local

2. メモリ使用量最適化

コンテナのメモリ使用量を効率化する具体的手法:

メモリ効率的なPython設定:

# src/config.py - メモリ最適化設定
import os
import gc
from typing import Optional

class MemoryOptimizedSettings:
    def __init__(self):
        # Python メモリ最適化
        self.setup_python_memory_optimization()

        # アプリケーション設定
        self.max_workers = self._calculate_optimal_workers()
        self.db_pool_size = self._calculate_db_pool_size()

    def setup_python_memory_optimization(self):
        """Python実行時のメモリ最適化"""
        # ガベージコレクション頻度調整
        gc.set_threshold(700, 10, 10)

        # メモリプールサイズ制限
        os.environ['PYTHONMALLOC'] = 'malloc'

        # 文字列インターン最適化
        os.environ['PYTHONHASHSEED'] = '0'

    def _calculate_optimal_workers(self) -> int:
        """利用可能メモリに基づく最適ワーカー数算出"""
        try:
            # コンテナのメモリ制限確認
            with open('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'r') as f:
                memory_limit = int(f.read().strip())

            # 1ワーカーあたり256MBとして計算
            optimal_workers = max(1, min(4, memory_limit // (256 * 1024 * 1024)))
            return optimal_workers
        except:
            return 2  # デフォルト値

    def _calculate_db_pool_size(self) -> int:
        """メモリに応じたDB接続プールサイズ"""
        workers = self.max_workers
        return max(5, workers * 2)

# 使用例
settings = MemoryOptimizedSettings()

Docker メモリ制限とモニタリング:

# docker-compose.yml - メモリ制限設定
services:
  app:
    build: .
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'
        reservations:
          memory: 256M
          cpus: '0.25'

    # メモリ使用量監視
    healthcheck:
      test: |
        MEMORY_USAGE=$$(ps -o pid,vsz,rss,comm -p 1 | tail -1 | awk '{print $$3}')
        if [ $$MEMORY_USAGE -gt 400000 ]; then
          echo "High memory usage: $${MEMORY_USAGE}KB"
          exit 1
        fi
      interval: 30s
      timeout: 10s
      retries: 3

メモリプロファイリングスクリプト:

#!/usr/bin/env python3
# scripts/memory_profiler.py - メモリ使用量分析

import psutil
import time
import json
from datetime import datetime

def profile_memory_usage(duration_minutes=5, interval_seconds=10):
    """メモリ使用量をプロファイリング"""

    results = []
    end_time = time.time() + (duration_minutes * 60)

    print(f"🔍 Memory profiling for {duration_minutes} minutes...")

    while time.time() < end_time:
        # システム全体のメモリ情報
        memory = psutil.virtual_memory()

        # Dockerコンテナのプロセス情報
        container_processes = []
        for proc in psutil.process_iter(['pid', 'name', 'memory_info', 'cpu_percent']):
            try:
                if 'python' in proc.info['name'].lower():
                    container_processes.append({
                        'pid': proc.info['pid'],
                        'name': proc.info['name'],
                        'memory_mb': proc.info['memory_info'].rss / 1024 / 1024,
                        'cpu_percent': proc.info['cpu_percent']
                    })
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue

        # 結果記録
        results.append({
            'timestamp': datetime.now().isoformat(),
            'system_memory': {
                'total_mb': memory.total / 1024 / 1024,
                'available_mb': memory.available / 1024 / 1024,
                'used_mb': memory.used / 1024 / 1024,
                'percent': memory.percent
            },
            'container_processes': container_processes
        })

        # 進捗表示
        print(f"📊 Memory: {memory.percent:.1f}% | "
              f"Processes: {len(container_processes)}")

        time.sleep(interval_seconds)

    # 結果をJSONで保存
    with open('/tmp/memory_profile.json', 'w') as f:
        json.dump(results, f, indent=2)

    # サマリー表示
    avg_memory = sum(r['system_memory']['percent'] for r in results) / len(results)
    max_memory = max(r['system_memory']['percent'] for r in results)

    print(f"n📈 Memory Profile Summary:")
    print(f"Average memory usage: {avg_memory:.1f}%")
    print(f"Peak memory usage: {max_memory:.1f}%")
    print(f"Profile saved to: /tmp/memory_profile.json")

if __name__ == "__main__":
    profile_memory_usage()

3. CPU使用効率化

マルチコア環境でのCPU使用効率を最大化:

並列処理最適化例(Python):

# src/performance/cpu_optimizer.py
import os
import multiprocessing as mp
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from typing import List, Callable, Any

class CPUOptimizer:
    def __init__(self):
        self.cpu_count = mp.cpu_count()
        self.optimal_workers = self._calculate_optimal_workers()

    def _calculate_optimal_workers(self) -> int:
        """コンテナ環境での最適ワーカー数計算"""
        try:
            # cgroup制限確認
            with open('/sys/fs/cgroup/cpu/cpu.cfs_quota_us', 'r') as f:
                quota = int(f.read().strip())
            with open('/sys/fs/cgroup/cpu/cpu.cfs_period_us', 'r') as f:
                period = int(f.read().strip())

            if quota > 0:
                cpu_limit = quota / period
                return max(1, int(cpu_limit))
        except:
            pass

        # デフォルト: 物理CPU数の80%
        return max(1, int(self.cpu_count * 0.8))

    def process_parallel_io(self, tasks: List[Callable], max_workers: int = None) -> List[Any]:
        """I/O集約的タスクの並列実行(スレッド使用)"""
        workers = max_workers or self.optimal_workers * 2

        with ThreadPoolExecutor(max_workers=workers) as executor:
            results = list(executor.map(lambda task: task(), tasks))

        return results

    def process_parallel_cpu(self, tasks: List[Callable], max_workers: int = None) -> List[Any]:
        """CPU集約的タスクの並列実行(プロセス使用)"""
        workers = max_workers or self.optimal_workers

        with ProcessPoolExecutor(max_workers=workers) as executor:
            results = list(executor.map(lambda task: task(), tasks))

        return results

# 使用例
def cpu_intensive_task():
    """CPU集約的な処理の例"""
    return sum(i * i for i in range(1000000))

def io_intensive_task():
    """I/O集約的な処理の例"""
    import time
    time.sleep(0.1)
    return "completed"

# 最適化された並列実行
optimizer = CPUOptimizer()
print(f"Optimal workers: {optimizer.optimal_workers}")

# CPU集約的タスク
cpu_tasks = [cpu_intensive_task] * 4
cpu_results = optimizer.process_parallel_cpu(cpu_tasks)

# I/O集約的タスク
io_tasks = [io_intensive_task] * 10
io_results = optimizer.process_parallel_io(io_tasks)

Uvicorn/Gunicorn最適化設定:

# gunicorn.conf.py - 本番用高性能設定
import os
import multiprocessing

# ワーカー設定
workers = int(os.environ.get("GUNICORN_WORKERS", multiprocessing.cpu_count() * 2 + 1))
worker_class = "uvicorn.workers.UvicornWorker"
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 50

# メモリ管理
preload_app = True
worker_tmp_dir = "/dev/shm"  # メモリファイルシステム使用

# パフォーマンス調整
keepalive = 2
timeout = 120
graceful_timeout = 30

# ログ設定
loglevel = "info"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'

def when_ready(server):
    server.log.info(f"Server ready with {workers} workers")

def worker_int(worker):
    worker.log.info("Worker received INT or QUIT signal")

def on_exit(server):
    server.log.info("Server shutting down")

イメージサイズ最適化

1. マルチステージビルドによるサイズ削減

本番イメージのサイズを最小限に抑制:

最適化前後の比較:

# 最適化前: 1.2GB
FROM python:3.11
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

# 最適化後: 150MB
FROM python:3.11-slim as builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

FROM python:3.11-slim
COPY --from=builder /root/.local /root/.local
COPY src/ /app/src/
WORKDIR /app
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "src/app.py"]

Distroless イメージ活用:

# Google Distroless使用 - さらなるサイズ削減
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --target=/app/dependencies -r requirements.txt

FROM gcr.io/distroless/python3
COPY --from=builder /app/dependencies /app/dependencies
COPY src/ /app/src/
WORKDIR /app
ENV PYTHONPATH=/app/dependencies
CMD ["src/app.py"]

2. レイヤー最適化

Docker レイヤー数とサイズを最小化:

# 最適化されたレイヤー構成
FROM python:3.11-slim

# 単一RUNコマンドで複数処理を実行(レイヤー削減)
RUN apt-get update && apt-get install -y 
    # 必要なパッケージのみ
    build-essential 
    libpq-dev 
    curl 
    && pip install --no-cache-dir 
    # pipキャッシュ無効化
    setuptools 
    wheel 
    # 不要ファイル削除
    && apt-get purge -y --auto-remove build-essential 
    && rm -rf /var/lib/apt/lists/* 
    && rm -rf /root/.cache

# .dockerignore と組み合わせた効率的コピー
COPY src/ /app/src/
COPY requirements.txt /app/

WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt 
    && rm requirements.txt

# 最小権限ユーザー
RUN adduser --disabled-password --gecos '' --uid 1000 appuser
USER appuser

CMD ["python", "src/app.py"]

3. イメージサイズ分析とモニタリング

#!/bin/bash
# scripts/image-analyzer.sh - イメージサイズ分析

echo "🔍 Docker Image Size Analysis"
echo "=============================="

IMAGE_NAME=${1:-"myapp:latest"}

# 基本情報
echo "📋 Basic Information:"
docker images $IMAGE_NAME --format "table {{.Repository}}t{{.Tag}}t{{.Size}}t{{.CreatedAt}}"
echo ""

# レイヤー別サイズ分析
echo "📊 Layer Analysis:"
docker history $IMAGE_NAME --format "table {{.CreatedBy}}t{{.Size}}"
echo ""

# イメージ内容詳細分析
echo "🔍 Content Analysis:"
docker run --rm $IMAGE_NAME du -sh /* 2>/dev/null | sort -rh | head -10
echo ""

# 最適化提案
CURRENT_SIZE=$(docker images $IMAGE_NAME --format "{{.Size}}" | head -1)
echo "💡 Optimization Recommendations:"
echo "Current size: $CURRENT_SIZE"

# Python キャッシュチェック
PYTHON_CACHE=$(docker run --rm $IMAGE_NAME find / -name "__pycache__" -type d 2>/dev/null | wc -l)
if [ "$PYTHON_CACHE" -gt 0 ]; then
    echo "⚠️  Found $PYTHON_CACHE Python cache directories - consider: RUN find /app -name '__pycache__' -delete"
fi

# apt キャッシュチェック
APT_CACHE=$(docker run --rm $IMAGE_NAME ls -la /var/lib/apt/lists/ 2>/dev/null | wc -l)
if [ "$APT_CACHE" -gt 3 ]; then
    echo "⚠️  APT cache found - consider: RUN rm -rf /var/lib/apt/lists/*"
fi

echo ""
echo "✅ Analysis completed!"

継続的パフォーマンス監視

自動化監視システム

# docker-compose.monitoring.yml - パフォーマンス監視
services:
  app:
    build: .
    depends_on:
      - prometheus
      - grafana
    labels:
      - "prometheus.scrape=true"
      - "prometheus.port=8000"

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
      - ./monitoring/grafana-dashboards:/var/lib/grafana/dashboards

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    privileged: true
    devices:
      - /dev/kmsg

volumes:
  prometheus_data:
  grafana_data:

パフォーマンス回帰検出

#!/bin/bash
# scripts/performance-regression-test.sh

echo "🧪 Performance Regression Test"
echo "==============================="

# ベースライン設定
BASELINE_BUILD_TIME=60  # 秒
BASELINE_IMAGE_SIZE=200  # MB
BASELINE_STARTUP_TIME=10  # 秒

# 現在の測定
CURRENT_BUILD_TIME=$(./scripts/performance-benchmark.sh | grep "Build time:" | awk '{print $3}' | sed 's/s//')
CURRENT_IMAGE_SIZE=$(docker images myapp:latest --format "{{.Size}}" | sed 's/MB//' | cut -d'.' -f1)
CURRENT_STARTUP_TIME=$(./scripts/performance-benchmark.sh | grep "Startup time:" | awk '{print $3}' | sed 's/s//')

# 回帰チェック
echo "📊 Performance Comparison:"
echo "MetricttBaselinetCurrentttStatus"
echo "----------------------------------------"

# ビルド時間チェック
BUILD_REGRESSION=$((CURRENT_BUILD_TIME * 100 / BASELINE_BUILD_TIME))
if [ $BUILD_REGRESSION -gt 120 ]; then
    BUILD_STATUS="❌ REGRESSION"
    EXIT_CODE=1
else
    BUILD_STATUS="✅ OK"
fi
echo -e "Build Timet${BASELINE_BUILD_TIME}stt${CURRENT_BUILD_TIME}stt${BUILD_STATUS}"

# イメージサイズチェック
SIZE_REGRESSION=$((CURRENT_IMAGE_SIZE * 100 / BASELINE_IMAGE_SIZE))
if [ $SIZE_REGRESSION -gt 120 ]; then
    SIZE_STATUS="❌ REGRESSION"
    EXIT_CODE=1
else
    SIZE_STATUS="✅ OK"
fi
echo -e "Image Sizet${BASELINE_IMAGE_SIZE}MBtt${CURRENT_IMAGE_SIZE}MBtt${SIZE_STATUS}"

# 起動時間チェック
STARTUP_REGRESSION=$((CURRENT_STARTUP_TIME * 100 / BASELINE_STARTUP_TIME))
if [ $STARTUP_REGRESSION -gt 120 ]; then
    STARTUP_STATUS="❌ REGRESSION"
    EXIT_CODE=1
else
    STARTUP_STATUS="✅ OK"
fi
echo -e "Startup Timet${BASELINE_STARTUP_TIME}stt${CURRENT_STARTUP_TIME}stt${STARTUP_STATUS}"

if [ ${EXIT_CODE:-0} -eq 1 ]; then
    echo ""
    echo "❌ Performance regression detected!"
    exit 1
else
    echo ""
    echo "✅ All performance metrics within acceptable range"
fi

まとめ

この記事では、コンテナ開発環境のパフォーマンス最適化について、実践的で即座に適用可能なテクニックを詳しく解説しました。

重要な最適化ポイント

ビルド時間削減:

  • レイヤーキャッシュの効果的活用
  • .dockerignore による不要ファイル除外
  • マルチステージビルドの適切な設計
  • BuildKit機能の活用

実行時パフォーマンス:

  • ファイルI/O最適化(ボリューム設定)
  • メモリ使用量の効率化
  • CPU使用率の最適化
  • 並列処理の適切な実装

リソース効率化:

  • イメージサイズの最小化
  • 継続的な監視と回帰検出
  • 自動化されたパフォーマンステスト

効果的な改善の進め方

  1. 現状測定: まず現在のパフォーマンスを定量的に測定
  2. 優先順位付け: 最もインパクトの大きい改善から実施
  3. 段階的改善: 小さな改善を積み重ねて大きな効果を実現
  4. 継続監視: 回帰を防ぐための監視体制構築

次のステップ

パフォーマンス最適化をマスターしたら、次は本番環境での運用とセキュリティ強化に進むことをお勧めします:

適切なパフォーマンス最適化により、開発効率が大幅に向上し、より快適なコンテナ開発環境を実現できます。


関連記事:

コメントする