Claude Media
Claude CodeでKafkaコンシューマーラグを調べる — describeだけ許可する設定

Claude CodeでKafkaコンシューマーラグを調べる — describeだけ許可する設定

kafka-consumer-groups.shの--describeと--listだけを許可し、--reset-offsetsと--deleteをdenyに置く権限設計と、ラグ急増をリバランスか処理遅延かに切り分ける読み方です。

KafkaのコンシューマーラグをClaude Codeに調べさせるなら、kafka-consumer-groups.sh の --list と --describe だけをallowに置き、--reset-offsets と --delete をdenyに置く構成が最小です。調査に必要なのは読み取りだけで、オフセットのリセットやグループの削除は、調査の途中でClaudeが選ぶ操作ではないからです。

この記事では、その settings.json の書き方と、--describe の出力からラグ急増の原因を絞る読み方を順に示します。MCPサーバー経由で同じ調査をする手順はKafka MCPサーバーでトピックとコンシューマーグループを調べるにあります。ここではMCPを入れず、手元のKafka同梱CLIだけで済ませる場合を扱います。

先に決める: Claudeに許す操作と許さない操作

kafka-consumer-groups.sh は、1つのコマンドで読み取りも破壊的操作もできるツールです。Kafkaのドキュメントでは、次のオプションが並んでいます。

オプション何をするかこの調査での扱い
--list何をするかコンシューマーグループの一覧この調査での扱いallow
--describe何をするか位置・ラグ・メンバー・状態の表示この調査での扱いallow
--reset-offsets何をするかグループのオフセットを書き換えるこの調査での扱いdeny
--delete何をするかコンシューマーグループを削除するこの調査での扱いdeny
--execute何をするかリセットを実際に実行するこの調査での扱いdeny

--reset-offsets は既定が --dry-run で、--execute を付けたときだけ実際に書き換わります。dry-runが既定でもdenyに置く理由は、フラグ1つで挙動が変わる操作を、許可リストの判断に混ぜたくないからです。

settings.jsonに書く許可リスト

プロジェクトの .claude/settings.json に、次のルールを置きます。Claude Codeのpermissionsは、deny、ask、allowの順に評価され、最初に一致したものが結果を決めます。denyに一致した呼び出しは、allowに具体的なルールがあっても止まります。

{
  "permissions": {
    "allow": [
      "Bash(bin/kafka-consumer-groups.sh --bootstrap-server * --list)",
      "Bash(bin/kafka-consumer-groups.sh --bootstrap-server * --describe *)"
    ],
    "deny": [
      "Bash(*--reset-offsets*)",
      "Bash(*--delete*)",
      "Bash(*--execute*)"
    ]
  }
}

書き方のポイントは3つあります。

  • Bashルールはコマンド文字列全体に対して照合され、* は空白を含む任意の文字列を表します
  • allowはオプションの並びまで固定しています。--describe のあとの * は --group my-group や --members --verbose を受けます
  • denyは先頭にも * を置いているので、bin/ の付かない呼び出しや絶対パス指定でも、--reset-offsets という文字列があれば一致します

allowの並びを固定した分、--describe --bootstrap-server ... の順で書かれたコマンドは一致せず、確認プロンプトに落ちます。プロンプトに落ちるのは安全側の挙動なので、そのまま承認して構いません。頻繁に起きるなら、CLAUDE.mdに実行する形を書いておきます。

Kafkaのラグ調査では次の形だけを使う。
bin/kafka-consumer-groups.sh --bootstrap-server <host:port> --describe --group <グループ名>
--members --verbose と --state は --describe の後ろに足してよい。
オフセットのリセット・グループの削除はこのセッションでは行わない。

この許可リストが守れる範囲

Claude Codeの権限ルールは、Claudeが書いたコマンド文字列に対する照合です。ドキュメントは、denyやaskのルールを「Claudeが通常出力する形を止めるもの」と位置づけ、同じプログラムを別の形で呼ぶ例(sh -c '...' や別パス指定)をルールが止めない例として挙げています。ルールは境界ではなく、運用上の安全柵です。

