保护 Istio Sidecar 和网关的 Prometheus 数据抓取过程
本任务演示如何使用 Prometheus 通过 Istio mTLS 安全地抓取 Istio Sidecar 和网关的指标。 默认情况下,Prometheus 通过 HTTP 从 Istio 工作负载和网关抓取指标。 在本任务中,您将配置 Istio 和 Prometheus,以便通过加密连接安全地抓取指标。 本文档重点介绍 Sidecar 和网关公开的 Envoy 和 Istio 生成的遥测数据。 它不涵盖工作负载本身发出的应用程序级指标。 有关 Prometheus 与 Istio 集成的更多信息(包括应用程序指标), 请参阅 Prometheus 集成文档。
了解默认指标抓取机制
默认情况下,Istio 会在 /stats/prometheus 端点上公开指标:
- 工作负载指标通过 Sidecar 遥测端口(
15020)或仅限 Envoy 的端口(15090)提供。 - 网关指标通过网关 Pod 的遥测端口提供。
- 这些端点不受双向 TLS 保护,因此不建议直接通过 HTTPS 进行抓取。
此任务将默认抓取配置替换为安全的 mTLS 配置。
Prometheus 将使用安全的代理端口(15091),而不是直接访问遥测端口。
开始之前
- 使用默认配置文件在集群中安装 Istio(请参阅安装 Istio)。
安装 Prometheus 并启用安全抓取功能
为了实现安全的指标抓取,Prometheus 需要 Istio Sidecar 通过 mTLS 对工作负载和网关进行身份验证。
为 Prometheus 命名空间启用 Sidecar 注入功能。
$ kubectl create namespace prometheus $ kubectl label namespace monitoring istio-injection=enabled --overwrite这确保了任何创建或重启的 Prometheus Pod 都会自动包含一个
istio-proxy边车容器。更新 Prometheus Deployment 的 Pod 模板。
Istio 在
samples/addons/prometheus.yaml路径下提供了一个 Prometheus 示例安装文件。 修改samples/addons/prometheus.yaml文件, 为 Prometheus 部署添加注解,以启用 Sidecar 注入、挂载 Istio 证书并配置代理:apiVersion: apps/v1 kind: Deployment metadata: name: prometheus namespace: monitoring spec: template: metadata: annotations: sidecar.istio.io/inject: "true" sidecar.istio.io/userVolumeMount: | [{"name": "istio-certs", "mountPath": "/etc/istio-certs", "readOnly": true}] proxy.istio.io/config: | proxyMetadata: OUTPUT_CERTS: /etc/istio-certs proxyMetadata.INBOUND_CAPTURE_PORTS: "" spec: containers: - name: prometheus image: prom/prometheus:latest volumes: - name: istio-certs secret: secretName: istio.default备注:
OUTPUT_CERTS指示 Istio Sidecar 将证书写入何处供 Prometheus 使用。INBOUND_CAPTURE_PORTS: ""阻止 Sidecar 拦截 Prometheus 的流量。userVolumeMount将证书挂载到 Prometheus 容器内。
修改
samples/addons/prometheus.yaml文件中的 Prometheus 抓取任务配置, 添加一个用于抓取安全指标的额外任务:- job_name: 'istio-secure-merged-metrics' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_istio_io_secure_port] action: keep regex: .+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: - __meta_kubernetes_pod_ip - __meta_kubernetes_pod_annotation_prometheus_istio_io_secure_port action: replace target_label: __address__ regex: (.+);(.+) replacement: $1:$2 scheme: https tls_config: ca_file: /etc/istio-certs/root-cert.pem cert_file: /etc/istio-certs/cert-chain.pem key_file: /etc/istio-certs/key.pem insecure_skip_verify: true验证 Prometheus Pod 是否包含 Istio Sidecar。
$ kubectl get pod <prometheus-pod> -n monitoring -o jsonpath='{.spec.containers[*].name}'您应该会看到一个名为
istio-proxy的容器。
Sidecar 的安全指标
此任务使用 httpbin 作为示例工作负载来生成流量和指标。
在默认命名空间中启用 Sidecar 注入并部署 httpbin。
$ kubectl label namespace default istio-injection=enabled --overwrite $ kubectl apply -f @samples/httpbin/httpbin.yaml为 httpbin Pod 添加注解,以便 Prometheus 能够安全地抓取数据。
确保 Prometheus 通过 mTLS 端口(
15091)安全地抓取指标:$ kubectl annotate pod -n default \ -l app=httpbin \ prometheus.io/scrape="true" \ prometheus.io/path="/stats/prometheus" \ prometheus.istio.io/secure-port="15091" \ --overwrite这些注解使 Prometheus 能够发现 httpbin Pod 并通过安全监听器抓取指标。
在端口 15091 上创建一个安全监听器。
可以使用端口
15091上的 Sidecar 监听器安全地公开工作负载指标。 该监听器会将来自安全监听器的请求转发到 Sidecar 的遥测端口15020。 对于仅限 Envoy 的指标,请使用端口15090。$ cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Sidecar metadata: name: secure-metrics namespace: default spec: ingress: - port: number: 15091 name: https-metrics protocol: HTTP defaultEndpoint: 127.0.0.1:15020 # 对于 Envoy 专属指标,将端口更改为 15090。 EOF
网关的安全指标
Istio 网关会暴露 Prometheus 可以抓取的指标。默认情况下,
这些指标分别位于端口 15020(用于合并遥测数据)和 15090(仅用于 Envoy 遥测数据),
并且默认情况下不受 mTLS 保护。以下步骤将配置使用 Istio mTLS 通过端口 15091 进行安全抓取。
创建一个在端口
15091上启用安全监听的Gateway。我们创建一个
Gateway,用于暴露标准 HTTP 流量和一个专用的安全 HTTPS 端口来收集指标。 HTTPS 服务器使用ISTIO_MUTUALTLS 模式,这样只有持有 Istio 颁发证书的客户端(例如 Prometheus Sidecar)才能抓取指标。$ cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: default spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: ["*"] - port: number: 15091 name: https-metrics protocol: HTTPS tls: mode: ISTIO_MUTUAL hosts: ["*"] EOF为网关的遥测端口(15020 或 15090)创建一个
ServiceEntry。除非网关的内部端口在服务网格中暴露出来,否则 Prometheus 无法直接访问这些端口。
ServiceEntry允许 Prometheus 将请求路由到服务网格内的这些端口。 您可以选择 15020 端口用于合并遥测数据,或选择 15090 端口用于仅限 Envoy 的遥测数据。$ cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: gateway-admin namespace: istio-system spec: hosts: [gateway-admin.local] location: MESH_INTERNAL ports: - number: 15020 # Change to 15090 for Envoy-only metrics name: http-metrics protocol: HTTP resolution: STATIC endpoints: - address: 127.0.0.1 EOF创建一个
VirtualService来路由指标数据。VirtualService将来自安全监听器 (15091) 的请求映射到指向遥测端口(15020 或 15090)的ServiceEntry。 这确保了发送到https://<gateway-ip>:15091/stats/prometheus的指标请求能够在服务网格内部正确路由。$ cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: gateway-metrics namespace: default spec: hosts: ["*"] gateways: [httpbin-gateway] http: - match: - uri: prefix: /stats/prometheus route: - destination: host: gateway-admin.local port: number: 15020 # 对于 Envoy 专属指标,将端口更改为 15090。 EOF对
GatewayPod 进行注释$ kubectl annotate pod -n istio-system <ingress-pod> prometheus.istio.io/secure-port=15091 --overwrite
验证
使用 Prometheus 验证安全指标抓取
完成配置后,请验证 Prometheus 是否已通过双向 TLS 成功从 Istio 工作负载和网关收集指标。
打开 Prometheus Dashboard。
$ istioctl dashboard prometheus此命令会在您的默认浏览器中打开 Prometheus Dashboard。
验证抓取目标
- 在 Prometheus 用户界面中,导航至 Status → Targets。
- 找到名为
istio-secure-merged-metrics的 Job,这正是我们在配置新的 Prometheus 抓取 Job 时使用的名称。
验证 httpbin 工作负载和 Istio Ingress Gateway 的目标是否已列出, 并且其端点类似于:
https://<pod-ip>:15091/stats/prometheus UP。每个目标的状态都应显示为 UP。
这证实了 Prometheus 正在通过 Istio mTLS 使用 HTTPS 协议, 经由安全前端端口(15091)抓取指标,而不是直接访问遥测端口(15020 或 15090)。