エンタープライズ向け Zabbix 拡張パターン:K8S Pod ネットワークトラフィック収集(cAdvisor ベース)

一般的に Zabbix の Kubernetes テンプレートは、CPU・メモリ・ディスク・ノード状態・コンテナ状態などの基本指標を中心に提供されている。
しかし Pod 単位のネットワークトラフィックは含まれていない
多くの運用環境では Prometheus を併用してこの課題を解決するが、ここでは Zabbix 単体で Pod レベルのネットワークトラフィック収集を完全に実現した構成を共有する。

この設計は参考資料が一切無い状態から独自に構築したもので、実際の運用環境で動作検証済みである。

🔗 関連記事


■ 設計概要

データソース: Kubelet cAdvisor メトリクス
収集構成: HTTP agent → マスターアイテム → Discovery(LDD) → アイテムプロトタイプ → 前処理チェーン
最終目的: Pod / Namespace / Interface 単位の RX/TX トラフィック(bps)


1. マスターアイテム

Kubernetes Kubelet by HTTP: Get cadvisor metrics
をマスターアイテムとして使用する。

すべての Discovery およびアイテムプロトタイプは、このデータを基に動作する。


2. Discovery ルール作成(Prod K8S NODE)

Zabbix Web UI → データ収集 → ホスト → 対象ホスト → Discovery →
Discovery ルール追加

  • 名前: cadvisor network interface discovery
  • 種類: 依存アイテム
  • キー: kubelet.cadvisor.net.discovery
  • マスターアイテム: Prod-K8S NODE: Get cadvisor metrics

● 前処理(JavaScript)

Pod / Namespace / Interface を抽出(重複排除あり)

var lines = value.split("\n");

var seen = {};
var result = [];

for (var i = 0; i < lines.length; i++) {

    var match = lines[i].match(/^container_network_receive_bytes_total{([^}]+)}/);
    if (!match) continue;

    var labelBlock = match[1];
    var iface = (labelBlock.match(/interface="([^"]+)"/) || [])[1];
    var pod = (labelBlock.match(/pod="([^"]+)"/) || [])[1];
    var ns = (labelBlock.match(/namespace="([^"]+)"/) || [])[1];

    if (!iface || !pod || !ns) continue;

    var key = iface + pod + ns;
    if (seen[key]) continue;

    seen[key] = true;

    result.push({
        "{#IFACE}": iface,
        "{#POD}": pod,
        "{#NAMESPACE}": ns
    });
}

return JSON.stringify({ data: result });

3. アイテムプロトタイプ


A. RX トラフィック

