Istio可观测性

Istio可观测性

image-20231129072302901

image-20231129072302901

前言

Istio 为网格内所有的服务通信生成详细的遥测数据。这种遥测技术提供了服务行为的可观测性,使运维人员能够排查故障、维护和优化应用程序,而不会给开发人员带来其他额外的负担。通过 Istio,运维人员可以全面了解到受监控的服务如何与其他服务以及 Istio 组件进行交互。

Istio 生成以下类型的遥测数据,以提供对整个服务网格的可观测性:

  • Metrics(指标):Istio 基于 4 个监控的黄金标识(延迟、流量、错误、饱和)生成了一系列服务指标,Istio 还为网格控制平面提供了更详细的指标。除此以外还提供了一组默认的基于这些指标的网格监控仪表板。

  • Tracing(分布式追踪):Istio 为每个服务生成分布式追踪 span,运维人员可以理解网格内服务的依赖和调用流程。

  • Log(访问日志):当流量流入网格中的服务时,Istio 可以生成每个请求的完整记录,包括源和目标的元数据,该信息使运维人员能够将服务行为的审查控制到单个工作负载实例的级别。

接下来我们将分别来学习 Istio 的指标、分布式追踪和访问日志是如何工作的。

指标

指标提供了一种以聚合的方式监控和理解行为的方法。为了监控服务行为,Istio 为服务网格中所有出入网格,以及网格内部的服务流量都生成了指标,这些指标提供了关于行为的信息,例如总流量、错误率和请求响应时间。除了监控网格中服务的行为外,监控网格本身的行为也很重要。Istio 组件还可以导出自身内部行为的指标,以提供对网格控制平面的功能和健康情况的洞察能力。

指标类别

整体上 Istio 的指标可以分成 3 个级别:代理级别、服务级别、控制平面级别。

1、代理级别指标

Istio 指标收集从 Envoy Sidecar 代理开始,每个代理为通过它的所有流量(入站和出站)生成一组丰富的指标。代理还提供关于它本身管理功能的详细统计信息,包括配置信息和健康信息。

Envoy 生成的指标提供了资源(例如监听器和集群)粒度上的网格监控。因此,为了监控 Envoy 指标,需要了解网格服务和 Envoy 资源之间的连接。

Istio 允许运维人员在每个工作负载实例上选择生成和收集哪些 Envoy 指标。默认情况下,Istio 只支持 Envoy 生成的统计数据的一小部分,以避免依赖过多的后端服务,还可以减少与指标收集相关的 CPU 开销。但是运维人员可以在需要时轻松地扩展收集到的代理指标数据。这样我们可以有针对性地调试网络行为,同时降低了跨网格监控的总体成本。

2、服务级别指标

除了代理级别指标之外,Istio 还提供了一组用于监控服务通信的面向服务的指标。这些指标涵盖了四个基本的服务监控需求:延迟、流量、错误和饱和情况。而且 Istio 还自带了一组默认的仪表板,用于监控基于这些指标的服务行为。默认情况下,标准 Istio 指标会导出到 Prometheus。而且服务级别指标的使用完全是可选的,运维人员可以根据自身的需求来选择关闭指标的生成和收集。

3、控制平面指标

另外 Istio 控制平面还提供了一组自我监控指标。这些指标允许监控 Istio 自己的行为。

通过 Prometheus 查询指标

Istio 默认使用 Prometheus 来收集和存储指标。Prometheus 是一个开源的系统监控和警报工具包,它可以从多个源收集指标,并允许运维人员通过 PromQL 查询语言来查询收集到的指标。

  • 首先要确保 Istio 的 prometheus 组件已经启用,如果没有启用可以通过以下命令启用:

[root@master1 ~]#cd istio-1.19.3/
[root@master1 istio-1.19.3]#ls samples/addons/
extras  grafana.yaml  jaeger.yaml  kiali.yaml  loki.yaml  prometheus.yaml  README.md

#部署
kubectl apply -f samples/addons

上面的命令会安装 Kiali,包括 Prometheus、Grafana 以及 jaeger。当然这仅仅只能用于测试环境,在生产环境可以单独安装 Prometheus 进行有针对性的配置优化。

  • 安装后可以通过以下命令查看 Prometheus 服务状态:

$ kubectl get svc prometheus -n istio-system
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.106.228.196   <none>        9090/TCP   25d
$ kubectl get pods -n istio-system -l app=prometheus
NAME                         READY   STATUS    RESTARTS       AGE
prometheus-5d5d6d6fc-2gtxm   2/2     Running   0              25d
  • 首先在浏览器中访问 http://$GATEWAY_URL/productpage 应用,然后我们就可以打开 Prometheus UI 来查看指标了。在 Kubernetes 环境中,执行如下命令就可以打开 Prometheus UI:

istioctl dashboard prometheus
# 也可以创建 Ingress 或者 Gateway 来访问 Prometheus UI

[root@master1 istio-1.19.3]#istioctl dashboard prometheus
http://localhost:9090
Failed to open browser; open http://localhost:9090 in your browser.

C[root@master1 istio-1.19.3]#istioctl dashboard prometheus --address 0.0.0.0
http://0.0.0.0:9090
Failed to open browser; open http://0.0.0.0:9090 in your browser.

image-20231129065931011

image-20231129065931011

打开后我们可以在页面中随便查询一个指标,比如我们查询 istio_requests_total 指标,如下所示:

img

img

istio_requests_total 这是一个 COUNTER 类型的指标,用于记录 Istio 代理处理的总请求数。

  • 当然然后可以根据自己需求来编写 promql 语句进行查询,比如查询 productpage 服务的总次数,可以用下面的语句:

istio_requests_total{destination_service="productpage.default.svc.cluster.local"}
  • 查询 reviews 服务 v3 版本的总次数:

istio_requests_total{destination_service="reviews.default.svc.cluster.local", destination_version="v3"}

该查询返回所有请求 reviews 服务 v3 版本的当前总次数。

  • 过去 5 分钟 productpage 服务所有实例的请求频次:

rate(istio_requests_total{destination_service=~"productpage.*", response_code="200"}[5m])
  • Graph 选项卡中,可以看到查询结果的图形化表示。

img

img

对于 PromQL 语句的使用可以参考官方文档 Prometheus Querying Basics,或者我们的 《Prometheus 入门到实战》课程,这并不是我们这里的重点,所以就不再详细介绍了。

虽然我们这里并没有做任何的配置,但是 Istio 默认已经为我们收集了一些指标,所以我们可以直接查询到这些指标了。

使用 Grafana 可视化指标

Prometheus 提供了一个基本的 UI 来查询指标,但是它并不是一个完整的监控系统,更多的时候我们可以使用 Grafana 来可视化指标。

  • 首先同样要保证 Istio 的 grafana 组件已经启用,如果没有启用可以通过以下命令启用:

kubectl apply -f samples/addons
  • 并且要保证 Prometheus 服务正在运行,服务安装后可以通过下面的命令来查看状态:

$ kubectl -n istio-system get svc grafana
NAME      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.96.197.74   <none>        3000/TCP   25d
$ kubectl -n istio-system get pods -l app=grafana
NAME                       READY   STATUS    RESTARTS       AGE
grafana-5f9b8c6c5d-jv65v   1/1     Running   0              25d
  • 然后我们可以通过以下命令来打开 Grafana UI:

istioctl dashboard grafana
# 也可以创建 Ingress 或者 Gateway 来访问 Grafana

istioctl dashboard grafana --address 0.0.0.0

然后我们就可以在浏览器中打开 Grafana UI 了,默认情况下 Grafana 已经配置了 Prometheus 数据源,所以我们可以直接使用 Prometheus 数据源来查询指标。

img

img

  • 此外 Grafana 也已经内置了 Istio 的一些仪表盘,我们可以直接使用这些仪表盘来查看指标,比如我们可以打开 Istio Mesh Dashboard 仪表盘来查看网格的指标:

img

img

从图中可以看出现在有一些数据,但是并不是很多,这是因为我们现在还没产生一些流量请求。

  • 下面我们可以用下面的命令向 productpage 服务发送 100 个请求:

for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done
  • 然后我们再次查看 Istio Mesh Dashboard,它应该反映所产生的流量,如下所示:

img

img

  • 当然除此之外我们也可以查看到 Service 或者 Workload 的指标,比如我们可以查看 productpage 工作负载的指标:

img

img

这里给出了每一个工作负载,以及该工作负载的入站工作负载(将请求发送到该工作负载的工作负载)和出站服务(此工作负载向其发送请求的服务)的详细指标。

Istio Dashboard 主要包括三个主要部分:

  • 网格摘要视图:这部分提供网格的全局摘要视图,并显示网格中(HTTP/gRPC 和 TCP)的工作负载。

  • 单独的服务视图:这部分提供关于网格中每个单独的(HTTP/gRPC 和 TCP)服务的请求和响应指标。这部分也提供关于该服务的客户端和服务工作负载的指标。

  • 单独的工作负载视图:这部分提供关于网格中每个单独的(HTTP/gRPC 和 TCP)工作负载的请求和响应指标。这部分也提供关于该工作负载的入站工作负载和出站服务的指标。

指标采集原理