破れない境界が必要なら、Kafka側のACLを使います。KafkaのACL表では、DESCRIBE_GROUPS に必要な権限がGroupへのDescribe、DELETE_GROUPS がGroupへのDelete、OFFSET_COMMIT がGroupへのReadとされています。調査用に別のプリンシパルを作り、GroupとTopicにDescribeだけを付ければ、リセットや削除はブローカーが拒否します。

なお、コンシューマープロトコルを使うグループをdescribeするには、グループが購読しているすべてのトピックへのDESCRIBE権限が管理クライアントに必要です。クラシックプロトコルでは、この要件はありません。調査用プリンシパルを作るときは、この違いに注意が要ります。

ネットワーク側も絞りたい場合は、network.strictAllowlistのようにサンドボックスで接続先を限定する方法があります。

ラグ急増の切り分けに使う4つの出力

権限が決まったら、Claudeに調査を頼みます。依頼文は「グループmy-groupのラグが増えている。describe、members、stateの順に読んで、原因を絞って」で足ります。ここからは、Claudeが読む出力の意味を4つに分けて説明します。以下の出力例はKafkaのドキュメントに載っているサンプルで、手元の実行結果ではありません。

1. パーティションごとのラグを見る

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group my-group

出力には CURRENT-OFFSET、LOG-END-OFFSET、LAG の列が出ます。ドキュメントのサンプルでは、topic1 のパーティション0のラグが1,665なのに対し、topic2 のパーティション0は342,753です。全パーティションが同じように遅れているのか、特定のパーティションだけが突出しているのかが、最初の分かれ目になります。

2. メンバーとパーティション割り当てを見る

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group my-group --members --verbose

--members --verbose は、メンバーごとの担当パーティションを出します。ドキュメントのサンプルには、#PARTITIONS が0で ASSIGNMENT が - のメンバーが含まれています。メンバー数がパーティション数を上回ると、担当のない待機メンバーが出ます。ラグが大きいパーティションを持つメンバーを特定し、そのインスタンスのログや負荷を見る手がかりになります。

3. グループの状態を見る

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group my-group --state

--state は、コーディネーター、割り当て戦略、状態、メンバー数を出します。サンプルでは STATE が Stable、#MEMBERS が4です。Kafkaのメトリクス表は、クラシックグループの状態として PreparingRebalance、CompletingRebalance、Empty、Stable、Dead を挙げています。Stable 以外が続く、あるいは #MEMBERS が想定より少ないなら、リバランスが落ち着いていないか、インスタンスが落ちています。

4. 同じコマンドを間をおいて2回読む

1回の --describe は静止画です。数十秒あけて2回実行し、CURRENT-OFFSET と LOG-END-OFFSET の増え方を比べると、次のように読めます。

2回の比較考えられる原因
CURRENT-OFFSET がほぼ動かず LOG-END-OFFSET だけ増える考えられる原因そのメンバーの処理が止まっている・極端に遅い
両方増えるが LAG が縮まらない考えられる原因流入速度が処理速度を上回っている
STATE が Stable に戻らない、メンバー数が揺れる考えられる原因リバランスが繰り返されている
特定パーティションだけ LAG が大きい考えられる原因そのパーティションを持つメンバーの遅さか、キーの偏り

この表は、各列の定義から導いた読み方です。ドキュメントがこの対応を規定しているわけではないので、原因の当たりを付ける目安として使い、最終判断はアプリケーションのログやメトリクスで裏取りします。コンシューマー側の指標としては、records-lag-max がクライアント側メトリクスとして定義されています。

denyに置くオプションが危ない理由

