td-agent から Amazon Linux 2023 + Fluentd v6 へのバージョンアップについて

どうも、クラ本の黒田です。
大変ご無沙汰しております。
以前は、AnsibleでTD-Agentを使ったログ収集システムの構築のアウトプットしてました。
今回、Amazon Linux 2 EOL: 2025年6月30日になることで、td-agent 4.x から Fluentd v6 への移行と、Amazon Linux 2 から Amazon Linux 2023 へのアップグレードを安全に実施するためのアウトプットをしていきます。
file

🎯 目次

  1. 前提条件と環境確認
  2. 移行計画と準備
  3. 詳細なアップグレード手順
  4. 注意事項とリスク管理
  5. トラブルシューティング
  6. ロールバック手順
  7. 運用移行と監視

📋 前提条件と環境確認 {#前提条件}

1.1 システム要件

現行環境の最小要件

項目 要件 確認コマンド
OS Amazon Linux 2 cat /etc/os-release
td-agent v4.0以上 td-agent --version
メモリ 最低2GB、推奨4GB以上 free -h
ディスク空き容量 最低10GB df -h
Ruby 2.7以上 /opt/td-agent/bin/ruby --version

移行先環境の要件

項目 要件 備考
OS Amazon Linux 2023 Kernel 6.1+
Fluentd v6.0以上 fluent-package
メモリ 推奨4GB以上 ワーカー数に応じて調整
ディスク 最低20GB バッファ用に余裕を持つ
Ruby 3.3 (自動インストール) Fluentdに同梱

1.2 環境確認スクリプト

#!/bin/bash
# pre_migration_check.sh - 移行前環境確認スクリプト

echo "========================================="
echo "td-agent 移行前環境確認"
echo "========================================="

# OSバージョン確認
echo -e "\n[1] OSバージョン"
cat /etc/os-release | grep -E "NAME|VERSION"

# td-agentバージョン
echo -e "\n[2] td-agent バージョン"
td-agent --version

# インストール済みプラグイン
echo -e "\n[3] インストール済みプラグイン"
td-agent-gem list | grep fluent-plugin

# 設定ファイルの確認
echo -e "\n[4] 設定ファイル"
ls -lh /etc/td-agent/*.conf

# ディスク使用状況
echo -e "\n[5] ディスク使用状況"
df -h | grep -E "Filesystem|/var|/opt"

# メモリ使用状況
echo -e "\n[6] メモリ使用状況"
free -h

# td-agentプロセス状況
echo -e "\n[7] td-agent プロセス状況"
systemctl status td-agent | head -20

# ログ出力先の確認
echo -e "\n[8] アクティブな出力先"
grep -E "^\s*@type\s+(s3|cloudwatch_logs|forward|kinesis)" /etc/td-agent/td-agent.conf

# バッファサイズの確認
echo -e "\n[9] 現在のバッファ使用量"
du -sh /var/log/td-agent/buffer/* 2>/dev/null || echo "バッファディレクトリが存在しません"

# ポート使用状況
echo -e "\n[10] ポート使用状況"
netstat -tuln | grep -E "24224|24230"

echo -e "\n========================================="
echo "確認完了"
echo "========================================="
# 実行
chmod +x pre_migration_check.sh
sudo ./pre_migration_check.sh > pre_migration_report.txt

1.3 依存関係の確認

# 使用中のプラグインとバージョンの完全リスト取得
sudo td-agent-gem list --local > current_plugins.txt

# 重要なプラグインの互換性確認
cat current_plugins.txt | grep -E "fluent-plugin-(s3|cloudwatch|kinesis|elasticsearch|kafka|prometheus)"

主要プラグインの互換性マトリクス

プラグイン td-agent 4.x Fluentd v6 移行時の注意
fluent-plugin-s3 1.7.x 2.0.x+ 設定項目名変更あり
fluent-plugin-cloudwatch-logs 0.14.x 0.15.x+ 互換性あり
fluent-plugin-kinesis 3.4.x 3.5.x+ バッファ設定見直し推奨
fluent-plugin-elasticsearch 5.2.x 5.4.x+ APIバージョン確認必要
fluent-plugin-kafka 0.18.x 0.19.x+ librdkafka更新必要

1.4 バックアップ必須項目チェックリスト

#!/bin/bash
# backup_preparation.sh - バックアップ準備スクリプト

BACKUP_DIR="/backup/td-agent-$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR

echo "バックアップ開始: $BACKUP_DIR"

# 1. 設定ファイル
echo "[1/7] 設定ファイルをバックアップ中..."
sudo cp -r /etc/td-agent $BACKUP_DIR/etc-td-agent

# 2. プラグインリスト
echo "[2/7] プラグインリストを保存中..."
sudo td-agent-gem list --local > $BACKUP_DIR/plugins.txt

# 3. カスタムプラグイン
echo "[3/7] カスタムプラグインをバックアップ中..."
if [ -d /etc/td-agent/plugin ]; then
    sudo cp -r /etc/td-agent/plugin $BACKUP_DIR/custom-plugins
fi

# 4. ログファイル(直近7日分)
echo "[4/7] ログファイルをバックアップ中..."
sudo find /var/log/td-agent -name "*.log" -mtime -7 -exec cp {} $BACKUP_DIR/logs/ \;

# 5. バッファファイル(重要)
echo "[5/7] バッファファイルをバックアップ中..."
if [ -d /var/log/td-agent/buffer ]; then
    sudo cp -r /var/log/td-agent/buffer $BACKUP_DIR/buffer
fi

# 6. 環境変数
echo "[6/7] 環境変数をバックアップ中..."
sudo systemctl show td-agent --property=Environment > $BACKUP_DIR/environment.txt

# 7. systemdユニットファイル
echo "[7/7] systemdユニットファイルをバックアップ中..."
sudo cp /usr/lib/systemd/system/td-agent.service $BACKUP_DIR/

# バックアップ検証
echo -e "\n========================================="
echo "バックアップ完了: $BACKUP_DIR"
echo "========================================="
ls -lh $BACKUP_DIR
du -sh $BACKUP_DIR

# S3へのバックアップ(オプション)
read -p "S3にもバックアップしますか? (y/n): " backup_s3
if [ "$backup_s3" = "y" ]; then
    read -p "S3バケット名を入力: " s3_bucket
    aws s3 cp -r $BACKUP_DIR s3://$s3_bucket/td-agent-backups/
    echo "S3バックアップ完了"
fi

📝 移行計画と準備 {#移行計画}

2.1 移行戦略の選択

オプション A: インプレース移行(非推奨)

メリット:
✅ IPアドレス変更不要
✅ 移行時間が短い

デメリット:
❌ ロールバックが困難
❌ ダウンタイムが発生
❌ リスクが高い

推奨度: ⭐⭐☆☆☆
適用: 開発/検証環境のみ

オプション B: ブルーグリーン移行(推奨)

メリット:
✅ ロールバックが容易
✅ ダウンタイムゼロ
✅ 並行運用で検証可能

デメリット:
❌ 一時的にリソース2倍
❌ 設定変更が必要

推奨度: ⭐⭐⭐⭐⭐
適用: 本番環境

オプション C: カナリアリリース(大規模環境推奨)

メリット:
✅ 段階的リスク軽減
✅ 問題の早期発見
✅ 影響範囲の限定

デメリット:
❌ 移行期間が長い
❌ 管理が複雑

推奨度: ⭐⭐⭐⭐⭐
適用: 大規模本番環境(100台以上)

2.2 移行スケジュール例

Week 1: 準備フェーズ
├─ Day 1-2: 環境確認とバックアップ
├─ Day 3-4: 検証環境構築
└─ Day 5: 動作テスト

Week 2: 検証フェーズ
├─ Day 1-3: 機能テスト
├─ Day 4: 負荷テスト
└─ Day 5: 振り返りと修正

Week 3: 移行フェーズ(カナリア)
├─ Day 1: 10%のサーバーを移行
├─ Day 2-3: 監視と検証
├─ Day 4: 50%まで拡大
└─ Day 5: 残り全て移行

Week 4: 安定化フェーズ
├─ Day 1-3: 監視と最適化
├─ Day 4: 旧環境の停止
└─ Day 5: ドキュメント整備

2.3 関係者への事前通知テンプレート

件名: 【重要】ログ収集基盤の移行について(影響度:中)

各位

ログ収集基盤の移行を以下の通り実施します。

## 移行内容
- td-agent 4.x → Fluentd v6
- Amazon Linux 2 → Amazon Linux 2023

## 実施日時
- 第1フェーズ: 2025年X月X日 10:00-12:00(検証環境)
- 第2フェーズ: 2025年X月X日 14:00-18:00(本番環境)

## 影響範囲
- ログ収集の一時的な遅延(最大5分)
- ダッシュボードの一時的な更新停止

## リスクと対策
- リスク: ログロストの可能性
- 対策: バッファリング設定により最小化

## ロールバック判断基準
- ログロスト率が1%を超えた場合
- エラー率が5%を超えた場合

## 連絡先
- 担当: [名前]
- 緊急連絡: [電話番号]

🚀 詳細なアップグレード手順 {#アップグレード手順}

Phase 1: 検証環境の構築(1-2日)

Step 1.1: 新規インスタンスの起動

# EC2インスタンス起動(AWS CLI)
aws ec2 run-instances \
  --image-id ami-0c50424cef7f9b81b \  # Amazon Linux 2023
  --instance-type t3.medium \
  --key-name my-keypair \
  --security-group-ids sg-xxxxx \
  --subnet-id subnet-xxxxx \
  --iam-instance-profile Name=FluentdRole \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=fluentd-v6-test},{Key=Environment,Value=staging}]' \
  --user-data file://init-script.sh

init-script.sh の内容:

#!/bin/bash
set -e

# ログ出力
exec > >(tee /var/log/user-data.log)
exec 2>&1

echo "=== Amazon Linux 2023 初期設定開始 ==="

# システムアップデート
echo "[1/8] システムアップデート実行中..."
dnf update -y

# 必要なパッケージのインストール
echo "[2/8] 必要なパッケージをインストール中..."
dnf install -y \
  gcc gcc-c++ make \
  git wget curl \
  vim htop \
  awscli \
  amazon-cloudwatch-agent

# Fluentd公式リポジトリの追加
echo "[3/8] Fluentdリポジトリを追加中..."
curl -fsSL https://toolbelt.treasuredata.com/sh/install-amazon2023-fluent-package.sh | sh

# Fluentdのインストール
echo "[4/8] Fluentd v6をインストール中..."
dnf install -y fluent-package

# バージョン確認
echo "[5/8] バージョン確認..."
fluentd --version
ruby --version

# ディレクトリ作成
echo "[6/8] 必要なディレクトリを作成中..."
mkdir -p /etc/fluent/plugin
mkdir -p /var/log/fluentd/{buffer,failed_chunks}
mkdir -p /opt/fluentd/scripts

# パーミッション設定
echo "[7/8] パーミッション設定中..."
chown -R fluentd:fluentd /var/log/fluentd
chown -R fluentd:fluentd /etc/fluent
chmod -R 755 /var/log/fluentd

# サービス有効化(まだ起動しない)
echo "[8/8] サービス設定中..."
systemctl enable fluentd
systemctl disable td-agent 2>/dev/null || true

echo "=== 初期設定完了 ==="

Step 1.2: 基本プラグインのインストール

# SSHでログイン後

# プラグインインストールスクリプト
cat << 'EOF' > /tmp/install_plugins.sh
#!/bin/bash

# 使用するプラグインのリスト
PLUGINS=(
  "fluent-plugin-s3"
  "fluent-plugin-cloudwatch-logs"
  "fluent-plugin-kinesis"
  "fluent-plugin-prometheus"
  "fluent-plugin-rewrite-tag-filter"
  "fluent-plugin-record-modifier"
  "fluent-plugin-systemd"
  "fluent-plugin-concat"
)

echo "Fluentd プラグインをインストール中..."

for plugin in "${PLUGINS[@]}"; do
  echo "Installing $plugin..."
  fluent-gem install $plugin

  if [ $? -eq 0 ]; then
    echo "✓ $plugin インストール成功"
  else
    echo "✗ $plugin インストール失敗"
    exit 1
  fi
done

echo -e "\n=== インストール済みプラグイン一覧 ==="
fluent-gem list | grep fluent-plugin

echo -e "\n=== インストール完了 ==="
EOF

chmod +x /tmp/install_plugins.sh
sudo /tmp/install_plugins.sh

Step 1.3: 基本設定ファイルの作成

# /etc/fluent/fluentd.conf

######################
# Fluentd v6 設定ファイル
# 作成日: 2025-01-XX
# 環境: staging
######################

# システム設定
<system>
  # プロセス設定
  workers 2
  root_dir /var/log/fluentd

  # ログ設定
  log_level info
  suppress_repeated_stacktrace true
  emit_error_log_interval 30s
  suppress_config_dump true

  # メトリクス(v6新機能)
  enable_input_metrics true
  enable_size_metrics true

  # プロセス名
  process_name fluentd-worker
</system>

# 内部ログのルーティング
<label @FLUENT_LOG>
  <match fluent.*>
    @type file
    path /var/log/fluentd/internal.log
    append true

    <format>
      @type json
    </format>

    <buffer>
      @type file
      path /var/log/fluentd/buffer/internal
      flush_mode interval
      flush_interval 10s
      flush_at_shutdown true
    </buffer>
  </match>
</label>

# Prometheus メトリクス公開
<source>
  @type prometheus
  bind 0.0.0.0
  port 24231
  metrics_path /metrics
</source>

<source>
  @type prometheus_monitor
  interval 10

  <labels>
    host "#{Socket.gethostname}"
    environment staging
  </labels>
</source>

<source>
  @type prometheus_output_monitor
  interval 10

  <labels>
    host "#{Socket.gethostname}"
    environment staging
  </labels>
</source>

# ヘルスチェック用エンドポイント
<source>
  @type http
  bind 0.0.0.0
  port 8888

  <parse>
    @type json
  </parse>
</source>

# テスト用入力
<source>
  @type tail
  path /var/log/test.log
  pos_file /var/log/fluentd/test.pos
  tag test.log

  <parse>
    @type json
  </parse>

  # v6の新機能
  read_lines_limit 1000
  read_bytes_limit_per_second 8388608  # 8MB/s
</source>

# テスト用出力(ファイル)
<match test.**>
  @type file
  path /var/log/fluentd/output/test
  append true

  <format>
    @type json
  </format>

  <buffer time>
    @type file
    path /var/log/fluentd/buffer/test
    timekey 60
    timekey_wait 10s
    flush_mode interval
    flush_interval 10s
    flush_at_shutdown true
  </buffer>
</match>

Step 1.4: 設定ファイルのテスト

# 構文チェック
sudo fluentd --dry-run -c /etc/fluent/fluentd.conf

# 期待される出力:
# configuration file /etc/fluent/fluentd.conf is valid

# テストモードで起動(フォアグラウンド)
sudo fluentd -c /etc/fluent/fluentd.conf -vv

# 別のターミナルでテストログを送信
echo '{"message":"test log","timestamp":"'$(date -Iseconds)'"}' | sudo tee -a /var/log/test.log

# 出力ファイルを確認
tail -f /var/log/fluentd/output/test/buffer.*

Phase 2: 設定移行(2-3日)

Step 2.1: td-agent設定の解析

# 設定ファイル解析スクリプト
cat << 'EOF' > /tmp/analyze_config.py
#!/usr/bin/env python3
"""
td-agent設定ファイル解析ツール
Fluentd v6への移行に必要な変更点を抽出
"""

import re
import sys
from collections import defaultdict

def analyze_config(config_file):
    """設定ファイルを解析"""

    results = {
        'sources': [],
        'matches': [],
        'filters': [],
        'plugins': set(),
        'issues': [],
        'warnings': []
    }

    with open(config_file, 'r') as f:
        content = f.read()

    # ソースの抽出
    sources = re.findall(r'<source>.*?</source>', content, re.DOTALL)
    for source in sources:
        source_type = re.search(r'@type\s+(\w+)', source)
        if source_type:
            results['sources'].append(source_type.group(1))

    # マッチの抽出
    matches = re.findall(r'<match\s+([^>]+)>.*?@type\s+(\w+)', content, re.DOTALL)
    results['matches'] = matches

    # プラグインの抽出
    plugins = re.findall(r'@type\s+(\w+)', content)
    results['plugins'] = set(plugins)

    # 非推奨設定のチェック
    deprecated = [
        (r'buffer_type\s+file', 'buffer_type は廃止。<buffer> ディレクティブを使用'),
        (r'time_slice_format', 'time_slice_format は廃止。timekey を使用'),
        (r'buffer_chunk_limit', 'buffer_chunk_limit は廃止。chunk_limit_size を使用'),
        (r'buffer_queue_limit', 'buffer_queue_limit は廃止。queue_limit_length を使用'),
    ]

    for pattern, message in deprecated:
        if re.search(pattern, content):
            results['issues'].append(message)

    # パス関連の警告
    if '/var/log/td-agent' in content:
        results['warnings'].append('パスを /var/log/fluentd に変更必要')

    if '/etc/td-agent' in content:
        results['warnings'].append('パスを /etc/fluent に変更必要')

    return results

def print_report(results):
    """レポート出力"""

    print("=" * 60)
    print("td-agent 設定ファイル解析レポート")
    print("=" * 60)

    print(f"\n[ソース] 検出数: {len(results['sources'])}")
    for source in set(results['sources']):
        count = results['sources'].count(source)
        print(f"  - {source}: {count}個")

    print(f"\n[出力] 検出数: {len(results['matches'])}")
    for pattern, output_type in results['matches']:
        print(f"  - {pattern} → {output_type}")

    print(f"\n[使用プラグイン] 検出数: {len(results['plugins'])}")
    for plugin in sorted(results['plugins']):
        print(f"  - {plugin}")

    if results['issues']:
        print(f"\n[重要な問題] {len(results['issues'])}件")
        for issue in results['issues']:
            print(f"  ⚠️  {issue}")

    if results['warnings']:
        print(f"\n[警告] {len(results['warnings'])}件")
        for warning in results['warnings']:
            print(f"  ⚡ {warning}")

    print("\n" + "=" * 60)

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print("Usage: python3 analyze_config.py <config_file>")
        sys.exit(1)

    config_file = sys.argv[1]
    results = analyze_config(config_file)
    print_report(results)
EOF

chmod +x /tmp/analyze_config.py

# 実行
python3 /tmp/analyze_config.py /etc/td-agent/td-agent.conf

Step 2.2: 設定ファイルの自動変換

# 設定変換スクリプト
cat << 'EOF' > /tmp/convert_config.sh
#!/bin/bash
# td-agent.conf を fluentd.conf に変換

INPUT_FILE="$1"
OUTPUT_FILE="$2"

if [ -z "$INPUT_FILE" ] || [ -z "$OUTPUT_FILE" ]; then
    echo "Usage: $0 <input_file> <output_file>"
    exit 1
fi

echo "変換開始: $INPUT_FILE → $OUTPUT_FILE"

# コピーして変換
cp "$INPUT_FILE" "$OUTPUT_FILE"

# パス変換
sed -i 's|/var/log/td-agent|/var/log/fluentd|g' "$OUTPUT_FILE"
sed -i 's|/etc/td-agent|/etc/fluent|g' "$OUTPUT_FILE"

# 非推奨パラメータ変換
sed -i 's|buffer_type file|@type file|g' "$OUTPUT_FILE"
sed -i 's|time_slice_format|timekey|g' "$OUTPUT_FILE"
sed -i 's|buffer_chunk_limit|chunk_limit_size|g' "$OUTPUT_FILE"
sed -i 's|buffer_queue_limit|queue_limit_length|g' "$OUTPUT_FILE"

# バッファ設定の構造変換
# 注意: 複雑な変換は手動確認が必要

echo "変換完了: $OUTPUT_FILE"
echo "⚠️  手動確認が必要な項目:"
echo "  - バッファ設定の構造"
echo "  - プラグイン固有の設定"
echo "  - カスタムフォーマット"

EOF

chmod +x /tmp/convert_config.sh

# 実行
sudo /tmp/convert_config.sh /etc/td-agent/td-agent.conf /etc/fluent/fluentd.conf.tmp

Step 2.3: 具体的な設定変換例

変換前(td-agent 4.x):

<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx.pos
  tag nginx.access
  format json
</source>

<match nginx.**>
  @type s3
  aws_key_id "#{ENV['AWS_ACCESS_KEY_ID']}"
  aws_sec_key "#{ENV['AWS_SECRET_ACCESS_KEY']}"
  s3_bucket my-logs
  s3_region ap-northeast-1
  path logs/

  buffer_type file
  buffer_path /var/log/td-agent/buffer/s3
  buffer_chunk_limit 256m
  buffer_queue_limit 512
  flush_interval 60s
  time_slice_format %Y%m%d%H
  time_slice_wait 10m
</match>

変換後(Fluentd v6):

<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/fluentd/nginx.pos
  tag nginx.access

  <parse>
    @type json
  </parse>

  # v6 新機能: パフォーマンス最適化
  read_lines_limit 1000
  read_bytes_limit_per_second 8388608  # 8MB/s

  # エラーハンドリング強化
  emit_unmatched_lines true
  ignore_repeated_permission_error true
</source>

<match nginx.**>
  @type s3

  # IAMロール使用(キー不要)
  # aws_key_id と aws_sec_key は削除

  s3_bucket my-logs
  s3_region ap-northeast-1
  path logs/%Y/%m/%d/  # 階層化されたパス

  # v6 推奨: タイムゾーン明示
  <inject>
    time_key timestamp
    time_type string
    time_format %Y-%m-%dT%H:%M:%S%z
    timezone Asia/Tokyo
  </inject>

  # バッファ設定(新フォーマット)
  <buffer time>
    @type file
    path /var/log/fluentd/buffer/s3

    # チャンク設定
    timekey 3600  # 1時間
    timekey_wait 600  # 10分
    chunk_limit_size 256m

    # キュー設定
    queue_limit_length 512
    total_limit_size 128g  # v6新機能: 合計サイズ制限

    # フラッシュ設定
    flush_mode interval
    flush_interval 60s
    flush_at_shutdown true
    flush_thread_count 2  # v6新機能: 並列フラッシュ

    # v6新機能: オーバーフロー対策
    overflow_action drop_oldest_chunk

    # リトライ設定強化
    retry_type exponential_backoff
    retry_timeout 72h
    retry_max_interval 30m
    retry_forever false
  </buffer>

  # v6新機能: セカンダリ出力
  <secondary>
    @type file
    path /var/log/fluentd/failed_chunks/s3

    <format>
      @type json
    </format>
  </secondary>

  # 圧縮設定
  <compress>
    @type gzip
  </compress>

  # S3固有設定
  store_as gzip
  s3_object_key_format %{path}%{time_slice}_%{index}.%{file_extension}
</match>

Phase 3: テストと検証(3-5日)

Step 3.1: 機能テスト

# 機能テストスクリプト
cat << 'EOF' > /tmp/functional_test.sh
#!/bin/bash
# Fluentd v6 機能テスト

set -e

TEST_LOG_FILE="/var/log/test_fluentd.log"
OUTPUT_DIR="/var/log/fluentd/output"
METRICS_URL="http://localhost:24231/metrics"

echo "========================================="
echo "Fluentd v6 機能テスト開始"
echo "========================================="

# Test 1: サービス起動確認
echo -e "\n[Test 1] サービス起動確認"
if systemctl is-active --quiet fluentd; then
    echo "✓ Fluentd サービスが起動しています"
else
    echo "✗ Fluentd サービスが起動していません"
    exit 1
fi

# Test 2: ポート確認
echo -e "\n[Test 2] ポート確認"
if netstat -tuln | grep -q ":24224"; then
    echo "✓ Forward port (24224) が開いています"
else
    echo "⚠️  Forward port (24224) が開いていません"
fi

if netstat -tuln | grep -q ":24231"; then
    echo "✓ Metrics port (24231) が開いています"
else
    echo "✗ Metrics port (24231) が開いていません"
fi

# Test 3: ログ収集テスト
echo -e "\n[Test 3] ログ収集テスト"
echo '{"timestamp":"'$(date -Iseconds)'","level":"info","message":"Test log from functional test"}' | sudo tee -a $TEST_LOG_FILE

sleep 5

if [ -d "$OUTPUT_DIR" ] && [ "$(ls -A $OUTPUT_DIR 2>/dev/null)" ]; then
    echo "✓ ログファイルが出力されています"
    ls -lh $OUTPUT_DIR/
else
    echo "✗ ログファイルが出力されていません"
fi

# Test 4: メトリクス取得
echo -e "\n[Test 4] Prometheusメトリクス取得"
if curl -s $METRICS_URL | grep -q "fluentd_"; then
    echo "✓ メトリクスが取得できています"
    echo "サンプル:"
    curl -s $METRICS_URL | grep fluentd_output_status_buffer | head -5
else
    echo "✗ メトリクスが取得できません"
fi

# Test 5: エラーログ確認
echo -e "\n[Test 5] エラーログ確認"
ERROR_COUNT=$(sudo grep -c "ERROR" /var/log/fluentd/fluentd.log 2>/dev/null || echo "0")
echo "エラー件数: $ERROR_COUNT"

if [ "$ERROR_COUNT" -eq 0 ]; then
    echo "✓ エラーログなし"
else
    echo "⚠️  エラーログあり - 確認が必要です"
    sudo grep "ERROR" /var/log/fluentd/fluentd.log | tail -5
fi

# Test 6: バッファディレクトリ確認
echo -e "\n[Test 6] バッファディレクトリ確認"
BUFFER_SIZE=$(du -sh /var/log/fluentd/buffer 2>/dev/null | cut -f1)
echo "バッファサイズ: $BUFFER_SIZE"

echo -e "\n========================================="
echo "機能テスト完了"
echo "========================================="
EOF

chmod +x /tmp/functional_test.sh
sudo /tmp/functional_test.sh

Step 3.2: 負荷テスト

# 負荷テストスクリプト
cat << 'EOF' > /tmp/load_test.sh
#!/bin/bash
# Fluentd v6 負荷テスト

DURATION=300  # 5分
RATE=1000     # 1000 events/sec
TEST_TAG="loadtest.data"

echo "負荷テスト開始"
echo "Duration: ${DURATION}秒"
echo "Rate: ${RATE} events/sec"

# テストデータ生成
generate_log() {
    echo "{\"timestamp\":\"$(date -Iseconds)\",\"level\":\"info\",\"message\":\"Load test message $RANDOM\",\"request_id\":\"$RANDOM\"}"
}

# メトリクス収集開始
echo "初期メトリクス:"
curl -s http://localhost:24231/metrics | grep fluentd_output_status_num_records_total

# 負荷生成
START_TIME=$(date +%s)
END_TIME=$((START_TIME + DURATION))
SENT_COUNT=0

while [ $(date +%s) -lt $END_TIME ]; do
    for i in $(seq 1 $RATE); do
        generate_log | curl -s -X POST -d @- http://localhost:8888/$TEST_TAG
        ((SENT_COUNT++))
    done
    sleep 1
done

echo "送信完了: $SENT_COUNT イベント"

# 処理待ち
echo "処理完了を待機中..."
sleep 30

# 最終メトリクス
echo "最終メトリクス:"
curl -s http://localhost:24231/metrics | grep fluentd_output_status_num_records_total

# リソース使用状況
echo -e "\nリソース使用状況:"
ps aux | grep fluentd | grep -v grep
EOF

chmod +x /tmp/load_test.sh
sudo /tmp/load_test.sh

⚠️ 注意事項とリスク管理 {#注意事項}

3.1 重要な注意事項

❗ クリティカルな注意点

  1. バッファデータの取り扱い
    
    # ⚠️ 重要: バッファ内のデータは移行前に必ずフラッシュ
    sudo systemctl stop td-agent
    sleep 60  # フラッシュ完了を待機

バッファ残存確認

sudo find /var/log/td-agent/buffer -type f -name "*.buf" | wc -l

0であることを確認

もし残っている場合

sudo systemctl start td-agent

フラッシュ完了まで待機してから再度停止


2. **IAMロールとアクセスキー**
```bash
# ⚠️ 重要: アクセスキーの平文保存は非推奨
# td-agentで使用していた場合、IAMロールに移行必須

# 現在の設定確認
grep -r "aws_key_id\|aws_sec_key" /etc/td-agent/

# IAMロール確認
aws sts get-caller-identity

# ポリシー確認
aws iam get-instance-profile --instance-profile-name FluentdRole</code></pre>
<ol start="3">
<li><strong>ログローテーション</strong>
<pre><code class="language-bash">
# ⚠️ 重要: posファイルの扱い
# td-agent と fluentd は別のposファイルを使用
# 同じログファイルを読む場合、重複送信に注意</code></pre></li>
</ol>
<h1>対策: 移行時は pos_file を削除して最初から読み直す</h1>
<h1>または、読み取り位置を調整する</h1>
<pre><code>
#### ⚡ 重要な変更点

| 項目 | td-agent 4.x | Fluentd v6 | 影響 |
|------|--------------|------------|------|
| デフォルトユーザー | td-agent | fluentd | パーミッション再設定必要 |
| 設定ディレクトリ | /etc/td-agent | /etc/fluent | パス変更必要 |
| ログディレクトリ | /var/log/td-agent | /var/log/fluentd | パス変更必要 |
| サービス名 | td-agent.service | fluentd.service | systemd設定変更必要 |
| Rubyバージョン | 2.7 | 3.3 | プラグイン互換性確認必要 |
| バッファフォーマット | 互換性あり | 互換性あり | そのまま利用可 |

### 3.2 よくある問題と対策

#### 問題 1: プラグインが見つからない

```bash
# エラー例
# Unknown output plugin 'cloudwatch_logs'

# 原因確認
fluent-gem list | grep cloudwatch

# 解決方法
sudo fluent-gem install fluent-plugin-cloudwatch-logs

# インストール確認
fluent-gem list | grep cloudwatch

問題 2: パーミッションエラー

# エラー例
# Permission denied - /var/log/nginx/access.log

# 原因確認
ls -l /var/log/nginx/access.log
# -rw-r----- 1 nginx nginx

# 解決方法1: グループに追加
sudo usermod -aG nginx fluentd

# 解決方法2: ACL設定
sudo setfacl -m u:fluentd:r /var/log/nginx/access.log
sudo setfacl -d -m u:fluentd:r /var/log/nginx/

# 解決方法3: パーミッション変更(非推奨)
sudo chmod 644 /var/log/nginx/access.log

# 再起動
sudo systemctl restart fluentd

問題 3: メモリ使用量が高い

# 現状確認
ps aux | grep fluentd
free -h

# バッファサイズの調整
# /etc/fluent/fluentd.conf
<buffer>
  # チャンクサイズを削減
  chunk_limit_size 128m  # 256m → 128m

  # 合計サイズを制限
  total_limit_size 4g    # 8g → 4g

  # フラッシュ間隔を短縮
  flush_interval 30s     # 60s → 30s
</buffer>

# ワーカー数を削減
<system>
  workers 1  # 2 → 1
</system>

問題 4: S3へのアップロードが遅い

# 最適化設定
<match **>
  @type s3
  s3_bucket my-logs
  s3_region ap-northeast-1

  <buffer time>
    # 圧縮を有効化
    compress gzip

    # 並列アップロード
    flush_thread_count 4

    # チャンクサイズ最適化
    chunk_limit_size 256m

    # フラッシュ間隔調整
    flush_interval 60s

    # タイムアウト設定
    flush_thread_burst_interval 0.05
  </buffer>

  # S3固有設定
  <format>
    @type json
  </format>

  # マルチパートアップロード
  use_server_side_encryption AES256
  compute_checksums false  # チェックサム計算を無効化(高速化)
</match>

3.3 セキュリティ考慮事項

# 1. 機密情報の保護
# 環境変数を使用
export AWS_REGION=ap-northeast-1
export S3_BUCKET=my-secure-logs

# systemd環境変数設定
sudo mkdir -p /etc/systemd/system/fluentd.service.d
cat << EOF | sudo tee /etc/systemd/system/fluentd.service.d/environment.conf
[Service]
Environment="AWS_REGION=ap-northeast-1"
Environment="S3_BUCKET=my-secure-logs"
EnvironmentFile=-/etc/sysconfig/fluentd
EOF

sudo systemctl daemon-reload

# 2. ログファイルのパーミッション
sudo chmod 640 /etc/fluent/fluentd.conf
sudo chown root:fluentd /etc/fluent/fluentd.conf

# 3. TLS/SSL設定(forward入力)
<source>
  @type forward
  port 24224
  bind 0.0.0.0

  <transport tls>
    cert_path /etc/fluent/certs/fluentd.crt
    private_key_path /etc/fluent/certs/fluentd.key
    private_key_passphrase your_passphrase
  </transport>

  <security>
    self_hostname fluentd-server
    shared_key secure_shared_key_here
  </security>
</source>

# 4. ファイアウォール設定
sudo firewall-cmd --permanent --add-port=24224/tcp  # Forward
sudo firewall-cmd --permanent --add-port=24231/tcp  # Metrics (内部のみ)
sudo firewall-cmd --reload

🔄 ロールバック手順 {#ロールバック}

4.1 ロールバック判断基準

自動ロールバック条件:
  - ログロスト率 > 1%
  - エラー率 > 5%
  - レイテンシ > 5秒(P95)
  - メモリ使用率 > 90%
  - CPU使用率 > 80%(5分以上継続)

手動ロールバック条件:
  - ビジネスクリティカルなログが欠損
  - 予期しない動作の発生
  - ステークホルダーからの要請

4.2 ロールバックスクリプト

#!/bin/bash
# rollback_to_td_agent.sh - Fluentd v6からtd-agentへのロールバック

set -e

BACKUP_DIR="/backup/td-agent-20250115_100000"  # バックアップディレクトリ

echo "========================================="
echo "ロールバック開始"
echo "========================================="

# 確認プロンプト
read -p "本当にロールバックしますか? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
    echo "ロールバックをキャンセルしました"
    exit 1
fi

# Step 1: Fluentd v6 停止
echo "[1/7] Fluentd v6 を停止中..."
sudo systemctl stop fluentd
sudo systemctl disable fluentd

# Step 2: 現在の設定をバックアップ(ロールバック失敗時用)
echo "[2/7] 現在の設定をバックアップ中..."
ROLLBACK_BACKUP="/backup/rollback-$(date +%Y%m%d_%H%M%S)"
sudo mkdir -p $ROLLBACK_BACKUP
sudo cp -r /etc/fluent $ROLLBACK_BACKUP/
sudo cp -r /var/log/fluentd $ROLLBACK_BACKUP/

# Step 3: td-agent 再インストール
echo "[3/7] td-agent を再インストール中..."
curl -fsSL https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh
sudo yum install -y td-agent

# Step 4: 設定ファイルのリストア
echo "[4/7] 設定ファイルをリストア中..."
sudo cp -r $BACKUP_DIR/etc-td-agent/* /etc/td-agent/

# Step 5: プラグインの再インストール
echo "[5/7] プラグインを再インストール中..."
if [ -f $BACKUP_DIR/plugins.txt ]; then
    while read plugin; do
        plugin_name=$(echo $plugin | awk '{print $1}')
        if [[ $plugin_name == fluent-plugin-* ]]; then
            echo "Installing $plugin_name..."
            sudo td-agent-gem install $plugin_name
        fi
    done < $BACKUP_DIR/plugins.txt
fi

# Step 6: バッファのリストア
echo "[6/7] バッファをリストア中..."
if [ -d $BACKUP_DIR/buffer ]; then
    sudo cp -r $BACKUP_DIR/buffer/* /var/log/td-agent/buffer/
    sudo chown -R td-agent:td-agent /var/log/td-agent/buffer
fi

# Step 7: td-agent 起動
echo "[7/7] td-agent を起動中..."
sudo systemctl enable td-agent
sudo systemctl start td-agent

# 動作確認
sleep 10
if sudo systemctl is-active --quiet td-agent; then
    echo "✓ td-agent が正常に起動しました"
else
    echo "✗ td-agent の起動に失敗しました"
    exit 1
fi

echo "========================================="
echo "ロールバック完了"
echo "========================================="

# 後処理の指示
echo -e "\n次の作業を実施してください:"
echo "1. ログ収集が正常に動作しているか確認"
echo "2. ダッシュボードでメトリクスを確認"
echo "3. 関係者へロールバック完了を通知"
echo "4. Fluentd v6 で発生した問題を記録"

4.3 部分ロールバック(カナリアリリース時)

# 特定のサーバーのみロールバック
# ロードバランサーから除外
aws elbv2 deregister-targets \
  --target-group-arn arn:aws:elasticloadbalancing:... \
  --targets Id=i-1234567890abcdef0

# 当該サーバーでロールバック実行
ssh ec2-user@server ./rollback_to_td_agent.sh

# 確認後、再登録
aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:... \
  --targets Id=i-1234567890abcdef0

📊 運用移行と監視 {#運用移行}

5.1 監視ダッシュボード構築

CloudWatch ダッシュボード設定

{
  "widgets": [
    {
      "type": "metric",
      "properties": {
        "metrics": [
          [ "Fluentd", "BufferQueueLength", { "stat": "Average" } ],
          [ ".", "OutputRecords", { "stat": "Sum" } ],
          [ ".", "ErrorCount", { "stat": "Sum", "color": "#d62728" } ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "ap-northeast-1",
        "title": "Fluentd メトリクス",
        "yAxis": {
          "left": {
            "min": 0
          }
        }
      }
    },
    {
      "type": "metric",
      "properties": {
        "metrics": [
          [ "AWS/EC2", "CPUUtilization", { "stat": "Average" } ],
          [ ".", "MemoryUtilization", { "stat": "Average" } ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "ap-northeast-1",
        "title": "リソース使用率"
      }
    }
  ]
}

Grafana ダッシュボード(Prometheus データソース)

# /etc/fluent/prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'fluentd'
    static_configs:
      - targets: ['localhost:24231']
        labels:
          environment: 'production'
          service: 'fluentd'

5.2 アラート設定

# CloudWatch Logs Insights クエリ
# エラー検出
fields @timestamp, level, message
| filter level = "error"
| stats count() by bin(5m)

# レイテンシ監視
fields @timestamp, latency
| filter latency > 1000
| stats avg(latency), max(latency), count() by bin(5m)
# CloudWatch Alarm 作成
aws cloudwatch put-metric-alarm \
  --alarm-name fluentd-high-error-rate \
  --alarm-description "Fluentd error rate is too high" \
  --metric-name ErrorCount \
  --namespace Fluentd \
  --statistic Sum \
  --period 300 \
  --threshold 100 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --alarm-actions arn:aws:sns:ap-northeast-1:123456789012:fluentd-alerts

5.3 運用ドキュメント

# Fluentd v6 運用マニュアル

## 日次運用

### 毎日チェック項目
- [ ] サービス稼働状況: `systemctl status fluentd`
- [ ] エラーログ確認: `sudo grep ERROR /var/log/fluentd/fluentd.log`
- [ ] ディスク使用率: `df -h | grep fluentd`
- [ ] メトリクス確認: CloudWatch ダッシュボード

### 週次運用

- [ ] バッファサイズ確認と削減
- [ ] ログローテーション確認
- [ ] プラグインアップデート確認
- [ ] パフォーマンスレポート作成

## トラブル対応

### サービスが起動しない

1. 設定ファイルの構文チェック
   ```bash
   sudo fluentd --dry-run -c /etc/fluent/fluentd.conf
   ```

2. ログ確認
   ```bash
   sudo journalctl -u fluentd -n 100
   ```

3. パーミッション確認
   ```bash
   sudo -u fluentd ls -l /var/log/fluentd
   ```

### ログが出力されない

1. 入力ソースの確認
2. フィルタ設定の確認
3. 出力先の接続確認
4. バッファ状態の確認

## エスカレーション

- レベル1: オンコールエンジニア(30分以内)
- レベル2: インフラチーム(1時間以内)
- レベル3: ベンダーサポート(翌営業日)

📚 まとめ

✅ 移行チェックリスト(最終確認)

## 移行前
- [ ] 現環境の完全バックアップ
- [ ] プラグインリストの取得
- [ ] 設定ファイルの解析
- [ ] 関係者への通知
- [ ] ロールバック手順の準備

## 移行中
- [ ] Amazon Linux 2023 インストール
- [ ] Fluentd v6 インストール
- [ ] プラグインインストール
- [ ] 設定ファイル変換と配置
- [ ] 機能テスト実施
- [ ] 負荷テスト実施

## 移行後
- [ ] 本番トラフィック切り替え
- [ ] 24時間監視
- [ ] パフォーマンスレポート作成
- [ ] ドキュメント更新
- [ ] 旧環境の廃止

## 1週間後
- [ ] 安定性の最終確認
- [ ] コスト分析
- [ ] 振り返りミーティング
- [ ] 知見の共有

📈 期待される効果

項目 改善前 改善後 改善率
スループット 10k events/s 15k events/s +50%
メモリ使用量 256 MB 192 MB -25%
CPU使用率 15% 12% -20%
サポート期限 2025年6月 2028年 +2.5年

🎓 教訓とベストプラクティス

  1. 段階的な移行が成功の鍵

    • いきなり本番環境で実施しない
    • カナリアリリースで徐々に拡大
  2. バックアップは念入りに

    • 設定だけでなくバッファも保存
    • 複数世代のバックアップを保持
  3. 監視体制の整備

    • 移行前にメトリクスの baseline 取得
    • リアルタイム監視の実装
  4. ドキュメンテーション

    • 手順書の整備
    • トラブルシューティングガイド
    • ナレッジベースの構築

📞 サポートとリソース

## 公式リソース
- Fluentd公式ドキュメント: https://docs.fluentd.org/
- Fluentd Slack: https://slack.fluentd.org/
- GitHub Issues: https://github.com/fluent/fluentd/issues

## AWS リソース
- Amazon Linux 2023 User Guide
- AWS Systems Manager (パッチ管理)
- AWS Support(Enterprise契約時)

## コミュニティ
- Fluentd Meetup
- AWS User Group
- Stack Overflow(fluentdタグ)

以上、上記内容をもとに、安全かつ確実に Fluentd v6 への移行を完了できます。不明点があれば、まずは検証環境で試してから本番環境に適用してください。 🚀

Last modified: 2025-11-11

Author