从上面的例子我们可以看出当我们安装了 Istio 的 Prometheus 插件后,Istio 就会自动收集一些指标,但是我们并没有做任何的配置,那么 Istio 是如何收集指标的呢?如果我们想使用我们自己的 Prometheus 来收集指标,那么我们应该如何配置呢?

  • 首先我们需要去查看下 Istio 的 Prometheus 插件的配置,通过 cat samples/addons/prometheus.yaml 命令查看配置文件,如下所示:

# Source: prometheus/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    component: "server"
    app: prometheus
    release: prometheus
    chart: prometheus-19.6.1
    heritage: Helm
  name: prometheus
  namespace: istio-system
spec:
  ports:
    - name: http
      port: 9090
      protocol: TCP
      targetPort: 9090
  selector:
    component: "server"
    app: prometheus
    release: prometheus
  sessionAffinity: None
  type: "ClusterIP"
---
# Source: prometheus/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: "server"
    app: prometheus
    release: prometheus
    chart: prometheus-19.6.1
    heritage: Helm
  name: prometheus
  namespace: istio-system
spec:
  selector:
    matchLabels:
      component: "server"
      app: prometheus
      release: prometheus
  replicas: 1
  strategy:
    type: Recreate
    rollingUpdate: null
  template:
    metadata:
      labels:
        component: "server"
        app: prometheus
        release: prometheus
        chart: prometheus-19.6.1
        heritage: Helm
        sidecar.istio.io/inject: "false"
    spec:
      enableServiceLinks: true
      serviceAccountName: prometheus
      containers:
        - name: prometheus-server-configmap-reload
          image: "jimmidyson/configmap-reload:v0.8.0"
          imagePullPolicy: "IfNotPresent"
          args:
            - --volume-dir=/etc/config
            - --webhook-url=http://127.0.0.1:9090/-/reload
          resources: {}
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config
              readOnly: true
        - name: prometheus-server
          image: "prom/prometheus:v2.41.0"
          imagePullPolicy: "IfNotPresent"
          args:
            - --storage.tsdb.retention.time=15d
            - --config.file=/etc/config/prometheus.yml ##配置文件
            - --storage.tsdb.path=/data
            - --web.console.libraries=/etc/prometheus/console_libraries
            - --web.console.templates=/etc/prometheus/consoles
            - --web.enable-lifecycle
          ports:
            - containerPort: 9090
          readinessProbe:
            httpGet:
              path: /-/ready
              port: 9090
              scheme: HTTP
            initialDelaySeconds: 0
            periodSeconds: 5
            timeoutSeconds: 4
            failureThreshold: 3
            successThreshold: 1
          livenessProbe:
            httpGet:
              path: /-/healthy
              port: 9090
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 15
            timeoutSeconds: 10
            failureThreshold: 3
            successThreshold: 1
          resources: {}
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config
            - name: storage-volume
              mountPath: /data
              subPath: ""
      dnsPolicy: ClusterFirst
      securityContext:
        fsGroup: 65534
        runAsGroup: 65534
        runAsNonRoot: true
        runAsUser: 65534
      terminationGracePeriodSeconds: 300
      volumes:
        - name: config-volume
          configMap:
            name: prometheus
        - name: storage-volume
          emptyDir: {} ##临时的
# 省略了部分配置

从上面的资源清单中可以看出 Prometheus 服务的核心配置文件为 --config.file=/etc/config/prometheus.yml,而该配置文件是通过上面的 prometheus 这个 ConfigMap 以 volume 形式挂载到容器中的。

  • 所以我们重点是查看这个 ConfigMap 的配置,如下所示:

# Source: prometheus/templates/cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    component: "server"
    app: prometheus
    release: prometheus
    chart: prometheus-19.6.1
    heritage: Helm
  name: prometheus
  namespace: istio-system
