查看原文
其他

使用Istio和Envoy实践服务网格gRPC度量

Renato Stoco 几米宋 2022-09-07

作者:Renato Stoco 译者:陈冬 原文:https://medium.com/pismolabs/istio-envoy-grpc-metrics-winning-with-service-mesh-in-practice-d67a08acd8f7

在这个令人惊奇的时代,我们可以不需要编写一行代码,便可以很智能的集成应用程序,收集应用程序指标。

在这篇文章中,我将演示使用 helm 安装 Istio mtls 环境、必要的 yamls 配置以及安装 Istio 带来的其他收获。另外,在文章最后,我还会展示路由配置的一些例子。

假设你已经安装好 Kubernetes 和 helm,并且对他们都有一定的了解。本教程将以 AWS 作为我们的运行环境。请参考官方安装文档:

https://istio.io/docs/setup/kubernetes/helm-install/

以下是 Istio 的官方拓扑图:

通过我们的设置,所有的容器会连同一个 istio-proxy 一起创建并部署到 istio-injected 的命名空间中。应用程序将与 istio-proxy (envoy) 进行通信,然后后者将处理所有的链接、mtls 以及其他应用程序的负载均衡。

安装以及配置

开始步骤,下载并解压 istio-1.0.0 安装包

  1. wget https://github.com/istio/istio/archive/1.0.0.zip\ && unzip 1.0.0.zip

修改 istio 目录下的 values.yaml 文件,修改环境需要的设置

  1. istio-1.0.0/install/kubernetes/helm/istio/values.yaml

以下修改将使 istio ingressgateway 的 mtls、ingress(用于监控服务)和 ssl 端口(443)重定向到 80 端口,并支持插件到安装(grafana, servicegraph, jaeger and kiali): 获取修改后到 values.yaml 文件,示例

修改完成后,安装所有的程序并查看 Istio 运行情况!

首先,如果使用 2.10.0 之前的 Helm 版本,可以通过 kubectl apply 安装 Istio 的自定义资源;如果不是这类版本,请跳过此步。

  1. kubectl apply -f istio-1.0.0/install/kubernetes/helm/istio/templates/crds.yaml

  2. kubectl apply -f istio-1.0.0/install/kubernetes/helm/istio/charts/certmanager/templates/crds.yaml

安装 Istio (请使用我们调整过的 values.yaml 文件)

  1. helm install istio-1.0.0/install/kubernetes/helm/istio --name istio --namespace istio-system

检查你的 istio-system 命名空间,并查看 pods 是否可以展示出来!同时为你的应用程序创建一个命名空间:

  1. kubectl create namespace istio-apps

现在可以为它加上标签,让 Istio 知道在哪里注入 istio-proxies。

  1. kubectl label namespace istio-apps istio-injection=enabled

现在我们的环境已经运行起来,让我们思考一下应用程序是如何相互通信的。在网格中的服务通过 envoy 来处理双向通行和负载均衡以达到服务间相互通信。那些不在网格中的服务该如何处理呢?你可能想知道他们如何与我们的服务进行沟通,我们的服务如何与网格外部的服务进行通信。这就是我们配置入口的地方。下图将说明外部服务如何与网格内的应用进行联系的:

所有外部的流量将通过 Istio-ingressgateway 进入网格中,Istio-ingressgateway 会尝试查找网格内主机与路径匹配一致的虚拟服务。如果未查找到匹配的虚拟服务,则外部服务将访问不到网格内的应用程序。

提示:正是因为这样的虚拟服务,我们可以做到流量的管理!

对于网格中的服务需要访问外部的服务,例如:访问镜像中的存储应用,你还需要做虚拟服务的流量映射。

本教程中,我们可以使用下面的 yaml 文件(也可以指定 ips)访问网格中的所有主机:

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: ServiceEntry

  3. metadata:

  4.  name: allhosts-serviceentry

  5.  namespace: istio-apps

  6. spec:

  7.  hosts:

  8.  - "*"

  9.  ports:

  10.  - number: 80

  11.    name: http

  12.    protocol: HTTP

  13.  - number: 443

  14.    name: https

  15.    protocol: HTTPS

  16.  - number: 3306

  17.    name: tcp

  18.    protocol: TCP

