首页 > 解决方案 > 我们可以通过 Kiali 在代理后面使用 Istio 跟踪外部 API 调用吗?

问题描述

我们有一个基于 Nodejs 的微服务在我们的本地 kubernetes v1.19 和 Istio v1.8.0 中运行。我想要实现的是在 Kiali 中跟踪或显示外部 API 调用,其中每个微服务都有 Jaeger 客户端,并且能够跟踪内部流量。

但到目前为止,我无法跟踪来自任何微服务的任何外部 API 调用命中。我唯一能在 Kiali 的图表概览中看到代理的流量。

我们有一个合作代理,每个容器都为 http_proxy、https_proxy 设置了环境代理。任何可以通过合作代理访问的外部服务,因此流量应该首先通过我们的合作代理。我们有一个带有 TLS 的安全网关,我们没有 egressgateway,只有 istio-ingressgateway。

那么是否有办法像跟踪集群内部的内部流量一样跟踪外部流量?如果是的话,可能缺少什么?

   $ kubectl get pods -n dev
    NAME                                     READY   STATUS    RESTARTS   AGE
    api-dev-74896ff4f9-slxt5                 3/3     Running   0          7h1m
    auth-dev-98f77d487-qt5zd                 3/3     Running   0          3d5h
    backend-dev-bb7765464-b7bpr              2/2     Running   0          7d3h
    mp-dev-86d6b8b978-slqp7                  3/3     Running   0          5d9h
    ui-dev-d5667946b-sdvlc                   2/2     Running   0          5d4h

这是我创建的 ServiceEntries 和 VirtualServices,我想在其中使用重试功能以及对代理和 externalAPI 的调用

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: company-proxy
  namespace: dev
spec:
  hosts:
  - foo-proxy.net
  ports:
  - number: PORT
    name: tcp
    protocol: TCP
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: proxy
  namespace: dev
spec:
  hosts:
    - "foo-proxy.net"
  http:
    - name: "company-proxy"
      match:
        - uri:
            prefix: "/"
      route:
        - destination:
            host: "foo-proxy.com"
      timeout: 90s
      retries:
        retryOn: "5xx"
        attempts: 3
        perTryTimeout: 30s
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: foo-example.com
  namespace: dev
spec:
  hosts:
    - "foo-example.com"
  ports:
    - number: 80
      name: http
      protocol: HTTP
    - number: 443
      name: https
      protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: foo-example.com
  namespace: dev
spec:
  hosts:
    - "foo-example.com"
  http:
    - name: "developer-api"
      match:
        - uri:
            prefix: "/"
      route:
        - destination:
            host: "foo-example.com"
      timeout: 90s
      retries:
        retryOn: "5xx"
        attempts: 3
        perTryTimeout: 30s

标签: kubernetesistiojaegerkiali

解决方案


我不确定为什么 Istio 不会自动跟踪您对外部 API 的调用。也许它需要使用出口网关,我不确定。另请注意,Istio 为 http(s) 流量创建跟踪,而不是 TCP。

但是,您仍然可以通过编程方式执行此操作。您可以使用任何Jaeger 客户端库通过附加您自己的 span 来扩充 Envoy 已经创建的跟踪。

为此,您首先需要从传入请求的 HTTP 标头中提取跟踪上下文(假设您的外部 API 调用与传入请求是连续的),然后创建一个新跨度作为之前跨度上下文的子级。一个好主意是在标记新跨度时使用OpenTracing 语义约定。如果遵循这个约定,像 Kiali 这样的工具将能够利用一些信息。

我发现这篇博客文章解释了如何使用 nodejs jaeger 客户端进行操作:https ://rhonabwy.com/2019/01/06/adding-tracing-with-jaeger-to-an-express-application/


推荐阅读