data:
  allow-snippet-annotations: "false"
  alerting_rules.yml: |
    {}
  alerts: |
    {}
  prometheus.yml: |
    global:
      evaluation_interval: 1m
      scrape_interval: 15s
      scrape_timeout: 10s
    rule_files:
    - /etc/config/recording_rules.yml
    - /etc/config/alerting_rules.yml
    - /etc/config/rules
    - /etc/config/alerts
    scrape_configs:
    - job_name: prometheus
      static_configs:
      - targets:
        - localhost:9090
    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      job_name: kubernetes-apiservers
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        regex: default;kubernetes;https
        source_labels:
        - __meta_kubernetes_namespace
        - __meta_kubernetes_service_name
        - __meta_kubernetes_endpoint_port_name
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      job_name: kubernetes-nodes
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - replacement: kubernetes.default.svc:443
        target_label: __address__
      - regex: (.+)
        replacement: /api/v1/nodes/$1/proxy/metrics
        source_labels:
        - __meta_kubernetes_node_name
        target_label: __metrics_path__
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      job_name: kubernetes-nodes-cadvisor
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - replacement: kubernetes.default.svc:443
        target_label: __address__
      - regex: (.+)
        replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
        source_labels:
        - __meta_kubernetes_node_name
        target_label: __metrics_path__
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
    - honor_labels: true
      job_name: kubernetes-service-endpoints
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scrape
      - action: drop
        regex: true
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow
      - action: replace
        regex: (https?)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scheme
        target_label: __scheme__
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_path
        target_label: __metrics_path__
      - action: replace
        regex: (.+?)(?::\d+)?;(\d+)
        replacement: $1:$2
        source_labels:
        - __address__
        - __meta_kubernetes_service_annotation_prometheus_io_port
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_service_annotation_prometheus_io_param_(.+)
        replacement: __param_$1
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_service_name
        target_label: service
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: node
    - honor_labels: true
      job_name: kubernetes-service-endpoints-slow
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow
      - action: replace
        regex: (https?)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_scheme
        target_label: __scheme__
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_path
        target_label: __metrics_path__
      - action: replace
        regex: (.+?)(?::\d+)?;(\d+)
        replacement: $1:$2
        source_labels:
        - __address__
        - __meta_kubernetes_service_annotation_prometheus_io_port
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_service_annotation_prometheus_io_param_(.+)
        replacement: __param_$1
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_service_name
        target_label: service
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: node
      scrape_interval: 5m
      scrape_timeout: 30s
    - honor_labels: true
      job_name: prometheus-pushgateway
      kubernetes_sd_configs:
      - role: service
      relabel_configs:
      - action: keep
        regex: pushgateway
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_probe
    - honor_labels: true
      job_name: kubernetes-services
      kubernetes_sd_configs:
      - role: service
      metrics_path: /probe
      params:
        module:
        - http_2xx
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_service_annotation_prometheus_io_probe
      - source_labels:
        - __address__
        target_label: __param_target
      - replacement: blackbox
        target_label: __address__
      - source_labels:
        - __param_target
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - source_labels:
        - __meta_kubernetes_service_name
        target_label: service
    - honor_labels: true
      job_name: kubernetes-pods
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scrape
      - action: drop
        regex: true
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow
      - action: replace
        regex: (https?)
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scheme
        target_label: __scheme__
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_path
        target_label: __metrics_path__
      - action: replace
        regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})
        replacement: '[$2]:$1'
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_port
        - __meta_kubernetes_pod_ip
        target_label: __address__
      - action: replace
        regex: (\d+);((([0-9]+?)(\.|$)){4})
        replacement: $2:$1
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_port
        - __meta_kubernetes_pod_ip
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+)
        replacement: __param_$1
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: drop
        regex: Pending|Succeeded|Failed|Completed
        source_labels:
        - __meta_kubernetes_pod_phase
    - honor_labels: true
      job_name: kubernetes-pods-slow
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: keep
        regex: true
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow
      - action: replace
        regex: (https?)
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_scheme
        target_label: __scheme__
      - action: replace
        regex: (.+)
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_path
        target_label: __metrics_path__
      - action: replace
        regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})
        replacement: '[$2]:$1'
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_port
        - __meta_kubernetes_pod_ip
        target_label: __address__
      - action: replace
        regex: (\d+);((([0-9]+?)(\.|$)){4})
        replacement: $2:$1
        source_labels:
        - __meta_kubernetes_pod_annotation_prometheus_io_port
        - __meta_kubernetes_pod_ip
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+)
        replacement: __param_$1
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: drop
        regex: Pending|Succeeded|Failed|Completed
        source_labels:
        - __meta_kubernetes_pod_phase
      scrape_interval: 5m
      scrape_timeout: 30s
  recording_rules.yml: |
    {}
  rules: |
    {}
---

这个配置文件中描述了 6 个指标抓取任务的配置:

  • prometheus:抓取 Prometheus 服务自身的指标。

  • kubernetes-apiservers:抓取 Kubernetes API 服务器的指标。

  • kubernetes-nodes:抓取 Kubernetes 节点的指标。

  • kubernetes-nodes-cadvisor:抓取 Kubernetes 节点的 cadvisor 指标,主要包括容器的 CPU、内存、网络、磁盘等指标。

  • kubernetes-service-endpoints:抓取 Kubernetes 服务端点的指标。

  • kubernetes-pods:抓取 Kubernetes Pod 的指标。

img

img

