Skip to content

可观测性

指标

安装PrometheusGrafana组件用来收集和可视化查看日志。

默认情况下,istio定义并生成一组标准指标,但您也可以使用Telemetry API自定义标准指标并创建新指标。

自动生成

参照准备部署httpbin和sleep服务,并从sleep访问httpbin服务。

bash
$ kubectl exec -it $(kubectl get po -l app=sleep -o jsonpath={.items[0].metadata.name}) -c sleep -- curl http://httpbin:8000/headers

等待一会,查看是否自动生成了istio_request_total指标prometheus4

警告

基于Kind部署的测试集群,可能会存在istio_request等指标无法自动生成的情况。

指标含义

指标含义范围
istio_requests_total请求数:用于记录Istio代理处理的总请求数。REQUEST_COUNT
istio_request_duration_milliseconds请求时长:用于测量请求的持续时间。REQUEST_DURATION
istio_request_bytes请求体大小:用来测量HTTP请求主体大小。REQUEST_SIZE
istio_response_bytes响应体大小:用来测量HTTP响应主体大小。RESPONSE_SIZE
istio_request_messages_totalgRPC 请求消息数:用于记录从客户端发送的gRPC消息总数。GRPC_REQUEST_MESSAGES
istio_response_messages_totalgRPC 响应消息数:用于记录从服务端发送的gRPC消息总数。GRPC_RESPONSE_MESSAGES
istio_tcp_sent_bytes_totalTCP 发送字节大小:用于测量在TCP连接情况下响应期间发送的总字节数。TCP_SENT_BYTES
istio_tcp_received_bytes_totalTCP 接收字节大小:用于测量在TCP连接情况下请求期间接收到的总字节数。TCP_RECEIVED_BYTES
istio_tcp_connections_opened_totalTCP 已打开连接数:用于记录TCP已打开的连接总数。TCP_OPENED_CONNECTIONS
istio_tcp_connections_closed_totalTCP 已关闭连接数:用于记录TCP已关闭的连接总数。TCP_CLOSED_CONNECTIONS

TelemetryApi

使用TelemetryApi实现对指标中标签的新增、覆盖和禁用操作。

覆盖标签

  • 去除istio_requests_total指标中请求响应source_cluster标签
bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-tags
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - match:
            mode: CLIENT_AND_SERVER # 匹配请求和响应
            metric: REQUEST_COUNT
          tagOverrides:
            source_cluster:
              operation: REMOVE
EOF

metrics的取值来自指标含义中的范围

再次请求httpbin服务后,等待约15s,继续查看istio_requests_total指标,发现标签source_cluster已经不在了。

prometheus5

  • 去除istio_tcp_connections_opened_total指标中请求source_cluster标签

安装tcp-echo服务后,执行命令访问tcp服务

bash
$ kubectl exec -it "$(kubectl get po -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- sh -c 'echo "port 9000" | nc tcp-echo 9000'

查看prometheus对应的指标结果

prometheus6

警告

TCP相关的指标也是由Envoy自动生成的

配置Telemetry规则,将请求指标中的source_cluster去除

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-tags
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - match:
            mode: CLIENT # 匹配请求
            metric: TCP_OPENED_CONNECTIONS # 匹配TCP_OPEN相关指标
          tagOverrides:
            source_cluster:
              operation: REMOVE
EOF

再次执行命令,查看prometheus查询结果

prometheus7

CLIENT端的source_cluster已经不在,但SERVER端的source_cluster仍在。

添加标签

  • istio_requests_total添加source_xdestination_x标签
bash
$ kubectl apply -f - <<EOF 
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: custom-tags
spec:
  metrics:
    - overrides:
        - match:
            metric: REQUEST_COUNT
            mode: CLIENT
          tagOverrides:
            destination_x:
              value: upstream_peer.labels['app'].value
        - match:
            metric: REQUEST_COUNT
            mode: SERVER
          tagOverrides:
            source_x:
              value: downstream_peer.labels['app'].value
      providers:
        - name: prometheus
EOF

自定义标签的值支持如下参数,通过upstream_peer/downstream_peer调用

字段类型
namestringPod 的名字。
namespacestringPod 运行的命名空间。
labelsmap工作负载标签。
ownerstring工作负载所有者。
workload_namestring工作负载名称。
platform_metadatamap带有前缀键的平台元数据。
istio_versionstring代理的版本标识符。
mesh_idstring网格的唯一标识符。
app_containerslist<string>应用程序容器的短名称列表。
cluster_idstring此工作负载所属的集群的标识符。

