跳到主要内容

使用 Cilium + CLS 实现网络流日志审计

概述

Cilium 的 cilium-agent 可以将网络流日志(Hubble Flows)写到文件中,它记录了集群中每一条网络连接的详细元数据,包括源/目标 Pod、IP、端口、协议、策略裁决(允许/拒绝)等信息。

网络流日志的常见使用场景包括:

  • 安全审计:记录所有网络连接,满足合规要求,追溯异常访问。
  • 故障排查:通过检索特定 Pod 或 IP 的网络流日志,快速定位网络不通、连接超时等问题。
  • 网络策略验证:查看哪些流量被 NetworkPolicy 拒绝(verdict=DROPPED),验证策略是否符合预期。
  • 流量分析:分析集群内外的流量模式,识别异常流量。

本文介绍如何将 Cilium 的网络流日志导出到文件,并借助腾讯云 CLS 日志服务进行采集和检索分析。

整体架构

整体数据流转如下:

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│ Hubble │ │ Export to │ │ CLS Agent │ │ CLS Search │
│ Server │───▶│ Log Files │───▶│ Collect │───▶│ & Analyze │
│ (per node) │ │ (cilium pod) │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
  • Hubble Server:内置在每个节点的 cilium-agent 中,默认开启,负责观测和记录网络流日志。
  • 日志导出:通过 Hubble 的动态导出功能,将网络流日志写入 cilium pod 内的本地文件。
  • CLS Agent:TKE 的日志采集组件,负责从 cilium pod 中采集日志文件并上报到 CLS。
  • CLS 检索分析:在 CLS 控制台中对网络流日志进行检索、过滤和分析。

将网络流日志导出到文件

基本配置

启用 Hubble 动态日志导出并配置导出规则:

helm upgrade cilium cilium/cilium --version 1.19.1 \
--namespace kube-system \
--reuse-values \
--set hubble.enabled=true \
--set hubble.export.dynamic.enabled=true \
--set hubble.export.dynamic.config.content[0].name=all \
--set hubble.export.dynamic.config.content[0].filePath=/var/run/cilium/hubble/events-all.log \
--set hubble.export.dynamic.config.content[0].excludeFilters[0].source_ip[0]=169.254.0.71 \
--set hubble.export.dynamic.config.content[0].excludeFilters[1].destination_ip[0]=169.254.0.71

以上配置的含义是:

  • 导出所有网络流日志到 /var/run/cilium/hubble/events-all.log 文件。
  • 排除源 IP 或目标 IP 为 169.254.0.71 的流量(这是 CLS API 地址,排除的原因见常见问题中的excludeFilters 为什么要加 169.254.0.71?)。

导出配置详解

Hubble 支持静态导出动态导出两种方式:

对比项静态导出动态导出
启用方式hubble.export.static.enabled=truehubble.export.dynamic.enabled=true
规则数量仅支持一组过滤规则支持多组规则,各自导出到不同文件
配置变更需要重启 cilium pod无需重启,修改 ConfigMap 后自动生效
过滤语法allowList / denyListincludeFilters / excludeFilters

推荐使用动态导出,它更灵活,支持多规则配置,且修改配置后无需重启 pod。

过滤器

includeFiltersexcludeFilters 完整的过滤器字段列表参考源码 flow.proto 中的 FlowFilter meesage 定义,以下是常用字段:

字段说明示例
source_pod源 Pod(格式:namespace/pod-name["kube-system/coredns"]
destination_pod目标 Pod["default/nginx"]
source_ip源 IP["10.0.1.100"]
destination_ip目标 IP["10.0.2.200"]
verdict策略裁决["DROPPED"]["FORWARDED"]
event_type事件类型[{"type": 1}]

同一个 filter 对象中的多个字段为 AND 关系,同一数组中的多个 filter 对象为 OR 关系。

fieldMask(字段裁剪)

如果不需要导出所有字段,可以使用 fieldMask 只保留需要的字段,减少日志体积:

helm upgrade cilium cilium/cilium --version 1.19.1 \
--namespace kube-system \
--reuse-values \
--set hubble.enabled=true \
--set hubble.export.dynamic.enabled=true \
--set hubble.export.dynamic.config.content[0].name=dropped \
--set hubble.export.dynamic.config.content[0].filePath=/var/run/cilium/hubble/dropped.log \
--set hubble.export.dynamic.config.content[0].includeFilters[0].verdict[0]=DROPPED \
--set hubble.export.dynamic.config.content[0].fieldMask[0]=time \
--set hubble.export.dynamic.config.content[0].fieldMask[1]=source.namespace \
--set hubble.export.dynamic.config.content[0].fieldMask[2]=source.pod_name \
--set hubble.export.dynamic.config.content[0].fieldMask[3]=destination.namespace \
--set hubble.export.dynamic.config.content[0].fieldMask[4]=destination.pod_name \
--set hubble.export.dynamic.config.content[0].fieldMask[5]=IP \
--set hubble.export.dynamic.config.content[0].fieldMask[6]=l4 \
--set hubble.export.dynamic.config.content[0].fieldMask[7]=verdict \
--set hubble.export.dynamic.config.content[0].fieldMask[8]=drop_reason_desc

以上配置只导出被 DROP 的流量,且只保留时间、源/目标 Pod、IP、四层协议、裁决结果和丢包原因这些关键字段。

fieldMask 的字段路径使用点号(.)分隔嵌套字段,完整的可用字段列表基于 flow.proto 中的 Flow message 定义,以下是常用字段:

字段路径说明
time流量发生的时间
verdict策略裁决(FORWARDED / DROPPED / ERROR)
drop_reason_desc丢包原因描述
IP完整的 IP 信息(含源/目标 IP)
IP.source源 IP
IP.destination目标 IP
l4完整的四层协议信息
l4.TCP.source_portTCP 源端口
l4.TCP.destination_portTCP 目标端口
l4.UDP.source_portUDP 源端口
l4.UDP.destination_portUDP 目标端口
source完整的源端点信息
source.namespace源 Pod 所在 Namespace
source.pod_name源 Pod 名称
source.labels源端点的标签
source.identity源端点的 Cilium Identity
source.workloads源端点的 Workload 信息
destination完整的目标端点信息
destination.namespace目标 Pod 所在 Namespace
destination.pod_name目标 Pod 名称
destination.labels目标端点的标签
destination.identity目标端点的 Cilium Identity
destination.workloads目标端点的 Workload 信息
node_name节点名称
node_labels节点标签
is_reply是否为回复包
traffic_direction流量方向(INGRESS / EGRESS)
trace_reason追踪原因
event_type事件类型
source_service.name源 Service 名称
source_service.namespace源 Service 所在 Namespace
destination_service.name目标 Service 名称
destination_service.namespace目标 Service 所在 Namespace
l7七层协议信息(DNS/HTTP 等)
l7.dnsDNS 请求/响应信息
l7.httpHTTP 请求/响应信息
interface网络接口信息
Summary流量摘要(已废弃)

多规则配置

动态导出支持同时配置多组规则,每组规则可以导出到不同的文件,适用于按场景分类导出:

helm upgrade cilium cilium/cilium --version 1.19.1 \
--namespace kube-system \
--reuse-values \
--set hubble.enabled=true \
--set hubble.export.dynamic.enabled=true \
--set hubble.export.dynamic.config.content[0].name=all \
--set hubble.export.dynamic.config.content[0].filePath=/var/run/cilium/hubble/events-all.log \
--set hubble.export.dynamic.config.content[0].excludeFilters[0].source_ip[0]=169.254.0.71 \
--set hubble.export.dynamic.config.content[0].excludeFilters[1].destination_ip[0]=169.254.0.71 \
--set hubble.export.dynamic.config.content[1].name=dropped \
--set hubble.export.dynamic.config.content[1].filePath=/var/run/cilium/hubble/dropped.log \
--set hubble.export.dynamic.config.content[1].includeFilters[0].verdict[0]=DROPPED

以上配置定义了两组规则:

  • all:导出所有流量(排除 CLS API 地址)。
  • dropped:只导出被拒绝的流量,方便快速定位 NetworkPolicy 相关问题。

日志轮转

导出的日志文件会自动轮转,可通过以下参数配置:

参数说明默认值
hubble.export.fileMaxSizeMb单个日志文件的最大大小(MB)10
hubble.export.fileMaxBackups保留的轮转文件数量5
hubble.export.fileCompress是否压缩轮转后的文件false

如果日志量较大,可以适当调大文件大小和备份数量:

helm upgrade cilium cilium/cilium --version 1.19.1 \
--namespace kube-system \
--reuse-values \
--set hubble.export.fileMaxSizeMb=50 \
--set hubble.export.fileMaxBackups=10 \
--set hubble.export.fileCompress=true

日志格式说明

导出的日志每行是一个 JSON 对象,包含完整的网络流日志信息。以下是一条示例日志(已格式化)—— test 命名空间中的 curl Pod 向 nginx Pod 发起 HTTP 请求:

{
"flow": {
"IP": {
"destination": "10.20.0.9",
"ipVersion": "IPv4",
"source": "10.20.0.10"
},
"Summary": "TCP Flags: ACK",
"Type": "L3_L4",
"destination": {
"cluster_name": "default",
"identity": 27312,
"labels": [
"k8s:app=nginx",
"k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=test",
"k8s:io.cilium.k8s.policy.cluster=default",
"k8s:io.cilium.k8s.policy.serviceaccount=default",
"k8s:io.kubernetes.pod.namespace=test"
],
"namespace": "test",
"pod_name": "nginx-54c98b4f84-sw9q9"
},
"emitter": {
"name": "Hubble",
"version": "1.19.1+gd0d0c879"
},
"ethernet": {
"destination": "02:21:a9:ff:89:f4",
"source": "ce:0a:b9:d8:63:61"
},
"event_type": {
"sub_type": 3,
"type": 4
},
"is_reply": false,
"l4": {
"TCP": {
"destination_port": 80,
"flags": {
"ACK": true
},
"source_port": 56598
}
},
"node_labels": [
"beta.kubernetes.io/arch=amd64",
"beta.kubernetes.io/instance-type=S5.MEDIUM4",
"beta.kubernetes.io/os=linux",
"cloud.tencent.com/auto-scaling-group-id=asg-q9zxcooe",
"cloud.tencent.com/node-instance-id=ins-f5wpfrc5",
"failure-domain.beta.kubernetes.io/region=cd",
"failure-domain.beta.kubernetes.io/zone=160001",
"kubernetes.io/arch=amd64",
"kubernetes.io/hostname=10.10.21.35",
"kubernetes.io/os=linux",
"node.kubernetes.io/instance-type=S5.MEDIUM4",
"node.tke.cloud.tencent.com/accelerator-type=cpu",
"node.tke.cloud.tencent.com/cpu=2",
"node.tke.cloud.tencent.com/memory=4",
"os=tencentos4",
"tke.cloud.tencent.com/cbs-mountable=true",
"tke.cloud.tencent.com/nodepool-id=np-p8uyib3x",
"tke.cloud.tencent.com/route-eni-subnet-ids=subnet-fg9qdb1f",
"topology.com.tencent.cloud.csi.cbs/zone=ap-chengdu-1",
"topology.kubernetes.io/region=cd",
"topology.kubernetes.io/zone=160001"
],
"node_name": "10.10.21.35",
"source": {
"ID": 3863,
"cluster_name": "default",
"identity": 4368,
"labels": [
"k8s:app=curl",
"k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=test",
"k8s:io.cilium.k8s.policy.cluster=default",
"k8s:io.cilium.k8s.policy.serviceaccount=default",
"k8s:io.kubernetes.pod.namespace=test"
],
"namespace": "test",
"pod_name": "curl-7d4d858f75-j76f7",
"workloads": [
{
"kind": "Deployment",
"name": "curl"
}
]
},
"time": "2026-02-25T03:25:54.227004477Z",
"trace_observation_point": "TO_STACK",
"trace_reason": "ESTABLISHED",
"traffic_direction": "EGRESS",
"uuid": "a38e44fa-b7b7-4f8f-a40b-2c1dd2621140",
"verdict": "FORWARDED"
},
"node_name": "10.10.21.35",
"time": "2026-02-25T03:25:54.227004477Z"
}

关键字段说明:

字段说明
flow.time流量发生的时间
flow.verdict策略裁决:FORWARDED(放行)、DROPPED(拒绝)、ERROR(错误)
flow.IP源/目标 IP 地址
flow.l4四层协议信息(TCP/UDP 的端口、标志位等)
flow.source / flow.destination源/目标的 Pod 名称、命名空间、标签、workload 等
flow.traffic_direction流量方向:INGRESSEGRESS
flow.drop_reason_desc丢包原因描述(仅当 verdict 为 DROPPED 时有值)
flow.is_reply是否为回复包
flow.Summary流量摘要信息

启用七层日志

默认情况下,Hubble 只记录 L3/L4 层的网络流日志(IP、端口、协议等)。如果需要记录七层协议的详细信息(如 DNS 查询内容、HTTP 请求方法和 URL 等),需要通过 CiliumNetworkPolicy 配置 L7 规则来启用。

注意

启用 L7 可观测需要 L7 Proxy(Envoy)支持,Cilium 默认已部署 Envoy DaemonSet。匹配 L7 规则的流量会被重定向到 Envoy 代理进行解析,这会带来一定的性能开销。建议仅对需要审计的流量启用 L7 规则。

配置示例

以下 CiliumNetworkPolicy 对 default 命名空间的 Pod 启用 DNS 和 HTTP 的七层可观测:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "l7-visibility"
namespace: default
spec:
endpointSelector:
matchLabels: {}
egress:
- toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*"
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": default
toPorts:
- ports:
- port: "80"
protocol: TCP
- port: "8080"
protocol: TCP
rules:
http: [{}]

以上策略的含义:

  • DNS 规则:对所有 DNS 出口流量(TCP/UDP 53)启用七层可观测,使用 matchPattern: "*" 放行所有 DNS 查询。
  • HTTP 规则:对发往 default 命名空间 Pod 的 HTTP 出口流量(TCP 80/8080)启用七层可观测,使用 http: [{}] 放行所有 HTTP 请求。
注意

L7 规则不仅启用可观测,同时也会限制流量 —— 不匹配规则的流量将被拒绝。请根据实际需求配置规则,确保合法流量不被误拦截。

支持的七层协议

协议规则类型说明
DNSdns记录 DNS 查询域名、响应 IP、TTL 等。仅支持出口(egress)方向
HTTPhttp记录 HTTP 方法、URL、状态码、响应延迟等
Kafkakafka已废弃(deprecated)

L7 日志字段

启用七层可观测后,导出的网络流日志中 flow.l7 字段会包含七层协议的详细信息:

DNS 日志字段:

字段说明
l7.type流类型:REQUESTRESPONSE
l7.latency_ns响应延迟(纳秒)
l7.dns.queryDNS 查询的域名
l7.dns.ipsDNS 响应中的 IP 列表
l7.dns.ttlDNS 响应的 TTL
l7.dns.rcodeDNS 返回码(0=成功,3=NXDOMAIN 等)
l7.dns.qtypes查询类型(A、AAAA、CNAME 等)
l7.dns.rrtypes响应资源记录类型

HTTP 日志字段:

字段说明
l7.type流类型:REQUESTRESPONSE
l7.latency_ns响应延迟(纳秒)
l7.http.codeHTTP 状态码(如 200、404)
l7.http.methodHTTP 方法(GET、POST 等)
l7.http.url请求 URL
l7.http.protocolHTTP 协议版本(如 HTTP/1.1)
l7.http.headersHTTP 头信息(key/value 列表)

安全注意事项

L7 日志可能包含敏感信息(URL 中的查询参数、认证信息等)。Cilium 提供了脱敏配置:

helm upgrade cilium cilium/cilium --version 1.19.1 \
--namespace kube-system \
--reuse-values \
--set hubble.redact.enabled=true \
--set hubble.redact.http.urlQuery=true \
--set hubble.redact.http.userInfo=true
  • hubble.redact.http.urlQuery:脱敏 URL 中的查询参数。
  • hubble.redact.http.userInfo:脱敏 URL 中的用户认证信息。

将网络流日志投递到 CLS

配置 TKE 日志采集,将所有 cilium-agent 中的日志流文件采集到 CLS。

启用日志采集功能

在配置日志采集规则前,先确保集群开通了日志采集功能,控制台操作路径:监控告警>日志>业务日志

通过 YAML 配置(推荐)

TKE 使用 LogConfig 这个 CRD 配置日志采集规则,通过这种方式配置可以快捷配置索引,避免在控制台大量手动操作。参考以下 YAML 进行配置:

通过 kubectl apply -f <your-logconfig-yaml-file> 进行配置。

注意

需根据注释替换相关字段。

apiVersion: cls.cloud.tencent.com/v1
kind: LogConfig
metadata:
name: cilium-flow-logs
spec:
clsDetail:
region: ap-chengdu # 替换成你的 CLS 所在地域,可用列表参考 https://cloud.tencent.com/document/product/614/18940
logsetName: "TKE-cls-k398qwbj-102564" # 替换成你的 CLS 日志集名称。如果存在该名称的日志集,则会使用该日志集,如果不存在,则会新建一个该名称的日志集。
topicName: "tke-cls-k398qwbj-cilium-flow-logs" # 替换成你的 CLS 日志主题名称,自动创建出来的日志主题会使用该名称。
extractRule:
backtracking: "0"
isGBK: "false"
jsonStandard: "true"
timeFormat: '%Y-%m-%dT%H:%M:%S.%f%z'
timeKey: time
unMatchUpload: "true"
unMatchedKey: LogParseFailure
indexStatus: "on"
indexs:
- indexName: namespace
- indexName: pod_name
- indexName: container_name
- indexName: flow.verdict
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.uuid
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.drop_reason_desc
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.source.pod_name
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.source.namespace
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.source.cluster_name
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.source.labels
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.source.identity
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination.pod_name
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination.namespace
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination.cluster_name
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination.labels
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination.identity
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination_service.name
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.destination_service.namespace
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.IP.ipVersion
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.IP.source
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.IP.destination
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.l4
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.l7
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.l4.TCP.source_port
indexType: long
- indexName: flow.l4.TCP.destination_port
indexType: long
- indexName: flow.l4.UDP.source_port
indexType: long
containZH: false
- indexName: flow.l4.UDP.destination_port
indexType: long
- indexName: flow.event_type.type
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.event_type.sub_type
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.Summary
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.traffic_direction
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.trace_reason
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.is_reply
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.Type
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.node_labels
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
- indexName: flow.file
indexType: text
tokenizer: "@&?|#()='\",;:<>[]{}/ \n\t\r\\"
containZH: false
autoIndex: "true"
logFormat: default
logType: json_log
maxSplitPartitions: 0
period: 30
storageType: ""
inputDetail:
type: container_file
containerFile:
namespace: kube-system
workload:
kind: daemonset
name: cilium
container: cilium-agent
filePaths:
- file: '*.log'
path: /var/run/cilium/hubble
metadataContainer:
- namespace
- pod_name
- pod_ip
- pod_uid
- container_id
- container_name
- image_name
- cluster_id
metadataLabels:
- __NULL__
nodeMetadataLabels:
- __NULL__

通过控制台配置

如有必要,你也可以在 TKE 控制台配置日志采集规则,在 TKE 集群的 监控告警>日志>业务日志 下新建日志规则,部分配置参考截图:

CLS 检索示例

日志投递到 CLS 后,可以在 CLS 控制台进行各种维度的检索分析。以下是一些常用的检索语句:

查询某个 Pod 的所有网络流日志

flow.source.pod_name:"nginx-deployment-abc123" OR flow.destination.pod_name:"nginx-deployment-abc123"

查询被拒绝的流量

flow.verdict:"DROPPED"

查看详细的丢包原因:

flow.verdict:"DROPPED" | select flow.drop_reason_desc, flow.source.namespace, flow.source.pod_name, flow.destination.namespace, flow.destination.pod_name, count(*) as cnt group by flow.drop_reason_desc, flow.source.namespace, flow.source.pod_name, flow.destination.namespace, flow.destination.pod_name order by cnt desc

按命名空间过滤

查询从 default 命名空间发出的所有流量:

flow.source.namespace:"default"

查询发往 kube-system 命名空间的所有流量:

flow.destination.namespace:"kube-system"

按端口过滤

查询目标端口为 80 的流量:

flow.l4.TCP.destination_port:80

查询某个 IP 的所有流量

flow.IP.source:"10.0.1.100" OR flow.IP.destination:"10.0.1.100"

按流量方向过滤

只看入站流量:

flow.traffic_direction:"INGRESS"

相关产品

腾讯云网络流日志 FL 也提供了类似的网络流日志功能,它基于 VPC 层面采集流日志,与 Cilium Hubble 的网络流日志有以下区别:

对比项Cilium Hubble 网络流日志腾讯云网络流日志 FL
采集层级Pod 级别,基于 eBPFVPC 级别,基于弹性网卡
信息丰富度包含 Pod 名称、标签、Namespace、NetworkPolicy 裁决等 K8s 元数据,甚至还支持七层信息主要包含 IP、端口、协议等网络层信息
过滤能力支持按 Pod、标签、裁决等 K8s 维度过滤支持按 VPC、子网、弹性网卡过滤
适用场景Kubernetes 集群内网络可观测VPC 级别的网络流量审计

可根据实际需求选择使用,两者也可以互补:Cilium 提供 K8s 层面的精细化网络流日志,FL 提供 VPC 层面的全局网络流日志。

常见问题

Hubble 动态日志导出配置存到哪里的?

存在 kube-system/cilium-flowlog-config 这个 ConfigMap 中的,可以通过 kubectl 查看当前配置:

$ kubectl -n kube-system get cm cilium-flowlog-config -o yaml
apiVersion: v1
data:
flowlogs.yaml: |
flowLogs:
- excludeFilters:
- source_ip:
- 169.254.0.71
- destination_ip:
- 169.254.0.71
filePath: /var/run/cilium/hubble/events-all.log
name: all
kind: ConfigMap
metadata:
annotations:
meta.helm.sh/release-name: cilium
meta.helm.sh/release-namespace: kube-system
creationTimestamp: "2026-02-24T08:35:22Z"
labels:
app.kubernetes.io/managed-by: Helm
name: cilium-flowlog-config
namespace: kube-system
resourceVersion: "3969239884"
uid: 87978d03-638a-4c31-80d2-0a3e0fe17049

CLS 为什么没有自动创建日志主题?

确保 logsetNametopicName 都配置,且没有跟 topicName 同名的已有日志主题存在,也不要指定 topicIdlogsetId

哪里查看完整的 LogConfig 配置字段参考?

TKE 的日志采集规则 LogConfig 完整字段参考 LogConfig json 格式说明

excludeFilters 为什么要加 169.254.0.71?

169.254.0.71 是 CLS 的 API 地址的目标 IP,采集的日志最终会通过这个 IP 上报,如果没有指定 includeFilters,需加上这个 excludeFilters 避免将上报 CLS 日志的流量也作为 cilium 网络流日志记录下来,然后又采集这个日志,又上报,导致无限循环采集上报,即便在没有其他网络流量的情况下也会一直产生和采集新日志,造成不必要的开销。

参考资料