监控被阻止和直通的外部服务流量
如何使用 Istio 监控被阻止和直通的外部流量。
了解、控制和保护您的外部服务访问是您从 Istio 等服务网格获得的主要优势之一。从安全和运营角度来看,监控被阻止的外部服务流量至关重要,因为它们可能会暴露可能的错误配置或安全漏洞,例如如果应用程序尝试与它不应该被允许访问的服务通信。类似地,如果您目前有一个允许任何外部服务访问的策略,那么监控流量将有助于您逐步添加显式 Istio 配置以允许访问并更好地保护您的集群。无论哪种情况,通过遥测获得对该流量的可视性都非常有帮助,因为它使您能够创建警报和仪表板,并更好地推理您的安全态势。这是 Istio 生产用户强烈要求的功能,我们很高兴在 1.3 版本中添加了对该功能的支持。
为了实现这一点,Istio 默认指标 已通过显式标签进行扩充,以捕获被阻止和直通的外部服务流量。本博文将介绍如何使用这些扩充的指标来监控所有外部服务流量。
Istio 控制平面使用名为 BlackHoleCluster 和 Passthrough 的预定义集群来配置 sidecar 代理,分别阻止或允许所有流量。为了了解这些集群,让我们从 Istio 服务网格中外部服务和内部服务意味着什么开始。
外部服务和内部服务
内部服务被定义为属于您的平台且被认为在网格中的服务。对于内部服务,Istio 控制平面默认情况下会向 sidecar 提供所有必需的配置。例如,在 Kubernetes 集群中,Istio 会为所有 Kubernetes 服务配置 sidecar,以保留所有服务能够相互通信的默认 Kubernetes 行为。
外部服务是指不属于您的平台的服务,即在网格之外的服务。对于外部服务,Istio 提供两种选择,一是阻止所有外部服务访问(通过将 global.outboundTrafficPolicy.mode
设置为 REGISTRY_ONLY
来启用),二是允许对外部服务的所有访问(通过将 global.outboundTrafficPolicy.mode
设置为 ALLOW_ANY
来启用)。此设置的默认选项(截至 Istio 1.3)是允许所有外部服务访问。此选项可以通过 网格配置 进行配置。
这就是 BlackHole 和 Passthrough 集群的使用场景。
什么是 BlackHole 和 Passthrough 集群?
BlackHoleCluster - BlackHoleCluster 是在 Envoy 配置中创建的虚拟集群,当
global.outboundTrafficPolicy.mode
设置为REGISTRY_ONLY
时。在这种模式下,除非明确添加了每个服务的 服务条目,否则对外部服务的任何流量都会被阻止。为了实现这一点,默认的虚拟出站侦听器在0.0.0.0:15001
使用 原始目标,被设置为使用 BlackHoleCluster 作为静态集群的 TCP 代理。BlackHoleCluster 的配置如下所示{ "name": "BlackHoleCluster", "type": "STATIC", "connectTimeout": "10s" }
如您所见,此集群是静态的,没有端点,因此所有流量都会被丢弃。此外,Istio 为平台服务的每个端口/协议组合创建唯一的侦听器,如果请求发送到同一端口上的外部服务,则会命中该侦听器,而不是虚拟侦听器。在这种情况下,Envoy 中每个虚拟路由的路由配置都将增加以添加 BlackHoleCluster,如下所示
{ "name": "block_all", "domains": [ "*" ], "routes": [ { "match": { "prefix": "/" }, "directResponse": { "status": 502 } } ] }
该路由被设置为 直接响应,响应代码为
502
,这意味着如果没有其他路由匹配,Envoy 代理将直接返回502
HTTP 状态代码。PassthroughCluster - PassthroughCluster 是在 Envoy 配置中创建的虚拟集群,当
global.outboundTrafficPolicy.mode
设置为ALLOW_ANY
时。在这种模式下,允许对任何外部服务的任何流量。为了实现这一点,默认的虚拟出站侦听器在0.0.0.0:15001
使用SO_ORIGINAL_DST
,被设置为使用 PassthroughCluster 作为静态集群的 TCP 代理。PassthroughCluster 的配置如下所示{ "name": "PassthroughCluster", "type": "ORIGINAL_DST", "connectTimeout": "10s", "lbPolicy": "ORIGINAL_DST_LB", "circuitBreakers": { "thresholds": [ { "maxConnections": 102400, "maxRetries": 1024 } ] } }
此集群使用 原始目标负载均衡 策略,该策略配置 Envoy 将流量发送到原始目标,即直通。
与 BlackHoleCluster 类似,对于每个基于端口/协议的侦听器,虚拟路由配置都会增加以添加 PassthroughCluster 作为默认路由
{ "name": "allow_any", "domains": [ "*" ], "routes": [ { "match": { "prefix": "/" }, "route": { "cluster": "PassthroughCluster" } } ] }
在 Istio 1.3 之前,没有报告指标,或者如果报告指标,则在流量命中这些集群时没有设置显式标签,导致缺乏对流经网格的流量的可视性。
下一节将介绍如何利用这种增强功能,因为发出的指标和标签取决于是否命中虚拟出站或显式端口/协议侦听器。
使用扩充的指标
为了捕获两种情况下(BlackHole 或 Passthrough)的所有外部服务流量,您需要监控 istio_requests_total
和 istio_tcp_connections_closed_total
指标。根据被调用的 Envoy 侦听器类型,即 TCP 代理或 HTTP 代理,其中一个指标将被递增。
此外,在 TCP 代理侦听器的情况下,为了查看通过 BlackHole 或 Passthrough 集群被阻止或允许的外部服务的 IP 地址,您需要将 destination_ip
标签添加到 istio_tcp_connections_closed_total
指标。在这种情况下,不会捕获外部服务的主机名。此标签默认情况下不会添加,可以通过扩展 Istio 配置以生成属性和 Prometheus 处理程序来轻松添加。如果您有许多服务且 IP 地址不稳定,则应注意时间序列中的基数爆炸问题。
PassthroughCluster 指标
本节解释了基于 Envoy 中调用的侦听器类型发出的指标和标签。
HTTP 代理侦听器:当外部服务的端口与集群中定义的服务端口之一相同,就会发生这种情况。在这种情况下,当 PassthroughCluster 被命中时,
istio_requests_total
会像这样增加{ "metric": { "__name__": "istio_requests_total", "connection_security_policy": "unknown", "destination_app": "unknown", "destination_principal": "unknown", "destination_service": "httpbin.org", "destination_service_name": "PassthroughCluster", "destination_service_namespace": "unknown", "destination_version": "unknown", "destination_workload": "unknown", "destination_workload_namespace": "unknown", "instance": "100.96.2.183:42422", "job": "istio-mesh", "permissive_response_code": "none", "permissive_response_policyid": "none", "reporter": "source", "request_protocol": "http", "response_code": "200", "response_flags": "-", "source_app": "sleep", "source_principal": "unknown", "source_version": "unknown", "source_workload": "sleep", "source_workload_namespace": "default" }, "value": [ 1567033080.282, "1" ] }
请注意,
destination_service_name
标签设置为 PassthroughCluster,以指示命中了此集群,并且destination_service
设置为外部服务的主机。TCP 代理虚拟侦听器 - 如果外部服务端口不映射到集群中的任何基于 HTTP 的服务端口,则会调用此侦听器,并且
istio_tcp_connections_closed_total
是将被递增的指标{ "status": "success", "data": { "resultType": "vector", "result": [ { "metric": { "__name__": "istio_tcp_connections_closed_total", "connection_security_policy": "unknown", "destination_app": "unknown", "destination_ip": "52.22.188.80", "destination_principal": "unknown", "destination_service": "unknown", "destination_service_name": "PassthroughCluster", "destination_service_namespace": "unknown", "destination_version": "unknown", "destination_workload": "unknown", "destination_workload_namespace": "unknown", "instance": "100.96.2.183:42422", "job": "istio-mesh", "reporter": "source", "response_flags": "-", "source_app": "sleep", "source_principal": "unknown", "source_version": "unknown", "source_workload": "sleep", "source_workload_namespace": "default" }, "value": [ 1567033761.879, "1" ] } ] } }
在这种情况下,
destination_service_name
设置为 PassthroughCluster,destination_ip
设置为外部服务的 IP 地址。destination_ip
标签可用于执行反向 DNS 查询并获取外部服务的主机名。由于此集群是直通的,因此其他与 TCP 相关的指标,如istio_tcp_connections_opened_total
、istio_tcp_received_bytes_total
和istio_tcp_sent_bytes_total
也会更新。
BlackHoleCluster 指标
与 PassthroughCluster 类似,本节解释了基于 Envoy 中调用的侦听器类型发出的指标和标签。
HTTP 代理侦听器:当外部服务的端口与集群中定义的服务端口之一相同,就会发生这种情况。在这种情况下,当 BlackHoleCluster 被命中时,
istio_requests_total
会像这样增加{ "metric": { "__name__": "istio_requests_total", "connection_security_policy": "unknown", "destination_app": "unknown", "destination_principal": "unknown", "destination_service": "httpbin.org", "destination_service_name": "BlackHoleCluster", "destination_service_namespace": "unknown", "destination_version": "unknown", "destination_workload": "unknown", "destination_workload_namespace": "unknown", "instance": "100.96.2.183:42422", "job": "istio-mesh", "permissive_response_code": "none", "permissive_response_policyid": "none", "reporter": "source", "request_protocol": "http", "response_code": "502", "response_flags": "-", "source_app": "sleep", "source_principal": "unknown", "source_version": "unknown", "source_workload": "sleep", "source_workload_namespace": "default" }, "value": [ 1567034251.717, "1" ] }
请注意,
destination_service_name
标签设置为 BlackHoleCluster,并且destination_service
设置为外部服务的主机名。在这种情况下,响应代码始终应为502
。TCP 代理虚拟侦听器 - 如果外部服务端口不映射到集群中的任何基于 HTTP 的服务端口,则会调用此侦听器,并且
istio_tcp_connections_closed_total
是将被递增的指标{ "metric": { "__name__": "istio_tcp_connections_closed_total", "connection_security_policy": "unknown", "destination_app": "unknown", "destination_ip": "52.22.188.80", "destination_principal": "unknown", "destination_service": "unknown", "destination_service_name": "BlackHoleCluster", "destination_service_namespace": "unknown", "destination_version": "unknown", "destination_workload": "unknown", "destination_workload_namespace": "unknown", "instance": "100.96.2.183:42422", "job": "istio-mesh", "reporter": "source", "response_flags": "-", "source_app": "sleep", "source_principal": "unknown", "source_version": "unknown", "source_workload": "sleep", "source_workload_namespace": "default" }, "value": [ 1567034481.03, "1" ] }
请注意,
destination_ip
标签表示外部服务的 IP 地址,destination_service_name
设置为 BlackHoleCluster,以指示此流量被网格阻止。值得注意的是,对于 BlackHole 集群情况,其他与 TCP 相关的指标,如istio_tcp_connections_opened_total
不会增加,因为没有建立连接。
监控这些指标可以帮助运营商轻松了解集群中应用程序使用的所有外部服务。