再次访问httpbin服务,查看prometheus结果

prometheus8

警告

如果自定义标签一直无法出现,说明受到其他TelemetryApi规则影响,建议删除其他规则避免影响。

禁用标签

禁用请求和响应端的istio_requests_total指标

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: remove-request-count
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - disabled: true
          match:
            mode: CLIENT_AND_SERVER
            metric: REQUEST_COUNT
EOF

日志

提示

OpenTelemetryCNCF的一个观测性项目,旨在提供可观测性领域的标准化方案,以简化在分布式系统中生成、收集、处理、导出跟踪和度量数据的过程。

istio中支持配置Envoy代理以OpenTelemetry格式导出访问日志,并发送到指定的OpenTelemetry收集器

基于Enovy访问日志记录

安装sleep和httpbin服务,并部署otel-collector组件用于日志数据的采集和处理。

部署Telemetry资源告诉istio将访问日志发送到otel-collector收集器。

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: sleep-logging
spec:
  selector:
    matchLabels:
      app: sleep # 匹配需要导出访问日志的服务
  accessLogging:
    - providers:
      - name: otel # 指定istio配置的provider
EOF

执行命令从sleep访问http

bash
$ kubectl exec -it $(kubectl get po -l app=sleep -ojsonpath={.items[0].metadata.name}) -c sleep -- curl httpbin:8000/status/418

查看otel-collector输出的访问日志

bash
$ kubectl -n istio-system logs -f --tail 200 -l app=opentelemetry-collector

访问日志如下所示(去除了不重要的数据)

bash
Body: [2024-01-25T06:03:13.551Z] "GET /status/418 HTTP/1.1" 418 - via_upstream - "-" 0 135 9 8 "-" "curl/8.5.0" "c52dd60d-c5e7-98e6-8122-3c57483ddab2" "httpbin:8000" "10.244.0.53:80" outbound|8000||httpbin.default.svc.cluster.local 10.244.0.50:33034 10.96.67.124:8000 10.244.0.50:41772 - default

警告

从sleep访问httpbin服务,访问日志会出现两条,分别是sleep的出站和httpbin的入站访问日志。因为envoy会代理出入站流量

访问日志格式

日志运算符对应sleep中的访问日志httpbin 中的访问日志
[%START_TIME%][2020-11-25T21:26:18.409Z][2020-11-25T21:26:18.409Z]
"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%""GET /status/418 HTTP/1.1""GET /status/418 HTTP/1.1"
%RESPONSE_CODE%418418
%RESPONSE_FLAGS%--
%RESPONSE_CODE_DETAILS%via_upstreamvia_upstream
%CONNECTION_TERMINATION_DETAILS%--
"%UPSTREAM_TRANSPORT_FAILURE_REASON%""-""-"
%BYTES_RECEIVED%00
%BYTES_SENT%135135
%DURATION%43
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%41
"%REQ(X-FORWARDED-FOR)%""-""-"
"%REQ(USER-AGENT)%""curl/7.73.0-DEV""curl/7.73.0-DEV"
"REQ(X-REQUEST-ID)%""84961386-6d84-929d-98bd-c5aee93b5c88""84961386-6d84-929d-98bd-c5aee93b5c88"
"REQ(:AUTHORITY)%""httpbin:8000""httpbin:8000"
"UPSTREAM_HOST%""10.44.1.27:80""127.0.0.1:80"
%UPSTREAM_CLUSTER%outbound|8000||httpbin.foo.svc.cluster.localinbound|8000||
%UPSTREAM_LOCAL_ADDRESS%10.44.1.23:37652127.0.0.1:4185
%DOWNSTREAM_LOCAL_ADDRESS%10.0.45.184:80010.44.1.27:80
%DOWNSTREAM_REMOTE_ADDRESS%10.44.1.23:4652010.44.1.23:37652
%REQUESTED_SERVER_NAME%-outbound_.8000_._.httpbin.foo.svc.cluster.local
%ROUTE_NAME%defaultdefault

默认格式如上所示,同样我们也可以自定义需要显示的日志格式

bash
$ kubectl -n istio-system apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
data:
  mesh: |-
    defaultConfig:
      discoveryAddress: istiod.istio-system.svc:15012
      tracing:
        zipkin:
          address: zipkin.istio-system:9411
    enablePrometheusMerge: true
    accessLogFile: /dev/stdout
    extensionProviders:
    - name: otel
      envoyOtelAls:
        service: opentelemetry-collector.istio-system.svc.cluster.local
        port: 4317
        logFormat:
          text: "[%START_TIME%]:\"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\""
    rootNamespace: istio-system
    trustDomain: cluster.local