ディスカバリ → アイテムプロトタイプ → 新規追加

  • 名前: RX: [{#NAMESPACE}] {#POD} ({#IFACE})
  • 種類: 依存アイテム
  • キー: cadvisor.net.rx[{#IFACE},{#POD},{#NAMESPACE}]
  • 単位: bps
  • データ型: 数値(float)
  • マスターアイテム: Prod K8S NODE: Get cadvisor metrics

● 前処理チェーン ①:RX 最新値抽出(JavaScript)

var lines = value.split("\n");

var iface = "{#IFACE}";
var pod = "{#POD}";
var ns = "{#NAMESPACE}";

var latestTs = 0;
var latestVal = 0;

for (var i = 0; i < lines.length; i++) {

    var m = lines[i].match(/^container_network_receive_bytes_total{([^}]+)}\s+([0-9.eE+-]+)\s+(\d+)$/);
    if (!m) continue;

    var labels = m[1];
    var val = parseFloat(m[2]);
    var ts = parseInt(m[3], 10);

    if (
        labels.includes('interface="' + iface + '"') &&
        labels.includes('pod="' + pod + '"') &&
        labels.includes('namespace="' + ns + '"')
    ) {
        if (ts > latestTs) {
            latestTs = ts;
            latestVal = val;
        }
    }
}

if (latestTs > 0) return latestVal;

throw "No matching metric found";

● 前処理チェーン ②:1秒単位の変化量(per second)

※Zabbix の「変化量を毎秒値として計算」を使用

(Zabbix UI 上の標準前処理ステップ:差分 → 秒換算

● 前処理チェーン ③:bps(bit/sec)へ変換(JavaScript)

return value * 8;

B. TX トラフィック

  • 名前: TX: [{#NAMESPACE}] {#POD} ({#IFACE})
  • 種類: 依存アイテム
  • キー: cadvisor.net.tx[{#IFACE},{#POD},{#NAMESPACE}]
  • 単位: bps
  • データ型: 数値(float)
  • マスターアイテム: Prod K8S NODE: Get cadvisor metrics

● 前処理 ①:TX 最新値抽出(JavaScript)

var lines = value.split("\n");

var iface = "{#IFACE}";
var pod = "{#POD}";
var ns = "{#NAMESPACE}";

var latestTs = 0;
var latestVal = 0;

for (var i = 0; i < lines.length; i++) {

    var m = lines[i].match(/^container_network_transmit_bytes_total\{([^}]+)\}\s+([0-9.eE+-]+)\s+(\d+)$/);
    if (!m) continue;

    var labels = m[1];
    var val = parseFloat(m[2]);
    var ts = parseInt(m[3]);

    if (
        labels.includes('interface="' + iface + '"') &&
        labels.includes('pod="' + pod + '"') &&
        labels.includes('namespace="' + ns + '"')
    ) {
        if (ts > latestTs) {
            latestTs = ts;
            latestVal = val;
        }
    }
}

if (latestTs > 0) return latestVal;

throw "No matching metric found";

● 前処理 ②:1秒単位変化量(per second)

Zabbix 標準前処理「変化量を毎秒値として計算」を適用。

● 前処理 ③:bps へ変換(JavaScript)

return value * 8;

■ Tip.

Prod K8S NODE ホストの {$KUBE.KUBELET.URL} がマスターノードを向いている場合
Zabbix は そのマスター上のコンテナ(Pod)しか収集できない

これは cAdvisor が
「そのノード上で稼働しているコンテナのみを提供する」
という構造だからである。

したがって クラスタ全体の Pod トラフィックを収集するには、すべてのノードを Zabbix ホストとして追加し、
各ホストで {$KUBE.KUBELET.URL} を以下のように設定する必要がある:

https://<ノードIP>:10250

例:

https://192.168.50.11:10250
https://192.168.50.12:10250
https://192.168.50.13:10250

これにより、ノードごとに独立して cAdvisor を参照し、
そのノードで実際に動作している Pod の RX/TX が自動生成される。

Prometheus のように自動で全ノードをスクレイプする方式ではないため、
Zabbix ではノード単位の設定が必須となる。


■ cAdvisor の特性とノード単位設定が必要な理由

cAdvisor は kubelet 内で動作し、
そのノードのコンテナしかメトリクスを提供しない

そのため:

  • マスター → システム Pod(kube-proxy / calico-node / node-local-dns など)だけが見える
  • ワーカー → アプリケーション Pod のネットワークトラフィックは、そのノードを直接参照しない限り取得不可

もしマスターだけでディスカバリを動かすと、
業務 Pod がまったく見えない。


4. トリガー戦略

物理 NIC のトラフィック監視は別で実施しているため、
Pod レベルのネットワークはフロー分析専用として運用中。
そのためトリガーは作成していないが、必要に応じてプロトタイプから容易に追加できる。


5. エンタープライズ利用価値

  • Zabbix 標準テンプレートの限界を独自に補完
  • Prometheus なしで Pod レベルのネットワーク可視化を実現
  • Discovery + プロトタイプ で自動的に拡張
  • 実運用で安定性を確認済み

この設計は Zabbix を
ノード/リソース監視ツールから Pod ネットワーク監視まで拡張するエンタープライズ級ソリューションへ発展させた事例である。

🛠 마지막 수정일: 2025.11.25

💡 お困りですか?
Zabbix、Kubernetes、各種オープンソースインフラの構築・運用・最適化・障害解析が必要であれば、いつでもご連絡ください。

📧 メール: jikimy75@gmail.com
💼 サービス: 導入支援 | 性能チューニング | 障害解析コンサルティング