这里我们可以重点关注下 kubernetes-pods 这个指标抓取任务的配置,因为我们大部分的指标数据都是通过 Pod 的 Envoy Sidecar 来提供的。

从配置上可以看到这是基于 pod 的服务发现方式:

  • 首先只会保留 __meta_kubernetes_pod_annotation_prometheus_io_scrape 这个源标签为 true 的指标数据,这个源标签表示的是如果 Pod 的 annotation 注解中有 prometheus.io/scrape 标签,且值为 true,则会保留该指标数据,否则会丢弃该指标数据

  • 然后根据 prometheus.io/scheme 注解来配置协议为 http 或者 https

  • 根据 prometheus.io/path 注解来配置抓取路径

  • 根据 prometheus.io/port 注解来配置抓取端口;

  • prometheus.io/param 注解的值映射为 Prometheus 的标签;

  • 然后还会将 pod 的标签通过 labelmap 映射为 Prometheus 的标签;最后还会将 pod 的 namespace 和 pod 的名称映射为 Prometheus 的标签。

  • 最后需要判断 Pod 的 phase 状态,只有当 Pod 的 phase 状态为 Running 时才会保留该指标数据,否则会丢弃该指标数据。

比如我们查询 istio_requests_total{app="productpage", destination_app="details"} 这个指标,如下所示:

img

img

  • 该查询语句的查询结果为:

istio_requests_total{
    app="details",
    connection_security_policy="mutual_tls",
    destination_app="details",
    destination_canonical_revision="v1",
    destination_canonical_service="details",
    destination_cluster="Kubernetes",
    destination_principal="spiffe://cluster.local/ns/default/sa/bookinfo-details",
    destination_service="details.default.svc.cluster.local",
    destination_service_name="details",
    destination_service_namespace="default",
    destination_version="v1",
    destination_workload="details-v1",
    destination_workload_namespace="default",
    instance="10.244.2.74:15020",
    job="kubernetes-pods",
    namespace="default",
    pod="details-v1-5f4d584748-9fflw",
    pod_template_hash="5f4d584748",
    reporter="destination",
    request_protocol="http",
    response_code="200",
    response_flags="-",
    security_istio_io_tlsMode="istio",
    service_istio_io_canonical_name="details",
    service_istio_io_canonical_revision="v1",
    source_app="productpage",
    source_canonical_revision="v1",
    source_canonical_service="productpage",
    source_cluster="Kubernetes",
    source_principal="spiffe://cluster.local/ns/default/sa/bookinfo-productpage",
    source_version="v1",
    source_workload="productpage-v1",
    source_workload_namespace="default",
    version="v1"
}  362

该查询表示的是从 productpage 服务到 details 服务的请求总次数,从查询结果可以看出该指标就是来源于 job="kubernetes-pods" 这个指标抓取任务,那说明这个指标数据是通过服务发现方式从 Pod 中抓取的。

  • 我们可以查看下 productpage Pod 的信息,如下所示:

$ kubectl get pods productpage-v1-564d4686f-l8kxr -oyaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    istio.io/rev: default
    kubectl.kubernetes.io/default-container: productpage
    kubectl.kubernetes.io/default-logs-container: productpage
    prometheus.io/path: /stats/prometheus
    prometheus.io/port: "15020"
    prometheus.io/scrape: "true"
    sidecar.istio.io/status: '{"initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["workload-socket","credential-socket","workload-certs","istio-envoy","istio-data","istio-podinfo","istio-token","istiod-ca-cert"],"imagePullSecrets":null,"revision":"default"}'
  labels:
    app: productpage
    pod-template-hash: 564d4686f
    security.istio.io/tlsMode: istio
    service.istio.io/canonical-name: productpage
    service.istio.io/canonical-revision: v1
    version: v1
  name: productpage-v1-564d4686f-l8kxr
  namespace: default
spec:
  containers:
  - image: docker.io/istio/examples-bookinfo-productpage-v1:1.18.0
    imagePullPolicy: IfNotPresent
# ......

我们从上面的资源清单中可以看到该 Pod 包含如下几个注解:

  • prometheus.io/path: /stats/prometheus

  • prometheus.io/port: "15020"

  • prometheus.io/scrape: "true"

这些注解就是用来配置 Prometheus 服务发现的,其中 prometheus.io/scrape: "true" 表示该 Pod 的指标数据是需要被抓取的,而 prometheus.io/path: /stats/prometheusprometheus.io/port: "15020" 则是用来配置抓取路径和抓取端口的,当 Prometheus 发现这个 Pod 后根据配置就可以通过 <pod ip>:15020/stats/prometheus 这个路径来抓取该 Pod 的指标数据了,这个路径就是 Envoy Sidecar 提供的 /stats/prometheus 路径,而 15020 则是 Envoy Sidecar 的端口,这个端口是通过 istio-proxy 这个容器配置的静态监听器暴露出来的。

