本系列文章将分为两部分,在此我们将探讨Istio服务网格中一部分,即可观测性工具集。这些工具包含了Jaeger、Kiali、Prometheus以及Grafana。为辅助我们此行探索,我们将在GCP上部署基于Go的微服务参考平台到GKE上去。

由Cindy Sridharan撰写,O’Reilly出版的《分布式系统可观测性[1]》一书在第四章节中详细地介绍了“可观测性的三大支柱”。在继续下文之前,我强烈建议你阅读下这篇在线摘录。关于可观测性资讯的另一大来源是honeycomb.io,一个生产系统可观测性工具的开发商,由知名的行业思想领袖Charity Majors领导。这个站点上面发布了很多关于可观测性的文章、博文、白皮书和博客。
随着现代分布式系统变得越发复杂,想具备观察这些系统的能力需要同样在设计之初就考虑到适配如此复杂环境的现代化的工具。传统的日志记录和监控系统通常与当今的混合和多云、基于多种语言、事件驱动、基于容器和无服务器、可无限扩展的、临时计算的平台相竞争。
像Istio服务网格这类工具试图通过提供与几种同类最佳的开源遥测工具的原生集成方案来解决可观测性带来的挑战。Istio的集成包括Jaeger用于分布式跟踪,Kiali用于分布式系统可视化,Prometheus和Grafana用于度量指标收集、监控和警报。同时结合云平台原生的监控和日志服务,例如谷歌云平台上Google Kubernetes Engine(GKE)的Stackdriver,我们为现代化的分布式应用打造完整的可观测平台。
该参考平台旨在生成基于HTTP的服务到服务,基于TCP的服务到数据库以及基于TCP的服务到队列再到服务(RabbitMQ)的IPC(进程间通信)。服务A调用服务B和C,服务B调用服务D和E,服务D生产消息到RabbitMQ队列供服务F来消费并写入到MongoDB,依此类推。当这个系统部署到运行Istio服务网格的Kubernetes集群中时,可以使用Istio的可观测性工具来观察这些分布式通信。
服务响应
在该平台上,每个上游服务通过返回一个小的JSON信息负载(在源码中称为问候语)来响应下游服务的请求。

这些请求响应在调用链中聚合,进而产生给边缘服务的一系列服务响应,并返回给UI界面,最终展示在用户的浏览器中。响应聚合功能只是简单验证服务到服务间通信,Istio组件和遥测工具都能否正常工作。

所有的Go微服务都包含一个/ping和/health端点。/health端点用于配置Kubernetes的存活以及就绪探针。此外,边缘服务A使用响应头access-control-allow-origin: *用来配置Cross-Origin Resource Sharing(CORS)[2]。CORS允许用于浏览器来调用位于与UI不同子域的/ping端点。相关服务A的源码可以在此[3]查看。
在本次演示中,MongoDB数据库将被托管到GCP的外部,即MongoDB Atlas,它是一个基于云的MongoDB即服务平台。同样的,RabbitMQ队列服务将被托管到CloudAMQP,这是一个基于云的RabbitMQ即服务平台。我曾在之前的几篇文章中使用过这两种Saas供应商。使用外部服务将帮助我们了解Istio和它的可观测性工具是如何为位于Kubernetes集群中和外部系统的通信提供遥测的。 (如果你想深入快速学习Kubernetes, 可以报名参加我们组织的为期3天的Kubernetes实战培训 ,一线资深讲师带你从0开始上手Kubernetes。)
服务F[4]消费来自RabbitMQ队列的消息,服务D将消息写入队列并写入到MongoDB中,这些服务都能通过对应链接打开直接查看源码。
git clone --branch master --single-branch --depth 1 --no-tags \
https://github.com/garystafford/k8s-istio-observe-backend.git
Kubernetes资源中引用到的相关Go服务和UI界面的容器镜像,都可以在Docker Hub上找到。Go服务镜像是使用官方的Golang Alpine来作为基础镜像,包含了Go 1.12.0版本。使用Alpine镜像来编译源码将能保证容器镜像尽可能地小并且包含更小的可攻击面。
系统要求

创建MongoDB Atlas数据库集群
创建CloudAMQP RabbitMQ集群
根据自己的环境调整Kubernetes的资源文件和脚本
在GCP上创建GKE集群
使用Helm在GKE集群中部署Istio 1.1.0版本
为平台中需要暴露访问的资源创建DNS记录
部署所有Go微服务,Angular UI和与GKE相关联的资源
测试或为你的平台排障
在第二篇中查看观察的结果
MongoDB Atlas集群
MongoDB Atlas目前提供有四种定价方案,包含免费版、基础版、高级版和企业版。这些方案范围从最小的共享内存和512MB存储的M0规模的MongoDB集群,到最高具有488GB内存和3TB存储的大型M400 MongoDB集群。
在本文中,我在GCP的us-central1地区创建了一个M2大小的MongoDB集群,并为该演示创建了一个数据库账户,该帐户将用于连接GKE上运行的八个基于Go的微服务的其中四个。

最初我使用了一个M0大小的集群,但发现计算资源不足以支撑来自这些Go语言的微服务。在此我建议至少使用M2大小乃至更大的集群。
配置MongoDB Atlas的Istio ServiceEntry
在external-mesh-mongodb-atlas.yaml文件中添加MongoDB Atlas主机地址。此文件允许从GKE上的四个微服务到外部MongoDB Atlas集群的出口流量。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mongodb-atlas-external-mesh
spec:
hosts:
- { { your_host_goes_here }}
ports<