ネットワークパス
NetPath 収集器は、DataKit があるノードから対象のネットワークパスをアクティブにプローブします。TCP、UDP、ICMP をサポートします。対象は静的設定で指定することも、datakit-ebpf などのローカルなトラフィックソースから動的に検出することもできます。NetPath は現在 Linux と macOS をサポートし、Windows は未対応です。
実行ごとにネットワーク(N)分類の netpath データが 1 件生成されます。これには、送信元と宛先のコンテキスト、エンドツーエンド遅延、ICMP ロス指標、複数回の traceroute による各 hop の結果が含まれます。
設定¶
DataKit のインストールディレクトリにある conf.d/samples ディレクトリへ移動し、netpath.conf.sample を netpath.conf という名前でコピーします。例は次のとおりです。
[[inputs.netpath]]
## Default protocol for static targets: tcp/udp/icmp/auto.
protocol = "tcp"
## Default static target probe interval.
interval = "60s"
## Per-probe timeout.
timeout = "1s"
## Independent end-to-end probes. These do not inspect intermediate hops.
e2e_queries = 10
## Maximum traceroute TTL and number of complete traceroute runs. The
## effective TTL limit is 60 for TCP/ICMP and 255 for Linux UDP.
max_ttl = 30
traceroute_queries = 3
## Static network path targets.
# [[inputs.netpath.targets]]
# name = "api-gateway"
# target = "api.example.com"
# port = 443
# protocol = "tcp"
# interval = "60s"
# timeout = "1s"
# max_ttl = 30
# traceroute_queries = 3
# e2e_queries = 10
# [inputs.netpath.targets.tags]
# service = "api"
## Dynamic targets discovered from local traffic sources such as datakit-ebpf.
[inputs.netpath.dynamic]
enabled = true
## Optional only when both client and accepted server address are loopback.
## All other requests require a token.
## Configure the same token for datakit-ebpf, which sends it in this header:
## X-Datakit-Netpath-Token: <token>
token = ""
## auto/tcp/udp/icmp. auto uses candidate protocol and falls back to tcp for
## candidates with a port, icmp for address-only candidates. Traceroute
## requires raw socket permission; UDP traceroute is supported on Linux.
protocol = "auto"
## Dynamic candidates are deduplicated and kept for ttl. The scheduler runs
## each candidate at interval while it is alive.
contexts_limit = 5000
## Total estimated bytes retained by stored and currently running contexts.
contexts_bytes_limit = 67108864
ttl = "50m"
interval = "20m"
flush_interval = "10s"
max_per_minute = 150
workers = 4
timeout = "1s"
## The effective TTL limit is 60 for TCP/ICMP and 255 for Linux UDP.
max_ttl = 30
traceroute_queries = 3
e2e_queries = 10
## Maximum concurrent candidate admissions waiting for the store lock.
input_queue = 1000
process_queue = 1000
max_tests_per_request = 1000
max_body_bytes = 1048576
## Set true to allow address-only candidates that do not carry a domain or
## hostname. Keeping this false reduces noisy high-cardinality path tests.
monitor_ip_without_domain = false
## Exclude candidate rules. Conditions inside one rule are ANDed; values in
## the same condition are ORed. A candidate matching any rule is dropped
## before entering the scheduler. Hostname destinations are checked again
## against destination host/CIDR rules after every DNS lookup and before
## any probe packet is sent.
# [[inputs.netpath.dynamic.filters]]
# name = "ignore-kube-system"
# namespaces = ["kube-system"]
#
# [[inputs.netpath.dynamic.filters]]
# name = "ignore-private-db"
# dest_cidrs = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
# ports = [5432, 6379]
## Optional reverse DNS enrichment for destination and hop IPs. Disabled by
## default to avoid adding DNS lookup latency to every traceroute result.
[inputs.netpath.reverse_dns]
enabled = false
timeout = "500ms"
cache_ttl = "10m"
cache_size = 4096
[inputs.netpath.tags]
# some_tag = "some_value"
設定完了後、DataKit を再起動 すれば完了です。
ConfigMap で収集器設定を注入することもできますし、ENV_DEFAULT_ENABLED_INPUTS に netpath を追加したうえで、環境変数で設定を調整することもできます。
-
ENV_INPUT_NETPATH_PROTOCOL
収集器設定フィールド:
protocol -
ENV_INPUT_NETPATH_INTERVAL
収集間隔
フィールド型: Duration
収集器設定フィールド:
intervalデフォルト値: 10s
-
ENV_INPUT_NETPATH_TIMEOUT
タイムアウト時間
フィールド型: Duration
収集器設定フィールド:
timeoutデフォルト値: 30s
-
ENV_INPUT_NETPATH_MAX_TTL
収集器設定フィールド:
max_ttl -
ENV_INPUT_NETPATH_TRACEROUTE_QUERIES
収集器設定フィールド:
traceroute_queries -
ENV_INPUT_NETPATH_E2E_QUERIES
収集器設定フィールド:
e2e_queries -
ENV_INPUT_NETPATH_TAGS
カスタムタグ。設定ファイルに同名のタグがある場合は、それを上書きします
フィールド型: Map
収集器設定フィールド:
tags例:
tag1=value1,tag2=value2 -
ENV_INPUT_NETPATH_DYNAMIC_ENABLED
フィールド型: Boolean
収集器設定フィールド:
dynamic.enabled -
ENV_INPUT_NETPATH_DYNAMIC_PROTOCOL
収集器設定フィールド:
dynamic.protocol -
ENV_INPUT_NETPATH_DYNAMIC_TOKEN
フィールド型: String
収集器設定フィールド:
dynamic.token -
ENV_INPUT_NETPATH_DYNAMIC_TTL
フィールド型: Duration
収集器設定フィールド:
dynamic.ttl -
ENV_INPUT_NETPATH_DYNAMIC_INTERVAL
フィールド型: Duration
収集器設定フィールド:
dynamic.interval -
ENV_INPUT_NETPATH_DYNAMIC_FLUSH_INTERVAL
フィールド型: Duration
収集器設定フィールド:
dynamic.flush_interval -
ENV_INPUT_NETPATH_DYNAMIC_MAX_PER_MINUTE
フィールド型: Int
収集器設定フィールド:
dynamic.max_per_minute -
ENV_INPUT_NETPATH_DYNAMIC_WORKERS
フィールド型: Int
収集器設定フィールド:
dynamic.workers -
ENV_INPUT_NETPATH_DYNAMIC_CONTEXTS_LIMIT
フィールド型: Int
収集器設定フィールド:
dynamic.contexts_limit -
ENV_INPUT_NETPATH_DYNAMIC_CONTEXTS_BYTES_LIMIT
フィールド型: Int
収集器設定フィールド:
dynamic.contexts_bytes_limit -
ENV_INPUT_NETPATH_DYNAMIC_E2E_QUERIES
フィールド型: Int
収集器設定フィールド:
dynamic.e2e_queries -
ENV_INPUT_NETPATH_DYNAMIC_MONITOR_IP_WITHOUT_DOMAIN
フィールド型: Boolean
収集器設定フィールド:
dynamic.monitor_ip_without_domain
静的対象¶
[[inputs.netpath.targets]] で静的対象を設定します。
[[inputs.netpath.targets]]
name = "api-gateway"
target = "api.example.com"
port = 443
protocol = "tcp"
interval = "60s"
timeout = "1s"
max_ttl = 30
traceroute_queries = 3
e2e_queries = 10
[inputs.netpath.targets.tags]
service = "api"
protocol が auto の場合、ポートありの対象は TCP、ポートなしの対象は ICMP を使います。UDP は現在 Linux のみ対応しており、DataKit に raw ICMP 応答を受信する権限が必要です。TCP/ICMP traceroute の有効な max_ttl 上限は 60、Linux UDP traceroute の上限は 255 です。
traceroute_queries は、完全な traceroute を実行する回数を表します。各実行では TTL 1 から対象または max_ttl までを独立にプローブし、同じ TTL で複数回再試行するのではなく、message.runs[] の要素を 1 つ生成します。対象がドメイン名の場合、各 run は独立して DNS 解決を行います。実際の対象 IP は runs[].destination.ip_address に書き込まれ、1 回のタスクでドメイン名のすべての IP を網羅する保証はありません。
e2e_queries は独立したエンドツーエンド probe の回数を表し、デフォルトは 10 です。E2E は中間 hop を確認せず、traceroute と並行して実行されます。TCP は接続応答、ICMP は Echo Reply、Linux UDP は宛先からの ICMP 応答を使用します。E2E の送信パケットは通常のエンドツーエンド IP TTL を使い、traceroute の max_ttl は使いません。ドメイン名は E2E 用に別途解決され、選ばれたアドレスは e2e_dest_ip に書き込まれます。これは message.runs[].destination.ip_address と異なる場合があります。UDP アプリケーションの無応答は e2e_unknown に記録され、直接 loss として扱われません。
動的対象¶
動的対象 API のデフォルトは POST /v1/netpath/candidates です。dynamic.enabled はデフォルトで有効です。DataKit の HTTP リスニングアドレスがホスト外に公開される場合は、空でない dynamic.token を設定し、呼び出し元は X-Datakit-Netpath-Token リクエストヘッダで同じトークンを渡す必要があります。
動的候補に hostname がある場合は hostname で重複排除してプローブし、ない場合は IP を使用して ttl の有効期間中、interval 周期で実行します。同じ非 NAT hostname に対する異なる観測 IP は 1 つのスケジューリングタスクを共有します。宛先アドレス変換が発生した場合、元の宛先 IP とポートもタスク識別に追加で使われます。動的タスクの context、キュー、レート、worker の制限は、設定済みの静的対象を占有したり破棄したりしません。monitor_ip_without_domain = false を維持し、トラフィックを増やす前に dynamic.filters でプローブ不要な namespace、セグメント、ポートを除外して、高カーディナリティなパスを発生させないことを推奨します。
hostname 候補については、各 DNS 解決後、traceroute または E2E の送信前に、解決結果を使って宛先 host と CIDR のフィルタ規則を再確認します。候補のアイデンティティフィールドは 1 項目あたり最大 1024 bytes です。リクエスト単位のデフォルト値を含めると、各 test のアイデンティティフィールド合計は最大 4096 bytes です。各候補のリクエスト単位 tags と test 単位 tags の合計は最大 64 個です。tag key の長さは最大 128 bytes、value の長さは最大 1024 bytes です。traceroute_status、traceroute_fail_type、エンドポイントの 4 組などの固定プロトコルフィールドは、カスタム tags で上書きできません。
datakit-ebpf による動的検出には、eBPF 収集器側でも次を有効にする必要があります。
[inputs.ebpf]
network_path_enabled = true
network_path_api = "http://127.0.0.1:9529/v1/netpath/candidates"
network_path_token = ""
逆引き DNS¶
Reverse DNS はデフォルトで無効です。有効にすると、DataKit は宛先 IP と応答のあった hop IP に対して PTR クエリを実行し、TTL cache で重複クエリを抑制します。
データ構造¶
1 件の結果の tags は、タスク、送信元、宛先、パスの絞り込みに使われ、主に次を含みます。
- タスク:
task_name、task_source、origin、run_type、protocol - 4 組:
src_ip、src_port、dst_ip、dst_port。DNAT が発生した場合はdst_nat_ip、dst_nat_portもあります。 - エンドポイントのコンテキスト:
dst_domain、source_host、source_service、source_process、source_container_id、src_cloud_provider、dst_cloud_provider - 実際のプローブ出口:
probe_source_ip、probe_gateway_ip、probe_interface、probe_netns - 状態:
traceroute_protocol、traceroute_status、traceroute_fail_type、e2e_status
送信元・宛先 tags は各 hop の結果に依存しません。4 組の命名は NetFlow に合わせています。dst_* は元の宛先、dst_nat_* は実際にプローブで使った DNAT 後の宛先を表します。未知のポートは "*" を使います。プローブで hop が生成されなくても、トップレベルのエンドポイントは検索に利用できます。エンドポイントの *_cloud_provider は任意のクラウド事業者情報です。
NetPath は branch_key や path_key を送信しません。履歴の検索には、上記の構造化されたタスク、送信元、宛先 tags を使用してください。実際のルーティング分岐とその変化は message.runs[].hops[] から計算します。
パス完了状態は traceroute_status(reached、partial、failed)を使います。これは traceroute が宛先に到達したかを表し、エンドツーエンド品質を意味するものではありません。
エンドツーエンド品質は、独立した e2e_* fields で統一して扱います。
e2e_dest_ip:E2E probe が独立に解決して実際に使用した IPv4 アドレスe2e_packets_sent、e2e_packets_received、e2e_unknown:probe の送信数、応答数、不確定結果数e2e_probe_loss_percent:判定可能な probe のうち応答がなかった割合。曖昧な UDP 無応答は分母に入りませんe2e_rtt_avg、e2e_rtt_min、e2e_rtt_max:エンドツーエンド RTT、単位はマイクロ秒e2e_rtt_variation_avg、e2e_rtt_variation_max:送信順で隣接する成功 probe 間の RTT 絶対差、単位はマイクロ秒
フロントエンドは e2e_rtt_avg でパス全体の遅延を表示し、e2e_probe_loss_percent でエンドツーエンド probe の無応答率を表示すべきです。e2e_status と traceroute_status は独立しています。TCP の connection refused/RST は宛先到達を証明するため received に含めます。e2e_probe_loss_percent は中間装置の実際のロス率ではありません。
各 hop のパス¶
完全なパスは message field に標準 JSON として書き込まれます。
{
"runs": [
{
"run_id": "1",
"destination": {
"ip_address": "8.8.8.8",
"port": 443,
"reverse_dns": ["dns.google"]
},
"hops": [
{
"ttl": 1,
"ip_address": "10.0.0.1",
"reverse_dns": ["gateway.local"],
"rtt": 0.8315,
"reachable": true
},
{
"ttl": 2,
"reachable": false
},
{
"ttl": 3,
"ip_address": "8.8.8.8",
"rtt": 12.45,
"reachable": true,
"asn": 15169,
"as_name": "GOOGLE",
"as_prefix": "8.8.8.0/24",
"cloud_provider": "gcp"
}
]
}
],
"hop_count": {
"avg": 3,
"min": 3,
"max": 3
}
}
フィールド説明:
| フィールド | 型 | 説明 |
|---|---|---|
runs[].run_id |
string | message 内における 1 回の traceroute の順序 ID。 |
runs[].destination.ip_address |
string | この run で実際にプローブした対象の IPv4。 |
runs[].destination.port |
uint16 | TCP/UDP 対象ポート。 |
runs[].destination.reverse_dns |
string[] | ドメイン対象で使われた hostname。 |
runs[].hops[].ttl |
int | hop 番号。 |
runs[].hops[].reachable |
bool | この TTL probe に応答があったかどうか。 |
runs[].hops[].ip_address |
string | hop IP。応答がない場合は省略され、"*" のプレースホルダは使いません。 |
runs[].hops[].reverse_dns |
string[] | 任意の逆引き DNS 名。 |
runs[].hops[].rtt |
number | この TTL probe の往復時間、単位はミリ秒。隣接 hop 間の所要時間ではありません。 |
runs[].hops[].asn |
uint64 | Kodo がローカルのオフラインデータベースを使ってパブリック IP に付与した ASN。 |
runs[].hops[].as_name |
string | 任意の ASN 組織名。 |
runs[].hops[].as_prefix |
string | 任意の ASN ネットワークプレフィックス。 |
runs[].hops[].cloud_provider |
string | Kodo がローカルの IP 帰属データベースを使って付与した任意のクラウド事業者。 |
hop_count.avg/min/max |
number | 複数回の traceroute における hop 数の統計。 |
ASN とクラウド事業者のフィールドは、サーバー側の任意の富化情報です。プライベートネットワーク、CGNAT、無応答 hop、データベース欠落、または照合不能の場合は、該当フィールドは表示されません。富化処理は第三者サービスに hop IP を送信せず、as_name からクラウド事業者を推測もしません。
プローブがパス生成前に失敗した場合、message は JSON ではなくエラーテキストになることがあります。その場合は traceroute_status=failed、traceroute_fail_type、traceroute_fail_reason を組み合わせて処理してください。
Warning
reachable=false は、その TTL probe が応答を受け取れなかったことを示すだけで、機器のポリシーや ICMP レート制限が原因の可能性があります。該当 hop の実際のネットワークロスを直接意味するものではありません。hop ごとに probe_count、response_count、timeout_count は送信しません。
ログ¶
netpath¶
| Tags & Fields | 説明 |
|---|---|
| dst_cloud_provider ( tag) |
利用可能な場合の宛先エンドポイントに関連付けられたクラウド事業者。 |
| dst_domain ( tag) |
設定済みまたは検出された宛先ドメイン。 |
| dst_ip ( tag) |
トラフィックソースが観測した元の宛先 IP。netflow と整合。 |
| dst_nat_ip ( tag) |
DNAT がある場合に probe で使われる変換後の宛先 IP。netflow と整合。 |
| dst_nat_port ( tag) |
DNAT がある場合に probe で使われる変換後の宛先ポート。netflow と整合。 |
| dst_port ( tag) |
元の宛先ポート。利用できない場合は *。netflow と整合。 |
| e2e_status ( tag) |
エンドツーエンド状態。reached、partial、unknown、failed。 |
| namespace ( tag) |
送信元 namespace。 |
| netns ( tag) |
Linux network namespace。 |
| origin ( tag) |
元の送信元名。例: config、ebpf_netflow。 |
| probe_gateway_ip ( tag) |
アクティブ probe に使われた経路が選択した次 hop の gateway。 |
| probe_interface ( tag) |
アクティブ probe に使われた経路が選択した outbound interface。 |
| probe_interface_mac ( tag) |
アクティブ probe で使われた outbound interface の MAC address。 |
| probe_netns ( tag) |
アクティブ probe の network namespace。 |
| probe_source_ip ( tag) |
アクティブ probe に使われた経路が選択した送信元 IP。 |
| protocol ( tag) |
probe protocol。 |
| run_type ( tag) |
実行タイプ。scheduled、on_demand、dynamic。 |
| source_container_id ( tag) |
送信元 container ID。 |
| source_host ( tag) |
候補を検出した送信元 host。 |
| source_process ( tag) |
送信元 process 名。 |
| source_service ( tag) |
送信元 service 名。 |
| src_cloud_provider ( tag) |
利用可能な場合の送信元エンドポイントに関連付けられたクラウド事業者。 |
| src_ip ( tag) |
トラフィックソースが観測した送信元 IP。netflow と整合。 |
| src_port ( tag) |
トラフィックソースが観測した送信元ポート。利用できない場合は *。netflow と整合。 |
| task_name ( tag) |
probe task 名。 |
| task_source ( tag) |
task source。local、server、dynamic。 |
| traceroute_fail_type ( tag) |
正規化された traceroute failure type。例: timeout、dns_error、permission、protocol_unsupported、target_unreachable、runner_error。 |
| traceroute_protocol ( tag) |
traceroute probe の生成に使った protocol。 |
| traceroute_status ( tag) |
traceroute status。例: reached、partial、failed。 |
| dst_reverse_dns | reverse_dns が有効な場合の宛先 IP の reverse DNS 名。 Type: string | (string) Unit: N/A |
| duration | probe 実行時間。 Type: int | (gauge) Unit: time,μs |
| e2e_dest_ip | エンドツーエンド probe で使われた IPv4 address。 Type: string | (string) Unit: N/A |
| e2e_fail_reason | エンドツーエンド probe の設定または実行失敗理由。 Type: string | (string) Unit: N/A |
| e2e_packets_received | 識別可能な宛先応答の受信数。 Type: int | (gauge) Unit: count |
| e2e_packets_sent | 送信されたエンドツーエンド probe 数。 Type: int | (gauge) Unit: count |
| e2e_probe_loss_percent | 識別可能な応答がなかった確定 probe の割合。曖昧な UDP の無応答は除外されます。 Type: float | (gauge) Unit: percent,percent |
| e2e_queries | 設定された独立エンドツーエンド probe 数。 Type: int | (gauge) Unit: count |
| e2e_rtt_avg | 受信応答全体のエンドツーエンド往復時間の平均。 Type: float | (gauge) Unit: time,μs |
| e2e_rtt_max | エンドツーエンド往復時間の最大値。 Type: float | (gauge) Unit: time,μs |
| e2e_rtt_min | エンドツーエンド往復時間の最小値。 Type: float | (gauge) Unit: time,μs |
| e2e_rtt_variation_avg | 連続する成功 probe 間の RTT 絶対差の平均。 Type: float | (gauge) Unit: time,μs |
| e2e_rtt_variation_max | 連続する成功 probe 間の RTT 絶対差の最大値。 Type: float | (gauge) Unit: time,μs |
| e2e_rtt_variation_samples | RTT 変動に使われた連続成功 probe ペア数。 Type: int | (gauge) Unit: count |
| e2e_tcp_connection_refused | connection refusal で応答した TCP probe 数。これらもエンドポイント到達を証明します。 Type: int | (gauge) Unit: count |
| e2e_unknown | 無音の UDP アプリケーションなど、結果が曖昧な probe 数。 Type: int | (gauge) Unit: count |
| hop_count | traceroute hop 数。 Type: int | (gauge) Unit: count |
| max_ttl | protocol 制限を反映した traceroute の有効最大 TTL。 Type: int | (gauge) Unit: count |
| message | 正規化された traceroute JSON、またはパスがない場合の失敗メッセージ。 Type: string | (string) Unit: N/A |
| scheduled_at | Unix マイクロ秒単位のスケジュール実行時刻。 Type: int | (gauge) Unit: timeStamp,usec |
| source_pid | 候補ソースが報告した送信元 process ID。 Type: int | (gauge) Unit: N/A |
| started_at | Unix マイクロ秒単位の probe 開始時刻。 Type: int | (gauge) Unit: timeStamp,usec |
| test_run_id | DataKit が生成した probe run ID。 Type: string | (string) Unit: N/A |
| traceroute_fail_reason | traceroute の設定または実行失敗理由。 Type: string | (string) Unit: N/A |
| traceroute_queries | 設定された完全 traceroute 実行回数。 Type: int | (gauge) Unit: count |
セキュリティとプライバシー¶
- DataKit は NetPath の結果とともに traceroute で観測した hop IP を送信します。これはパス表示の基礎データです。
- DataKit は hop IP を外部の ASN 照会サービスに送信しません。ASN は Kodo 内でオフラインデータベースを使って富化されます。
- Reverse DNS は DataKit があるネットワーク内から DNS クエリを発行します。DNS 露出が機微な場合は無効のままにしてください。
- 元の hop IP を顧客ネットワークの外へ出してはいけない場合は、導入前に NetPath の有効化を評価してください。ASN 富化だけを Kodo に移しても、観測プラットフォームへ送られる元の IP は隠れません。
トラブルシューティング¶
| 現象 | 確認項目 |
|---|---|
| Candidate API が HTTP 401 を返す | リクエストトークンは dynamic.token と一致している必要があります。 |
| Candidate API が HTTP 404 を返す | dynamic.enabled が無効になっていないか確認してください。 |
ip_without_domain |
hostname を指定するか、monitor_ip_without_domain を明示的に有効にしてください。 |
traceroute_fail_type=permission |
ICMP/UDP traceroute に必要な raw socket 権限を付与してください。 |
| パスが一部の hops しかない | traceroute_status=partial を確認してください。中間装置が TTL probe に応答しない場合があります。 |
| ASN がない | Kodo に ASN/ISP MMDB がデプロイされているか確認してください。プライベートネットワークと無応答 hop には ASN は付きません。 |