当然定义的标签也被映射为 Prometheus 的标签了,从结果来看除了 Pod 的这些标签之外,Envoy Sidecar 也会自己添加很多相关标签,主要是标明 destinationsource 的信息,有了这些标签我们就可以很方便的对指标进行查询了。Envoy Sidecar 自行添加的一些主要标签如下所示:

  • reporter:标识请求指标的上报端,如果指标由服务端 Istio 代理上报,则设置为 destination,如果指标由客户端 Istio 代理或网关上报,则设置为 source

  • source_workload:标识源工作负载的名称,如果缺少源信息,则标识为 unknown

  • source_workload_namespace:标识源工作负载的命名空间,如果缺少源信息,则标识为 unknown

  • source_principal:标识流量源的对等主体,当使用对等身份验证时设置。

  • source_app:根据源工作负载的 app 标签标识源应用程序,如果源信息丢失,则标识为 unknown

  • source_version:标识源工作负载的版本,如果源信息丢失,则标识为 unknown

  • destination_workload:标识目标工作负载的名称,如果目标信息丢失,则标识为 unknown

  • destination_workload_namespace:标识目标工作负载的命名空间,如果目标信息丢失,则标识为 unknown

  • destination_principal:标识流量目标的对等主体,使用对等身份验证时设置。

  • destination_app:它根据目标工作负载的 app 标签标识目标应用程序,如果目标信息丢失,则标识为 unknown

  • destination_version:标识目标工作负载的版本,如果目标信息丢失,则标识为 unknown

  • destination_service:标识负责传入请求的目标服务主机,例如:details.default.svc.cluster.local

  • destination_service_name:标识目标服务名称,例如 details

  • destination_service_namespace:标识目标服务的命名空间。

  • request_protocol:标识请求的协议,设置为请求或连接协议。

  • response_code:标识请求的响应代码,此标签仅出现在 HTTP 指标上。

  • connection_security_policy:标识请求的服务认证策略,当 Istio 使用安全策略来保证通信安全时,如果指标由服务端 Istio 代理上报,则将其设置为 mutual_tls。如果指标由客户端 Istio 代理上报,由于无法正确填充安全策略,因此将其设置为 unknown

  • response_flags:有关来自代理的响应或连接的其他详细信息。

  • Canonical Service:工作负载属于一个 Canonical 服务,而 Canonical 服务却可以属于多个服务。Canonical 服务具有名称和修订版本,因此会产生以下标签:

  • source_canonical_service

  • source_canonical_revision

  • destination_canonical_service

  • destination_canonical_revision

  • destination_cluster:目标工作负载的集群名称,这是由集群安装时的 global.multiCluster.clusterName 设置的。

  • source_cluster:源工作负载的集群名称,这是由集群安装时的 global.multiCluster.clusterName 设置的。

  • grpc_response_status: 这标识了 gRPC 的响应状态,这个标签仅出现在 gRPC 指标上。

对于 Istio 来说包括 COUNTERDISTRIBUTION 两种指标类型,这两种指标类型对应我们比较熟悉的计数器和直方图。

对于 HTTP,HTTP/2 和 GRPC 通信,Istio 生成以下指标:

  • 请求数 (istio_requests_total): 这都是一个 COUNTER 类型的指标,用于记录 Istio 代理处理的总请求数。

  • 请求时长 (istio_request_duration_milliseconds): 这是一个 DISTRIBUTION 类型的指标,用于测量请求的持续时间。

  • 请求体大小 (istio_request_bytes): 这是一个 DISTRIBUTION 类型的指标,用来测量 HTTP 请求主体大小。

  • 响应体大小 (istio_response_bytes): 这是一个 DISTRIBUTION 类型的指标,用来测量 HTTP 响应主体大小。

  • gRPC 请求消息数 (istio_request_messages_total): 这是一个 COUNTER 类型的指标,用于记录从客户端发送的 gRPC 消息总数。

  • gRPC 响应消息数 (istio_response_messages_total): 这是一个 COUNTER 类型的指标,用于记录从服务端发送的 gRPC 消息总数。

对于 TCP 流量,Istio 生成以下指标:

  • TCP 发送字节大小 (istio_tcp_sent_bytes_total): 这是一个 COUNTER 类型的指标,用于测量在 TCP 连接情况下响应期间发送的总字节数。

  • TCP 接收字节大小 (istio_tcp_received_bytes_total): 这是一个 COUNTER 类型的指标,用于测量在 TCP 连接情况下请求期间接收到的总字节数。

  • TCP 已打开连接数 (istio_tcp_connections_opened_total): 这是一个 COUNTER 类型的指标,用于记录 TCP 已打开的连接总数。

  • TCP 已关闭连接数 (istio_tcp_connections_closed_total): 这是一个 COUNTER 类型的指标,用于记录 TCP 已关闭的连接总数。

