五、TSF与ServiceMesh的集成
五、TSF与ServiceMesh的集成
微服务自2014年3月由Martin Fowler首次提出以来,在Spring Cloud、Dubbo等各类微服务框架的帮助下,以燎原之势席卷了整个IT技术界,成为了最主流的分布式应用解决方案。但仍然还有很多问题没有得到根本性的解决,比如技术门槛高、多语言支持不足、代码侵入性强等。如何应对这些挑战成为了下一代微服务首要回答的问题。直到服务网格(Service Mesh)被提出,这 一切都有了答案。
Service Mesh被称为云原生的三驾马车之一(k8s, Service Mesh, serverless)。
学习目标
通过本文的学习,您将可以:
- 了解Service Mesh的概念和应用场景
- 了解Service Mesh的架构
- 掌握TSF接入Service Mesh应用
第一章 Service Mesh的概念
1.1 Service Mesh概念
- 老系统,异构语言的困境:
在介绍Service Mesh之前我们先来看一下上面这个图。使用微服务架构确实给我们的开发带来了很大的便利,前面我们也介绍了使用Spring Cloud作为微服务架构;但是使用Spring Cloud还存 在几个明显的问题:首先Spring Cloud只能使用Java语言做开发,那如果不是Java 语言怎么办? 老系统怎么办,老系统很多情况下可能并没有改造的价值,如果再重新使用Spring Cloud进行重构得不偿失,这些问题是使用Spring Cloud框架无法解决的。既然有问题,人们总是会去寻找解 决方案,经过不断的演变发展,对于异构语言,老系统这种困境目前最好的解决办法就是使用 Service Mesh;接下来我们看一下Service Mesh到底是什么?它是如何帮助我们解决这些困难的。
什么是Service Mesh?
Service Mesh又被称之为“服务网格”,是致力于解决服务间通讯的基础设施层。
Service Mesh 通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起, 但应用程序不需要知道它们的存在。
根据Linkerd CEO William Morgan定义,Service Mesh是用于处理服务间通信的基础设施层, 用于在云原生应用复杂的服务拓扑中实现可靠的请求传递。在实践中,Service Mesh通常是一组 与应用一起部署,但对应用透明的轻量级网络代理。
Service Mesh 通常是由一系列轻量级的网络代理组成的,如上图中的蓝色块就是网络代理(这个网络代理也被称之为Sidecar),绿色块就是我们的应用。各个微服务应用之间的通信都被网络代理劫持,相当于在服务之间加了一个中间层,应用之间要想通信,必须要通过这个中间层;这个网络代理与应用程序部署在一起,但是相对于应用程序来说它是完全不需要知道有这个网络代理的。
接下来我们看一下这个网络代理(Sidecar)到底是什么?
1.1.1 Sidecar 模式
什么是Sidecar模式?
Sidecar模式是一种将应用功能从应用本身剥离出来作为单独进程的方式。该模式允许我们向应用无侵入添加多种功能,避免了为满足第三方组件需求而向应用添加额外的配置代码。
Sidecar 在软件系统架构中特指边车模式。这个模式的灵感来源于我们生活中的边三轮:即在两轮摩托车的旁边添加一个边车的方式扩展现有的服务和功能。
Sidecar模式是一种将应用功能从应用本身剥离出来作为单独进程的方式。该模式允许我们向应用无侵入添加多种功能,避免了为满足第三方组件需求而向应用添加额外的配置代码。
Sidecar模式如何工作(如上图):
- Service Mesh层可以位于应用程序侧的Sidecar容器中,同一sidecar的多个副本可以附在每个应用旁。
- 来自单个服务的所有传入和传出网络流量均通过Sidecar代理,完成微服务之间的流量管理、 遥测数据收集以及策略的执行等等。从某种意义上来说,服务对于网络是无感知的,只知道所附加的sidecar代理。这就是Sidecar模式工作的本质,它将网络依赖抽象成了Sidecar。
1.1.2 Service Mesh 架构分层
Service Mesh 架构分层
- 数据面( Data Plane ):由独立部署的智能 代理进行组成,接管及控制微服务进程间的 业务数据流量。
- 控制面( Control Plane ):对数据面进行管 理及配置流量路由,策略加强及统计数据采集。
在Service Mesh中,我们需要了解Data Plane和Control Plane两个概念
- Data Plane的作用是处理网格内服务间的通信,并完成服务发现、负载均衡、流量管理、健康检查等功能;
- Control Plane的作用是管理和配置Sidecar来执行策略并收集遥测(telemetry)
1.1.3 Service Mesh 开源项目
Service Mesh 开源项目:
- Linkerd :William Morgan创办的Buoyant 公司开发
- Envoy :由 Matt Klein 个人开发(Lyft 工程师)
- Istio :2017 年 5 月 24 日首发布,由 Google、IBM 和 Lyft 联合开发
- Conduit : Linkerd 的下一代产品
Service Mesh 开源项目简介:
- Linkerd:第一代 Service Mesh,2016 年 1 月 15 日首发布,业界第一个 Service Mesh 项目, 由 Buoyant 创业小公司开发(前 Twitter 工程师),2017 年 7 月 11 日,宣布和 Istio 集成, 成为 Istio 的数据面板。
- Envoy:第一代 Service Mesh,2016 年 9 月 13 日首发布,由 Matt Klein 个人开发(Lyft 工 程师),之后默默发展,版本较稳定。
- Istio:第二代 Service Mesh,2017 年 5 月 24 日首发布,由 Google、IBM 和 Lyft 联合开发, 只支持 Kubernetes 平台,2017 年 11 月 30 日发布 0.3 版本,开始支持非 Kubernetes 平台, 之后稳定的开发和发布。
- Conduit:第二代 Service Mesh,2017 年 12 月 5 日首发布,由 Buoyant 公司开发(借鉴 Istio 整体架构,部分进行了优化),对抗 Istio 压力山大,也期待 Buoyant 公司的毅力。
1.1.4 Istio 架构
Istio 服务网格逻辑上分为数据平面和控制平面:
数据平面由一组以 sidecar 方式部署的智能代理 (Envoy)组成。这些代理可以调节和控制微服务及 Mixer 之间所有的网络通信。
控制平面负责管理和配置代理来路由流量。 此外控制平面配置 Mixer 以实施策略和收集遥测数据。
Istio的很多设计理念的确非常吸引人,又有 Google 和 IBM 两个巨人加持,所以其竞争力非常之强,如上图是Istio的架构图,在TSF中也是采用的Istio/Envoy开源项目作为Service Mesh的落地方案。
Proxy:上图中的Proxy就是采用的Envoy代理(Envoy是一个高性能的C++写的proxy转发器),
Envoy: 是lstio的数据面,扮演sidecar的功能,协调服务网格中所有服务的出入站流量,并提供服务发现、负载均衡、限流熔断等能力,还可以收集大量与流量相关的性能指标。
Pilot:负责部署在service mesh中的Envoy实例的生命周期管理。本质上是负责流量管理和控制, 是将流量和基础设施扩展解耦,这是Istio的核心。感性上,可以把Pilot看做是管理sidecar的 sidecar, 但是这个特殊的sidacar并不承载任何业务流量。
Mixer:Mixer 是一个独立于平台的组件,负责在服务网格上执行访问控制和使用策略,并从 Envoy 代理和其他服务收集遥测数据,Mixer可以认为是其他后端基础设施(如数据库、监控、 日志、配额等)的sidecar proxy。
Citadel:Citadel 通过内置身份和凭证管理可以提供强大的服务间和最终用户身份验证。可用于升级服务网格中未加密的流量,并为运维人员提供基于服务标识而不是网络控制的强制执行策略的能力
第二章 为什么需要Service Mesh
2.1 Service Mesh典型场景
- Service Mesh 并非新出现的功能。Web 应用程序一直需要自己管理复杂的服务间通信, Service Mesh 的起源可以追溯到过去十五年来这些应用的发展。
- 当微服务存在多语言场景,底层并非使用SpringBoot框架开发,旧系统微服务化,希望服务框架的升级无需业务联动升级都推荐使用Service Mesh方式。
2.2 Service Mesh优势
Service Mesh优势?
- 轻量级网络代理
- 应用程序无感知
- 多编程语言应用兼容。
- 业务代码零侵入,代码无须改造。
- 解耦应用程序的重试、超时、监控、追踪和服务发现;
- 实施便利:在mesh部署完成后,应用仅需退回原始的直接调用模式即可使用mesh带来的收益。
如果用一句话来解释什么是 Service Mesh,可以将它比作是应用程序或者说微服务间的 TCP/IP, 负责服务之间的网络调用、限流、熔断和监控。对于编写应用程序来说一般无须关心 TCP/IP 这 一层(比如通过 HTTP 协议的 RESTful 应用),同样使用 Service Mesh 也就无须关心服务之间 的那些原来是通过应用程序或者其他框架实现的事情,比如 Spring Cloud、OSS,现在只要交 给 Service Mesh 就可以了。
微服务更像是一个服务之间的生态,专注于服务治理等方面,而服务网格更专注于服务之间的通信,以及和 DevOps 更好的结合。
优点主要有几点:
- 应用内部不必再嵌入复杂的微服务Client:应用不再涉及框架相关的服务发现等功能,每个接口仅需配置一个本地地址进行调用,不必知道集群的情况。
- 语言无关:由于不需嵌入语言特定的Client,使用标准协议通信的双方均可由任意语言编写, 即使是外采的二进制系统,也可以简单的嵌入集群中。
- 大量减少应用间连接数,数据库连接数:同一主机的调用方所涉及的连接可以被Proxy连接复用,因此应用间连接数可大幅减少,同时也避免避免微服务带来的数据库连接数爆炸问题。
- 提升通信加密的效率:可以将通信加密统一放置于由高运行性能语言编写的Proxy上,而非由运行效率较低的应用来进行。
- 调用过程的集中诊断:由于请求均通过Proxy进行,可以便利的进行统计并收集日志、报文等。
- 运维控制的统一认证和调度:由于服务发现和调用路由放置在了独立的系统中,运维可以完全掌控调用的过程,包括设置调用的路径,调用权限等。
- 容器友好:service mesh框架同K8S等编排系统集成度较高,可无缝协同运行。
- 实施便利:mesh部署完成后,应用仅需退回原始的直接调用模式即可使用mesh带来的收益。
第三章 TSF Service Mesh架构
3.1 TSF Mesh简介
- TSF Mesh是腾讯云TSF团队遵循Service Mesh设计理念,基于CNCF云原生开源软件Istio/envoy进行构建的一款服务框架产品。
- TSF Mesh与开源ServiceMesh相比具有如下优势:
- 与k8s解耦,能同时支持虚拟机及容器服务进行部署及互通;
- 与SpringCloud应用可无缝对接互通;
- 支持API级别的服务治理;
- 支持基于本地配置及远程配置的服务定义及自动注册。
- TSF Service Mesh (以下简称为 TSF Mesh) 是一个基础设施层,用于处理服务间的通信。TSF Mesh 是由一系列轻量级网络代理组成,这些代理(又称 sidecar),与应用程序部署在一起, 而应用程序不感知 sidecar 的存在。
- TSF Mesh 是处于 TCP / IP 之上的一个抽象层。TCP 解决了网络端点键字节传输问题,TSF Mesh 解决服务节点间请求的路由问题。
- TSF Mesh 具有如下优势:
- 多编程语言应用兼容;
- 业务代码零侵入,代码无须改造。
- CNCF,全称Cloud Native Computing Foundation(云原生计算基金会),口号是坚持和整合开源技术来编排容器作为微服务架构的一部分 ,其作为致力于云原生应用推广和普及的一支重要力量。
- Istio主要由Envoy、Pilot、Mixer三部分组成
- Envoy:以sidecar的形式和应用程序运行与同一个pod中,通过修改iptables来代理应用程序的所有出入流量
- Pilot:接受系统管理员发出的指令或者规则,遥控所有Envoy的行为
- Mixer:从Envoy处获取流量属性,根据自定义的属性匹配规则进行流量处理,如:流量限制、 日志记录等
3.2 TSF Mesh架构
- TSF Mesh整体架构:
- TSF Mesh的整体架构如上图;
- TSF Mesh组网架构从逻辑上划分为控制面和数据面两大部分
- 控制面主要提供配置及控制指令支撑sidecar的正常运行
- 数据面主要是提供通信代理(sidecar)来进行透明的服务调用,支撑正常的业务流程
3.2.1 基本实现原理
- 控制面,数据面架构如上图;
- 控制面组件
- api-server:提供mesh的对外REST API入口,通过API可以进行mesh的功能配置管理
- pilot:mesh调度控制中心,提供服务注册信息、以及服务配置下发,以控制数据面组件的功能
- mixer:mesh策略控制及采集分析中心,提供访问策略控制的能力
- 数据面组件 (sidecar)
- pilot-agent:负责环境的初始化及清理,envoy/mesh-dns的生命周期管理
- envoy:数据面,通信代理,提供服务与服务之间RPC通信的能力
- mesh-dns:提供mesh的组件及业务服务的本地域名解析的能力
- 实现原理如下:
- Proxy,Pilot-agent组件在虚拟机创建或者容器创建的时候已经安装好了,应用(如上图中的 ServiceA ,ServiceB)部署到虚拟机/容器时,Pilot-agent会根据应用中的服务描述文件自动进行服务注册,最终通过Pilot把服务与配置注册到Consul 服务注册中心。
- Proxy使用envoy原生的健康上报能力把节点健康信息上报到Pilot中;同时提供服务发现功能; Proxy通过修改iptables代理了应用(如上ServiceA,ServiceB)的所有出入流量。
- 如上图ServiceA要访问ServiceB是通过服务名称访问,其中就涉及到Mesh-dns(数据面组件, 提供mesh的组件及业务服务的本地域名解析的能力),首先访问会经过的Mesh-dns组件进行解析,解析完对应的服务名称以后就可以找到对应的服务节点进行访问。
- APIServer对接Consul,负责配置的CURD,屏蔽底层配置中心,对外提供简单的REST接口;
3.2.2 服务寻址
- Mesh-dns解析如上图:
- 应用(app)发起的请求通过iptables重定向到mesh-dns,mesh-dns解析服务名后就可以找到对应的服务节点;
- 如果不是服务名访问的方式会升级到其它非服务名DNS服务器解析,从而兼容服务名访问与非服务名访问方式;
- mesh-dns 通过 inotify 监听 /etc/resolv.conf,可以随时获取环境中 dns 配置的更改。
第四章 TSF接入Service Mesh应用
4.1 基本实现原理
TSF Mesh实现原理:
- TSF Mesh 可以代理使用云服务器或者容器部署的应用。
- Sidecar 和服务运行在同一个 Pod 中,与 Pod 共享网络。
- Sidecar 与服务的关系如下:
- Sidecar 代理服务向注册中心注册服务相关信息,以便其他服务发现自身。
- Sidecar 作为 Pod 内服务的 HTTP 代理,可以自动发现其他服务。
TSF Mesh的基本实现原理参照3.2内容。
4.2 TSF Mesh使用场景
- TSF Mesh 主要有三种使用场景:
- 仅服务消费者作为 Mesh 应用部署。
- 仅服务提供者作为 Mesh 应用部署。
- 服务消费者和服务提供者均作为 Mesh 应用部署
4.2.1 TSF Mesh使用场景1
仅服务消费者作为 Mesh 应用部署
服务提供者使用 TSF-Spring Cloud 框架实现,注册到服务注册中心;
服务消费者作为 Mesh 应用部署,由 Sidecar 注册到服务注册中心。
4.2.2 TSF Mesh使用场景2
仅服务提供者作为 Mesh 应用部署
服务提供者作为 Mesh 应用部署,由 Sidecar 注册到服务注册中心;
服务消费者使用 TSF-Spring Cloud 框架实现,注册到服务注册中心。
4.2.3 TSF Mesh使用场景3
服务消费者和服务提供者均作为 Mesh 应用部署
服务提供者作为 Mesh 应用部署,由 Sidecar 注册到服务注册中心;
服务消费者作为 Mesh 应用部署,由 Sidecar 注册到服务注册中心。
4.3 TSF Mesh应用接入
Demo示例说明
Demo for Python 提供了 3 个 Python 应用及 Dockerfile:
- user
- shop
- promotion
3个应用之间的调用关系是:user => shop => promotion
虚拟机demo下载地址:
https://main.qcloudimg.com/raw/cfc64e09c79e05581275ad6baaa1b20c/tsf_python_vm_ demo-1108.zip
容器部署demo下载地址:
https://main.qcloudimg.com/raw/449b92688fabd8903e1486f1d00577be/tsf_python_doc ker_demo-1115.zip
开发说明:
以 Python 应用说明如何改造来接入 TSF。Python 服务代码本身不需要修改,只需要修改服务间调用的 host。
Mesh 应用接入步骤:
Demo工程详细概述:
下面以 Python 应用为例说明如何改造代码来接入 TSF。Python 服务代码本身不需要修改,只需要修改服务间调用的 host。
将原来的 IP:Port 替换为服务名。
端口使用 80 或者 443。
其他代码不做修改。
4.3.1 开发说明
步骤一:
- 开发Python应用(以虚拟机 tsf_python_vm_demo项目为例):
- userService.py 和 common.py:Python 应用程序
- 开发Python应用(以虚拟机 tsf_python_vm_demo项目为例):
步骤二:
修改应用中IP:Port访问方式为服务名访问
此处把ip地址访问改为服务名访问以后,后续所有的访问服务方式的调用都会被Sidecar代理拦截, 拦截后会先经过mesh-dns进行本地域名解析(此处名称就是服务的名称,也可以理解为就是本地域名),最终就可以找到对应的服务节点。
其中第一行sidecarPort = 80;这里的sidecarPort 只是命名而已,应用在改造之前只是Python 应用程序,无需任何跟Mesh相关的开发。
虚拟机demo下载地址:
https://main.qcloudimg.com/raw/cfc64e09c79e05581275ad6baaa1b20c/tsf_python_vm_ demo-1108.zip
4.3.2 开发说明 - 虚拟机篇
步骤三:
添加Mesh应用相应脚本(虚拟机部署方式)
start.sh:启动脚本,示例:如图一。
stop.sh:停止脚本,示例:如图二。
cmdline:检查进程是否存活的文件, 示例:如图三
spec.yml:服务描述文件。
apis 目录:存放 API 定义的目录。
此处start.sh;stop.sh脚本只是用来启动应用;应用部署后,启动的时候就会自动调用start.sh脚本,停止的时候就会调用stop.sh脚本。
具体脚本内容见demo中脚本
虚拟机工程目录,以 tsf_python_vm_demo 中的 userService 为例说明虚拟机应用工程目录:
userService.py 和 common.py:Python 应用程序
start.sh:启动脚本。
stop.sh:停止脚本。
cmdline:检查进程是否存活的文件。
spec.yml:服务描述文件,具体解释请参考 Mesh 开发使用指引。
apis 目录:存放 API 定义的目录, 具体解释请参考 Mesh 开发使用指引。
4.3.3 开发说明 – 容器应用篇
步骤三:
添加Mesh应用相应脚本(容器部署方式)
spec.yml:服务描述文件。
apis 目录:存放 API 定义的目录。
start.sh:在启动脚本中创建 /opt/tsf/app_config/ 目录,然后将 spec.yml 文件和 apis 目 录拷贝到 /opt/tsf/app_config/ 中。
start.sh :目录中 start.sh 脚本来启动 Python 应用。
Dockerfile:打包生成镜像文件
start.sh注意事项:您需要在容器启动后通过用户程序的启动脚本(start.sh)拷贝目录,不可以在 Dockerfile 中提前拷贝;
如下是start.sh示例代码:
1
2
3
4
5
6#! /bin/bash
mkdir -p /opt/tsf/app_config/apis
cp /root/app/userService/spec.yaml /opt/tsf/app_config/
cp -r /root/app/userService/apis /opt/tsf/app_config/
cd /root/app/userService/
python ./userService.py 80 1>./logs/user.log 2>&1
容器部署demo下载地址:
https://main.qcloudimg.com/raw/449b92688fabd8903e1486f1d00577be/tsf_python_doc ker_demo-1115.zip
容器应用工程目录,以 tsf_python_docker_demo 中的 demo-mesh-user 为例说明容器应用工 程目录。
- Dockerfile:使用 userService 目录中 start.sh 脚本来启动 Python 应用。
- userService目录:基本结构和 tsf_python_vm_demo中 userService 目录类似,除了没有 stop.sh 和 cmdline 文件。
- start.sh:在启动脚本中创建 /opt/tsf/app_config/ 目录,然后将 spec.yml 文件和 apis 目录拷贝到 /opt/tsf/app_config/ 中。
4.3.4 开发说明(续)
步骤四:
- 前面的改造是为普通应用转变为Mesh应用提供必要的脚本以及配置信息;
- 部署应用到TSF以后,Mesh的所有底层操作由平台完成,只需要部署成功就可以把普通应用转变为Mesh应用:
虚拟机部署:
容器部署:
注意此处是改造原有应用,然后添加对应脚本,为应用转变为TSF Mesh应用提供必要的脚本以及配置信息;应用部署到TSF以后Mesh的所有底层操作都有平台完成,只要完成部署成功以后, 应用就已经转变为Mesh应用。
具体部署操作将在下一部分内容介绍;
官网文档:
4.3.5 服务定义和注册
在应用程序所在目录中设置创建 spec.yml 文件,该文件用于描述服务信息
sidecar 制定了服务名、端口号和健康检查URL
sidecar 根据服务描述文件将服务注册到注册中心
1
2
3
4
5
6
7
8
9
10apiVersion: v1
kind: Application
spec:
services:
- name: user # service name
ports:
- targetPort: 8091
protocol: http
healthCheck:
path: /health
TSF Mesh应用可以通过sidecar实现服务注册与发现,这里就需要用到spec.yml配置文件,应用部署启动的时候同时会自动启动Sidecar,在spec.yml配置文件中就定义了服务的相关信息,如服务名,端口,健康检查url等,通过在spec.yml配置的服务名称,端口,Sidecar会自动把服务注册到TSF的服务注册中心,同时也会通过Sidecar代理应用的出入站流量。
4.4 Mesh 应用-API 定义和上报
API 定义文件(如 user.yml)
API 定义文件放在 apis 目录下
文件名规则: <服务名>.yml
符合 openapi 3.0 规范
sidecar 根据api 定义上报到配置中心
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16openapi: 3.0.0
info:
version: "1.0.0"
title: user service
paths:
/api/v6/user/create:
get:
responses:
'200':
description: OK
'401':
description: Unauthorized
'402':
description: Forbidden
'403':
description: Not Found
TSF 支持 Mesh 应用 API 上报功能。在应用程序所在目录中创建 apis 目录,用来放置服务的 API 定义。一个服务对应一个 yaml 文件,文件名就是服务名,如 petstore 服务对应的配置是 petstore.yaml。API 遵循 OPENAPI 3.0 规范 。user.yml 的 API 定义如上述代码所示:
官网文档:https://cloud.tencent.com/document/product/649/19049(参考其中的API 定义和上报)
添加API配置文件后,在TSF的服务详情界面可以显示api列表。
在定义了API配置文件后,框架会自动将接口注册到服务注册中心,实现接口级别的路由、鉴权和限流。
4.5 Mesh 应用-服务治理功能
Mesh 应用支持服务限流、服务鉴权、服务路由功能,无须额外依赖 SDK
Mesh 支持通过 HTTP Header 设置自定义标签
以 Python 应用为例说明如何设置自定义标签,如下代码:(其中第三行代码: custom-key是自定义标签的名称,custom-value是自定义标签的值)。
1
2
3
4>>> import requests
>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'custom-key': 'custom-value'}
>>> r = requests.get(url, headers=headers)
具体操作步骤会在TSF服务治理中介绍,这里大家先了解概念即可
4.6 Mesh 应用-采集日志
- 创建日志配置项时,选择日志格式为“无解析规则”,会使用日志采集时 间作为日志检索时的时间参数
- 官网文档:https://cloud.tencent.com/document/product/649/18196
- 具体操作步骤会在TSF的日志管理功能中详细介绍。
思考题
Service Mesh的应用场景有哪些?
相对于Spring Cloud框架,Service Mesh有哪些独特的优势?
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!