我们需要确保 istio-ingressgateway 已经映射入 istio-apps 的命名空间中。首先,检查你的 istio-ingressgateway 服务,并指向由该服务创建的负载均衡器的域名。

使用下面的 yaml 配置映射你的域名到 istio-ingressgateway,教程中我们使用 *.yourdomain。在生产环境中需要一个个的映射你的主机(这步操作需要花费一些时间才能生效):

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: Gateway

  3. metadata:

  4.  name: istio-gateway

  5.  namespace: istio-apps

  6. spec:

  7.  selector:

  8.    istio: ingressgateway

  9.  servers:

  10.  - port:

  11.      number: 80

  12.      name: http

  13.      protocol: HTTP

  14.    hosts:

  15.    - "*.yourdomain"

  16.  - port:

  17.      number: 443

  18.      name: https

  19.      protocol: HTTPS

  20.    tls:

  21.      mode: PASSTHROUGH

  22.    hosts:

  23.    - "*.yourdomain"

现在可以准备测试我们的环境了。我已经使用 http(8080)/grpc(8333) 创建了一个应用程序,在测试环境调用第二个应用程序。同时创建了一个部署服务的文件来启动测试。请复制下面的 yaml 文件并应用到你的环境中:

  1. apiVersion: extensions/v1beta1

  2. kind: Deployment

  3. metadata:

  4.    name: application

  5. spec:

  6.  replicas: 1

  7.  template:

  8.    metadata:

  9.      labels:

  10.        name: application

  11.        app: application

  12.        version: 1.0.0

  13.    spec:

  14.      serviceAccountName: default

  15.      containers:

  16.      - name: application

  17.        image: pismotest/istio-application:v1

  18.        ports:

  19.        - containerPort: 8080

  20.          name: http-port

  21.        - containerPort: 8333

  22.          name: grpc-port

  23. ---

  24. apiVersion: v1

  25. kind: Service

  26. metadata:

  27.  name: application

  28. spec:

  29.  ports:

  30.    - name: http

  31.      port: 8080

  32.      targetPort: 8080

  33.    - name: grpc-port

  34.      port: 8333

  35.      targetPort: 8333

  36.  selector:

  37.    name: application

  38. ---

  39. apiVersion: extensions/v1beta1

  40. kind: Deployment

  41. metadata:

  42.    name: applicationtwo

  43. spec:

  44.  replicas: 1

  45.  template:

  46.    metadata:

  47.      labels:

  48.        name: applicationtwo

  49.        app: applicationtwo

  50.        version: 1.0.0

  51.    spec:

  52.      serviceAccountName: default

  53.      containers:

  54.      - name: applicationtwo

  55.        image: pismotest/istio-application:v1

  56.        ports:

  57.        - containerPort: 8080

  58.          name: http-port

  59.        - containerPort: 8333

  60.          name: grpc-port

  61. ---

  62. apiVersion: v1

  63. kind: Service

  64. metadata:

  65.  name: applicationtwo

  66. spec:

  67.  ports:

  68.    - name: http

  69.      port: 8080

  70.      targetPort: 8080

  71.    - name: grpc-port

  72.      port: 8333

  73.      targetPort: 8333

  74.  selector:

  75.    name: applicationtwo

  1. use kubectl apply -f applications.yaml -n istio-apps