当我们了解了 Istio 指标数据采集的原理后,我们就可以根据自身的需求来定制了,比如在我们的监控系统采样的是 Prometheus Operator 方式,那么也应该知道该如何来配置采集这些指标数据了。

自定义指标

除了 Istio 自带的指标外,我们还可以自定义指标,要自定指标需要用到 Istio 提供的 Telemetry API,该 API 能够灵活地配置指标、访问日志和追踪数据。

关于我

我的博客主旨:

  • 排版美观,语言精炼;

  • 文档即手册,步骤明细,拒绝埋坑,提供源码;

  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

image-20230107215114763

image-20230107215114763

🍀 微信公众号 《云原生架构师实战》

image-20230107215126971

image-20230107215126971

🍀 个人博客站点

http://onedayxyy.cn/

image-20231113073017981

image-20231113073017981

image-20231113073039083

image-20231113073039083

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20231113073101271

image-20231113073101271

🍀 csdn

一念一生~one_k8s,Linux,git-CSDN博客

image-20230107215149885

image-20230107215149885

🍀 知乎

一个人 - 知乎

image-20230107215203185

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/212576.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 Vue、Datav、Echart 框架的 “ 数据大屏项目 “,通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换

最近在研究大数据分析&#xff0c;基于 Vue、Datav、Echart 框架的 " 数据大屏项目 "&#xff0c;通过 Vue 组件实现数据动态刷新渲染&#xff0c;内部图表可实现自由替换。部分图表使用 DataV 自带组件&#xff0c;可进行更改&#xff0c;详情请点击下方 DataV 文档…

伪原创API,批量创作伪原创文章

内容创作已经成为互联网领域中不可或缺的一环。越来越多的内容创作者和网站管理员开始寻找更高效的伪原创工具&#xff0c;以确保其内容的独特性。 百度文心一言API 我们来了解一下百度文心一言API。作为百度文心推出的一项人工智能服务&#xff0c;通过自然语言处理技术&…

态势感知是什么

在当今高度信息化的时代&#xff0c;信息安全风险已经成为企业、政府和个人的重要关注点。为了有效应对这些风险&#xff0c;态势感知成为了一种日益重要的能力。态势感知是一种基于环境的、动态、整体地洞悉安全风险的能力&#xff0c;是以安全大数据为基础&#xff0c;从全局…

水果编曲软件fl studio手机版下载

fl studio mobile手机版中文名水果编曲软件&#xff0c;它是一款非常不错的音乐编曲软件&#xff0c;凭借简单易上手的操作方式&#xff0c;强悍且实用的功能&#xff0c;深受到了音乐创作者的喜爱&#xff0c;不仅仅提供了广阔的音乐创作空间&#xff0c;可以让用户对舞曲、轻…

可视化开源编辑器Swagger Editor本地部署并实现远程访问管理编辑文档

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagge…

分治-归并算法——LCR 170. 交易逆序对的总数

文章目录 &#x1f33c;0. 归并排序&#x1f33b;1. 题目&#x1f33c;2. 算法原理&#x1f337;3. 代码实现 &#x1f33c;0. 归并排序 归并排序是典型的分治&#xff0c;将数组分成若干个子数组&#xff0c;数组两两比较&#xff0c;不是很清楚的&#xff0c;可以查看此篇文…

jdk1.8 hashmap源码阅读

目录 hashmap 成员变量 hashmap支持null键吗&#xff1f;为什么&#xff1f; 当扩容的时候&#xff0c;所有元素都会重新计算hash值吗&#xff1f; 怎么减少扩容次数 为什么node数组的大小是2的n次&#xff1f; 1.8和1.7的区别 1.8为啥要用红黑树&#xff1f; 扩容机制…

右值引用和移动语句(C++11)

左值引用和右值引用 回顾引用 我们之前就了解到了左值引用&#xff0c;首先我们要了解引用在编译器底层其实就是指针。具体来说&#xff0c;当声明引用时&#xff0c;编译器会在底层生成一个指针来表示引用&#xff0c;但在代码编写和使用时&#xff0c;我们可以像使用变量类…

面试题:MySQL为什么选择B+树作为索引结构