EOF

再次发起服务请求,并查看访问日志

bash
Body: [2024-01-25T07:42:35.182Z]:"GET /status/418 HTTP/1.1"

访问日志持久化

安装grafana-loki来存储otel收集的访问日志,并通过grafana来查看。在浏览器中输入IP:30000来访问grafana,添加数据源loki,查询访问日志结果如下:

grafana

通过label标签匹配日志信息,也可以开启右上角的live功能,有访问日志会立刻刷新在控制台。

TelemetryApi

启用访问日志记录

bash
$ kubectl -n istio-system apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-logging-default
spec:
  accessLogging:
  - providers:
    - name: otel
EOF

不定义selector,默认匹配ns下的所有服务。如果是根空间(istio-system),则所有命令空间都生效

禁用服务日志记录

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: disable-sleep-logging
spec:
  selector:
    matchLabels:
      app: sleep
  accessLogging:
  - providers:
    - name: otel
    disabled: true
EOF

禁用default下的app=sleep的服务的访问日志记录。那么sleep的出入站日志都不会被记录。

禁用出/入站日志记录

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: disable-httpbin-logging
spec:
  selector:
    matchLabels:
      app: httpbin
  accessLogging:
  - providers:
    - name: otel
    match:
      mode: SERVER
    disabled: true
EOF
参数CLIENTSERVERCLIENT_AND_SERVER
含义出站入站出站和入站

配合disabled使用,表示禁用出站、入站或出入站的访问日志记录。

根据条件记录日志

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: filter-sleep-logging
spec:
  selector:
    matchLabels:
      app: sleep
  accessLogging:
  - providers:
    - name: otel
    filter:
      expression: response.code <= 200
EOF

通过sleep服务发起的请求,只有响应码<=200的才会被记录,sleep处理其他服务发起的请求则不受影响。更多

分布式追踪

Istio基于Envoy实现用户对跨多个分布式服务网格的1个请求进行追踪分析。进而可以通过可视化的方式更加深入地了解请求的延迟,序列化和并行度。

上下文传递

警告

应用程序无法自动传播追踪请求头,所以在应用程序中进行下游调用时,请传递追踪的请求头,来保证调用链的完整。

不同的追踪组件,追踪的请求头不同,应用程序必须按照下表要求转发请求头。

请求头组件
x-request-idEnvoy
x-b3-traceid x-b3-spanid x-b3-parentspanid x-b3-sampled x-b3-flagsZipkin Jaeger skywalking
x-datadog-trace-id x-datadog-parent-id x-datadog-sampling-priorityDatadog
x-ot-span-contextLightstep
sw8skywalking

Envoy专用请求头x-request-id必须转发,用于对日志和追踪进行一致的采样。其他的请求头根据各自的组件选择转发。

TelemetryApi

部署zipkin,istio将根据配置发送追踪信息到该组件。

启动链路追踪

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: "zipkin"
EOF

部署在istio-system根目录下,默认对所有ns下的服务都生效。

自定义采样率

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: "zipkin"
      randomSamplingPercentage: 100.0 # 0 -> 100.0
EOF

默认采样率是1%,即100次请求记录一次。

执行命令

bash
$ kubectl exec -it $(kubectl get po -l app=sleep -ojsonpath={.items[0].metadata.name}) -c sleep -- curl httpbin:8000/headers

httpbin服务将我们的请求头参数全部返回,其中就包含了zipkin支持的b3*的请求头。

json
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin:8000", 
    "User-Agent": "curl/8.5.0", 
    "X-B3-Parentspanid": "97aa916a8756def2", 
    "X-B3-Sampled": "1", 
    "X-B3-Spanid": "55b07652e65cbb6e", 
    "X-B3-Traceid": "bc805d24301ad17f97aa916a8756def2", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=65030e2dbc6f613f147a35df8cf93350ca733a50109bab4c3d36633c08c392c6;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
  }
}

"X-B3-Sampled": "1"表示访问记录被zipkin采样。

访问IP:30014查看链路追踪流程。

bash
$ kubectl exec -it $(kubectl get po -l app=sleep -ojsonpath={.items[0].metadata.name}) -c sleep -- curl httpbin:8000/status/418

zipkin1

自定义追踪标签

bash
$ kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: "zipkin"
      randomSamplingPercentage: 100.0
      customTags:
        "provider":
          literal:
            value: "zipkin123"
EOF

再次发起请求,然后查看链路追踪数据,能看到自定义的provider标签已经根据Span创建。

image-20240131171206660