现在,我们将创建我们的虚拟服务来映射到我们的应用程序,已便 istio-ingressgateway 可以将流量路由到我们的应用程序中(修改配置中的 application.yourdomain 修改为你的域名

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4.  name: application-ingress

  5.  namespace: istio-apps

  6. spec:

  7.  hosts:

  8.  - "application.yourdomain"

  9.  gateways:

  10.  -  istio-gateway

  11.  http:

  12.  - match:

  13.    - uri:

  14.        prefix: /health

  15.    route:

  16.    - destination:

  17.        port:

  18.          number: 8080

  19.        host: application

  20.    retries:

  21.      attempts: 25

  22.      perTryTimeout: 1s

  23.  - match:

  24.    - uri:

  25.        prefix: /

  26.    route:

  27.    - destination:

  28.        port:

  29.          number: 8333

  30.        host: application

  31.    retries:

  32.      attempts: 25

  33.      perTryTimeout: 1s

虚拟服务将主机映射到任何你想匹配的服务上,在示例中,第一条规则是匹配到服务 http 健康端点,如果匹配失败将跳转到 grpc 服务端口上。在重试的部分可以帮助我们知道网络是否有干扰或有不健康的 Pods。你可以添加更多你需要的匹配项,通过这些规则可以将任何形式的请求匹配到主机上:

  1. - match:

  2.     - uri:

  3.         regex: ".+"

你可以尝试一下方式访问 /health 端点:

  1. curl --request GET \

  2.  --url http://application.yourdomain/health

你将接收到200,同时你的应用也会记录接受到的请求。如果你接收到404,可能是你的虚拟服务没有将你的请求地址映射到你的服务上

请尝试如下方式:

  1. curl --request GET \

  2.  --url http://application.yourdomain/health \

  3.  --header 'propagate: yes'

你的应用程序会请求第二个应用程序,请检查应用程序二的日志记录。

Istio 也可以使用同样的规则映射 grpc 请求。复制应用程序仓库并使用同样的方式创建应用,修改 main.go 中的域名地址并进行尝试。

https://github.com/Stocco/istioapplications

网格的可视化度量

有很多方法来可视化网格中的内容,我将在本节中列举几种。

请注意,Istio 将收集所有需要的度量参数来绘制监控图形和对象,但是对于像 Kiali 和 Jaeger 这样的度量服务,你需要确保应用程序可以传播 Istio injected 的请求头,这样就可以将应用程序的请求历史连接起来。

检查应用程序处理健康功能的示例:https://github.com/Stocco/istioapplications/blob/a3c3275a63a0667f870d054ea5940284b8a100af/main.go#L72

Kiali

Kiali 可以帮助我们了解实时发生的事情。将 kiali 端口暴露到本地,这样就可以查看应用程序:

  1. kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001

点击链接并使用 admin(username)/admin(password) 登录:

  1. http://localhost:20001/console/service-graph/istio-apps?layout=cose-bilkent&duration=10800&edges=responseTime95thPercentile&graphType=versionedApp

你可以看到如下界面:

这样就成功了,Kiali 还有很多工具有待挖掘。

Jaeger

Jaeger 是一个功能强大的监控工具,可以用来监听请求到执行情况以及请求在每个部分中执行的时长。但是,你需要注意的是,如果你需要使用它更多的潜在功能,你需要适当的调整你的代码来传播 Istio injected 的头。如果你需要了解更多关于请求的信息,你需要使用一些工具(例如:opentracing)来获取应用程序内部功能调用的度量数据。

暴露 jaeger 端口和访问权限 http://localhost:16686

  1. kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686

在左边的界面中有一些过滤条件,选择你需要的条件,你可以通过点击查找到的数据查看最新的跟踪路径。选择一条跟踪路径,你可以查看到应用程序中每一个请求的所消耗的准确时间。

如果在应用程序中安装了 opentracing 并在每个功能调用的地方都使用到了,则会有更好的体验。

更多的度量工具

现在有3个应用程序通过 values.yaml 已经安装好了,并使用 Istio 收集了需要度量的数据。尝试使用 grafana,prometheus和servicegraph 检查应用。

使用一下命令暴露应用程序:

  1. kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090

  2. kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 &

  3. kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 &

  4. 提示:

  5.    本教程中 grafana 登录/密码 是 admin/admin(可以在 values.yaml 修改他们),可以使用这个地址查看 servicegraph:

  6.    http://localhost:8088/force/forcegraph.html?time_horizon=3000s&filter_empty=true

智能路由

如果你可以管理应用程序的版本?Istio 可以为 virtualservice.yaml 提供微小的修改。让我们来调整我们的虚拟服务(修改 application.yourdomain 为你的应用程序名

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4.  name: application-ingress

  5.  namespace: istio-apps

  6. spec:

  7.  hosts:

  8.  - "application.yourdomain"

  9.  gateways:

  10.  -  istio-gateway

  11.  http:

  12.  - match:

  13.    - headers:

  14.        myself:

  15.          exact: "yourself"

  16.    route:

  17.    - destination:

  18.        port:

  19.          number: 8080

  20.        host: applicationtwo

  21.  - match:

  22.    - uri:

  23.        prefix: /health

  24.    route:

  25.    - destination:

  26.        port:

  27.          number: 8080

  28.        host: application

  29.    retries:

  30.      attempts: 25

  31.      perTryTimeout: 1s

  32.  - match:

  33.    - uri:

  34.        prefix: /

  35.    route:

  36.    - destination:

  37.        port:

  38.          number: 8333

  39.        host: application

  40.    retries:

  41.      attempts: 25

  42.      perTryTimeout: 1s  

规则遵循优先顺序。现在可以使用前一章节中给的 curl 命令,并将头放到第一条规则中:

  1. curl --request GET \

  2.  --url http://application.pismolabs.io/health \

  3.  --header 'myself: yourself'

你可以从第二个应用程序中查看到日志,而不是在第一个程序!这是因为第一条规则匹配到了。

Grpc ssl 目标规则

如果你在工作中使用过 grpc,你知道将 ssl 应用到 grpc 调用时会存在一个问题。主要是因为你需要将服务服务器的证书放入到代码中才能使 ssl 管道生效。如何在基础设置中设置一些配置达到这样的调用目标呢?

尝试为你的域名创建服务条目和目标规则,并查看你的非 ssl 应用程序对外部 grpc 服务进行了加密的调用!

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: ServiceEntry

  3. metadata:

  4.  name: external-grpc-service-entry

  5. spec:

  6.  hosts:

  7.  - application.yourdomain

  8.  ports:

  9.  - number: 8333

  10.    name: grpc-ssl

  11.    protocol:  GRPC

  12. ---

  13. apiVersion: networking.istio.io/v1alpha3

  14. kind: DestinationRule

  15. metadata:

  16.  name: originate-tls-grpc

  17. spec:

  18.  host: application.yourdomain

  19.  trafficPolicy:

  20.    loadBalancer:

  21.      simple: ROUND_ROBIN

  22.    portLevelSettings:

  23.    - port:

  24.        number: 8333

  25.      tls:

  26.        mode: SIMPLE

有很多的服务条目和目标规则选项,你可以将他们结合起来为应用程序创建更丰富的环境。你可以通过下面的地址查看更多的信息。

  1. https://istio.io/docs/reference/config/istio.networking.v1alpha3/#DestinationRule

我们只是初出茅庐

祝贺你,你已经获得了第一个 Istio 环境应用程序。现在,可以尝试将我的 deployment.yaml 替换成你自己的应用程序并查看它在 Istio 中的运行情况。

使用 Istio 可以获得很多额外的好处,例如特殊的目标规则,自定义策略和自定义度量,但这是下一章的主题。

如果您对本教程有任何疑问、建议或反馈,请随时添加任何意见并与我联系!

社区见!

相关阅读推

通知

为了方便中文用户交流分享 Istio Service Mesh 技术,Istio 社区特地推出了 Istio 中文用户邮件组:https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!forum/istio-users-zh

Istio免费直播课程推荐

本课程来自 IBM 微课程,通过视频直播的方式帮助您快速了解 Istio,每周一期。

  • 11月1日 Istio初探

  • 11月8日 Istio上手

  • 11月15日 Istio的安全管理

  • 11月22日 Envoy

  • 11月29日 使用Istio来监控和可视化微服务

  • 12月6日 Istio mixer - 基本概念,策略、遥测与扩展

  • 12月13日 Istio跨云管理方案解析

  • 12月20日 Istio使用案例:Serverless 平台knative

  • 详情请参考:IBM微讲堂之年度大戏《Istio系列》

点击【阅读原文】跳转到ServiceMesher网站上浏览可以查看文中的链接。

  • SOFAMesh(https://github.com/alipay/sofa-mesh)基于Istio的大规模服务网格解决方案

  • SOFAMosn(https://github.com/alipay/sofa-mosn)使用Go语言开发的高性能Sidecar代理

合作社区

参与社区

以下是参与ServiceMesher社区的方式,最简单的方式是联系我!

  • 加入微信交流群:关注本微信公众号后访问主页右下角有获取联系方式按钮,添加好友时请注明姓名-公司

  • 社区网址:http://www.servicemesher.com

  • Slack:https://servicemesher.slack.com (需要邀请才能加入)

  • GitHub:https://github.com/servicemesher

  • Istio中文文档进度追踪:https://github.com/servicemesher/istio-official-translation

  • Twitter: https://twitter.com/servicemesher

  • 提供文章线索与投稿:https://github.com/servicemesher/trans


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存