リセットの方式は複数あり、選び方で結果が大きく変わります。Kafkaのドキュメントは --to-earliest、--to-latest、--shift-by、--to-datetime、--by-duration、--to-offset、--to-current、--from-file を挙げています。

  • --to-latest は未処理のレコードを読み飛ばして最新位置へ進めます。ラグは消えますが、その間のメッセージは処理されないままです
  • --to-earliest は保持されている最も古い位置へ戻します。処理済みのレコードを再処理するので、冪等でないコンシューマーでは二重処理が起きます
  • 範囲外のオフセットは、利用可能な末尾に丸められます

ラグの数字を早く0に近づけたいときほど、--to-latest は魅力的に見えます。ただし調査の目的は原因の特定で、データの扱いを決めるのは別の判断です。だからdenyに置き、実行は人の端末で行う分担にします。

調べる対象のグループ種別に注意する

kafka-consumer-groups.sh が扱うのはコンシューマーグループです。Kafkaは、コンシューマーグループ、シェアグループ、ストリームズグループを別々のツールで管理し、全種別の一覧は bin/kafka-groups.sh --list で出す構成になっています。ラグ調査を頼まれたグループがコンシューマーグループでない場合、--list に名前が出ません。その場合は kafka-groups.sh --list の TYPE 列で種別を確かめてから、種別に合うツールの許可ルールを足します。

また、パーティションを増やした直後のラグにも注意が要ります。Kafkaのドキュメントは、新しいパーティションがクライアントから見えるまでにメタデータの更新間隔(metadata.max.age.ms)による遅れがあり、その間はメッセージの偏りやコンシューマーラグが起きうると述べています。デプロイやパーティション追加の直後に出たラグは、まずこの可能性を除外します。

リセットが必要になったときの引き継ぎ方

原因が特定でき、オフセットを動かす判断をした場合は、人の端末で --dry-run と --export を組み合わせます。ドキュメントには、--all-topics --to-current --dry-run --export > FILE.CSV の形で、リセット後の値をCSVに書き出す例があります。CSVの中身を目で確かめてから、--from-file FILE.CSV --execute で実行する流れなら、何をどこへ動かすかを事前に読めます。ClaudeにはCSVの内容の説明までを頼み、実行は人が行います。

つまずきやすい点

  • allowに書いたのにプロンプトが出る: オプションの並びがルールと違います。--bootstrap-server、--describe の順に揃えるか、CLAUDE.mdで形を指定します
  • コマンドが複合になる: && や | でつなぐと、各部分のコマンドがそれぞれ許可される必要があります。| grep のような読み取りは組み込みの読み取り専用コマンドとして通りますが、tee で書き出す形は別途チェックが入ります
  • denyが広すぎる: *--delete* は --delete-offsets のような別オプションにも一致します。読み取り調査だけなら支障はありませんが、同じセッションで他の削除系操作を頼む場合は範囲を見直します
  • リセットが必要になった: 原因が特定でき、オフセットを戻す判断をしたのは人間です。--dry-run の出力を見せてもらい、実行は自分の端末で行います。コンシューマーが停止していることが前提です

同じ「読み取り系コマンドだけを許可する」発想は、データベースにも使えます。PostgreSQLのレプリケーション遅延を切り分ける手順や、curl -Iだけを許可するCache-Control点検も、同じ権限設計の別の例です。

まとめ

Kafkaのラグ調査は、--list と --describe だけで大半が進みます。allowは読み取り2系統、denyはリセット・削除・実行の3系統に絞り、破れない境界が要るなら調査用プリンシパルにGroupのDescribeだけを付けます。ラグの数字は、パーティション別の偏り、メンバーの割り当て、グループの状態、2回の差分の順に見ると、リバランスと処理遅延のどちらに寄っているかが見えてきます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/permissions
  2. github.com/apache/kafka/blob/trunk/docs/operations/basic-kafka-operat…
  3. github.com/apache/kafka/blob/trunk/docs/security/authorization-and-ac…
この記事を共有:XはてブLinkedIn