文章目录 前言二、平衡二叉树(AVL)&#xff1a;旋转耗时三、红黑树&#xff1a;树太高四、B树&#xff1a;为磁盘而生五、B树六、感受B树的威力七、总结 前言 在MySQL中&#xff0c;无论是Innodb还是MyIsam&#xff0c;都使用了B树作索引结构(这里不考虑hash等其他索引)。本文…

一缕青丝寄相思

10年8月16日七夕节男孩向女孩表白,女孩不知道那天是七夕,也没有读懂男孩的爱,女孩在9月22日中秋,向男孩打开了心门,男孩却没有懂女孩的心思.13年后的一封问候邮件,一束女孩的长发和回不去的青春 洒满阳光的午后 转眼间看到你的笑脸 微笑着你对我说 遇上你认识我真好 你说得好莫…

数据结构与算法(Java) -单调队列单调栈题单

单调队列&#xff08;灵神笔记&#xff09; 239 滑动窗口最大值 239. 滑动窗口最大值 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗…

找不到DNS地址的解决方案

找不到DNS地址的解决方案 第一种解决方案&#xff1a;刷新DNS缓存第二种解决方案&#xff1a; 配置Internet协议版本4&#xff08;TCP/IPv4&#xff09;配置IP地址配置DNS地址 如何查看本机IPv4地址、子网掩码与默认网关 第一种解决方案&#xff1a;刷新DNS缓存 WINR输入cmd回…

对比ProtoBuf和JSON的序列化和反序列化能力

1.序列化能力对比验证 在这里让我们分别使用PB与JSON的序列化与反序列化能力&#xff0c;对值完全相同的一份结构化数据进行不同次数的性能测试。 为了可读性&#xff0c;下面这一份文本使用JSON格式展示了需要被进行测试的结构化数据内容: {"age" : 20,"name…

2023年第十二届数学建模国际赛小美赛A题太阳黑子预测求解分析

2023年第十二届数学建模国际赛小美赛 A题 太阳黑子预测 原题再现&#xff1a; 太阳黑子是太阳光球上的一种现象&#xff0c;表现为比周围区域暗的暂时斑点。它们是由抑制对流的磁通量浓度引起的表面温度降低区域。太阳黑子出现在活跃区域内&#xff0c;通常成对出现&#xff…

Android自定义View实现八大行星绕太阳转动效果

最近尝试使用Android自定义View实现了一个8大行星绕太阳转动的自定义View效果&#xff0c;效果静态图如下所示&#xff1a; 还没来得及对该效果进行比较通用的包装&#xff0c;仅仅实现效果&#xff0c;有兴趣的可以继续扩展、美化、包装一下。 核心代码就一个类PlanetsView。 …

js中setinterval怎么用?怎么才能让setinterval停下来?

setinterval()是定时调用的函数&#xff0c;可按照指定的周期&#xff08;以毫秒计&#xff09;来调用函数或计算表达式。 setinterval()的作用是在播放动画的时&#xff0c;每隔一定时间就调用函数&#xff0c;方法或对象。 setInterval() 方法会不停地调用函数&#xff0c;…

Stm32F401RCT6内部FLASH数据擦除读写方法

Stm32F401RCT6内部FLASH数据的分区和F103的已经不一样了&#xff0c;读写格式化的方法网上内容不多&#xff0c;自己摸索了一下&#xff0c;基本可以&#xff0c;还存在一个问题 读取&#xff1a; uint16_t f[5];uint8_t tx[10];f[0] *(volatile uint16_t*)0x08020000; //ST…

tar文件覆盖漏洞 CVE-2007-4559

文章目录 前言原理例题 [NSSRound#7 Team]新的博客方法一 手搓文件名方法二 python脚本 前言 做到[NSSRound#6 Team]check(Revenge)时发现是tar文件覆盖&#xff0c;但是对概念和执行过程理解不够深就光光记住脚本&#xff0c;所以在做本题[NSSRound#7 Team]新的博客时打算重新…

一个网站,四种创建制作电子期刊的方法

想象一下&#xff0c;你正在走进一家神奇的商店&#xff0c;里面陈列着各种精美的杂志和期刊。但是&#xff0c;这些杂志和期刊并不是印刷品&#xff0c;而是可以直接在网站上制作和发布的电子期刊。 但是像这样能在网上发的电子期刊该怎么制作呢&#xff1f;不知道如何制作的小…

cc-product-waterfall仿天猫、淘宝购物车店铺商品列表组件

cc-product-waterfall仿天猫、淘宝购物车店铺商品列表组件 引言 在电商应用中&#xff0c;购物车体验的优化对于提升用户满意度和转化率至关重要。在本文中&#xff0c;我们将深入探讨如何使用cc-product-waterfall组件&#xff0c;结合uni-number-box和xg-widget&#xff0c;…