微服务架构之 Service Mesh 初体验

Posted IT实战联盟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务架构之 Service Mesh 初体验相关的知识,希望对你有一定的参考价值。

前言

⽬前,微服务的架构⽅式在企业中得到了极⼤的发展,主要原因是其解决了传统的单体架构中存在的问题。当单体架构拆分成微服务架构就可以⾼枕⽆忧了吗?显然不是的。微服务架构体系中同样也存在很多的挑战,

⽐如:原来的单个应⽤拆分成了许多分散的微服务,它们之间相互调⽤才能完成⼀个任务,而⼀旦某个过程出错(组件越多,出错的概率也就越⼤),就⾮常难以排查。

如果⽤户请求的响应太慢,我们就需要知道到底哪些地⽅⽐较慢?整个链路的调⽤各阶段耗时是多少?哪些调⽤是并发执⾏的,哪些是串⾏的?这些问题需要我们能⾮常清楚整个集群的调⽤以及流量情况。

微服务拆分成这么多组件,如果单个组件出错的概率不变,那么整体有地⽅出错的概率就会增⼤。服务调⽤的时候如果没有错误处理机制,那么会导致⾮常多的问题。

应⽤数量的增多,对于⽇常的应⽤发布来说也是个难题。应⽤的发布需要⾮常谨慎,如果应⽤都是⼀次性升级的,出现错误会导致整个线上应⽤不可⽤,影响范围太⼤。

很多情况我们需要同时存在不同的版本,使⽤AB 测试验证哪个版本更好。

为了保证整个系统的安全性,每个应⽤都需要实现⼀套相似的认证、授权、HTTPS、限流等功能。

等等一系列问题,那么有没有什么方案可以解决这些问题?没错,Service Mesh就是为了解决以上问题才出的。

什么是Service Mesh

Service Mesh主要解决的问题就希望开发⼈员对于业务的聚焦,服务发现、服务注册、负载均衡等对于开发⼈员透明,可以更加专注业务逻辑的实现。

如果将为微服务提供通信服务的这部分逻辑从应⽤程序进程中抽取出来,作为⼀个单独的进程进⾏部署,并将其作为服务间的通信代理,可以得到如下图所示的架构:

Sidecar,翻译成中⽂是边⻋,⾮常的形象。

当服务⼤量部署时,随着服务部署的Sidecar代理之间的连接形成了⼀个如下图所示的⽹格,该⽹格成为了微服务的通讯基础设施层,承载了微服务之间的所有流量,被称之为Service Mesh(服务⽹格)。

微服务架构之 Service Mesh 初体验

服务⽹格⽤来描述组成这些应⽤程序的微服务⽹络以及它们之间的交互。随着服务⽹格的规模和复杂性不断的增⻓,它将会变得越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、度量和监控等。服务⽹格通常还有更复杂的运维需求,⽐如A/B 测试、⾦丝雀发布、速率限制、访问控制和端到端认证。所有就有了二代Service Mesh出现:

微服务架构之 Service Mesh 初体验

为了更⽅便地对服务⽹格中的代理进⾏统⼀集中控制,在服务⽹格上增加了控制⾯组件。

微服务架构之 Service Mesh 初体验

第一代Service Mesh由一系列独立运行的单机代理服务构成,为了提供统一的上层运维入口,演化出了集中式控制面板,所有的单机代理组件通过和控制面板交互进行网络拓扑策略的更新和单机数据的汇报。这就是以Istio为代表的第二代Service Mesh。

Service Mesh的定义:

服务网格是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但对应用程序透明。

关键名词解释:

  • 基础设施层、请求可在这些拓扑中可靠地穿梭:这两个词加起来描述了Service Mesh的定位和功能,是不是似曾识?没错,你一定想到了TCP;

  • 网络代理:这描述了Service Mesh的实现形态;

  • 对应用透明:这描述了Service Mesh的关键特点,正是由于这个特点,Service Mesh能够解决以Spring Cloud为代表的第二代微服务框架所面临的三个本质问题;

Service Mesh优点

  • 屏蔽分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),服务只用关注业务逻辑;

  • 真正的语言无关,服务可以用任何语言编写,只需和Service Mesh通信即可;

  • 对应用透明,Service Mesh组件可以单独升级;

Service Mesh目前也面临一些挑战

  • Service Mesh组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销;

  • Service Mesh组件接管了网络流量,因此服务的整体稳定性依赖于Service Mesh,同时额外引入的大量Service Mesh服务实例的运维和管理也是一个挑战;

好了到这里,我相信你应该大概知道Serive Mesh到底是个什么思想了,下面我看看基于Service Mesh思想的产品有哪些?

Service Mesh 产品

CNCF

CNCF 是⼀个开源软件基⾦会,致⼒于使云原⽣计算具有普遍性和可持续性。云原⽣计算使⽤开源软件技术栈将应⽤程序部署为微服务,将每个部分打包到⾃⼰的容器中,并动态编排这些容器以优化资源利⽤率。云原⽣技术使软件开发⼈员能够更快地构建出⾊的产品。
常⽤的已经毕业的云原⽣项⽬:Kubernetes、Prometheus、Jaeger、Envoy、Containerd。

Linkerd

Linkerd是Buoyant公司2016年率先开源的⾼性能⽹络代理程序,是业界的第⼀款Service Mesh产品,甚⾄可以说Linkerd的诞⽣标志着Service Mesh时代的开始,其引领后来Service Mesh的快速发展。
其主要⽤于解决分布式环境中服务之间通信⾯临的⼀些问题,⽐如⽹络不可靠、不安全、延迟丢包等问题。Linkerd使⽤Scala语⾔编写,运⾏于JVM,底层基于Twitter的Finagle库,并对其做相应的扩展。
最主要的是Linkerd具有快速、轻量级、⾼性能等特点,每秒以最⼩的时延及负载处理万级请求,易于⽔平扩展,经过⽣产线测试及验证,可运⾏任何平台的产线级Service Mesh⼯具。

Envoy

Envoy也是⼀款⾼性能的⽹络代理程序,于2016年10⽉份由Lyft公司开源,为云原⽣应⽤⽽设计可作为边界⼊⼝,处理外部流量,当然,也作为内部服务间通信代理,实现服务间可靠通信。
Envoy的实现借鉴现有产线级代理及负载均衡器,如nginx、HAProxy、硬件负载均衡器及云负载衡器的实践经验,同时基于C++编写及Lyft公司产线实践证明,Envoy性能⾮常优秀、稳定。
Envoy既可⽤作独⽴代理层运⾏,也可作为Service Mesh架构中数据平⾯层,因此通常Envoy跟服运⾏在⼀起,将应⽤的⽹络功能抽象化,Envoy提供通⽤⽹络功能,实现平台及语⾔⽆关。

Istio

2017年5⽉24⽇,Google, IBM 和Lyft 共同发布Istio 的第⼀个公开版本(0.1)。Istio为⼀款开源的微服务提供服务间连接、管理以及安全保障的平台软件,⽀持运⾏在Kubernetes、Mesos等容器管理⼯具,但不限Kubernetes、Mesos,其底层依赖于Envoy。
Istio提供⼀种简单的⽅法实现服务间的负载均衡、服务间认证、监控等功能,⽽且⽆需应⽤层代调整。其控制平⾯由Pilot、Citadel 和Galley组成,数据平⾯由Envoy实现,通常情况下,数据平⾯理Envoy以sidecar模式部署,使得所有服务间的⽹络通信均由Envoy实现,⽽Istio的控制平⾯则负责务间流量管理、安全通信策略等功能。

Conduit

Conduit于2017年12⽉发布,作为由Buoyant继Linkerd后赞助的另⼀个开源项⽬。Conduit旨在彻底简
化⽤户在Kubernetes使⽤服务⽹格的复杂度,提⾼⽤户体验,⽽不是像Linkerd⼀样针对各种平台进⾏
优化。

国内产品

国内很多团队也已经在着⼿研究了,这些团队主要分为四类体系:

  • 以蚂蚁⾦服为⾸的开源系:蚂蚁⾦服⾃研的SOFA (Scalable Open Financial Architecture)Mesh 在开始的时候⾛的就是开源路线,他们参考了Istio 及Envoy 的设计思想,重新实现了⾃⼰的Service Mesh 系统,旁路⽹关(Sidecar)基于Go 语⾔,该系统的前身是已经开源的SOFA RPC 框架。蚂蚁⾦服于2018 年7 ⽉正式将其开源,正式的可以⽤于⽣产的框架可能还需要⼀些时间。

  • 以华为为代表的⾃研系:华为可能在Service Mesh 概念出来前就已经有类似的想法了,只是没有抽取出⼀个公共的概念。⽆论是华为早期的HSA 还是之后出现的CSE Mesher,都是对ServiceMesh 的探索。CSE Mesher 的整个架构都是基于华为⾃身微服务架构经验研发的,其Sidecar 也是⽤Go 语⾔编写的。如其官⽅⽂档所述,其资源占⽤⾮常⼩,常规状态下仅为30MB。

  • 以腾讯为代表的拿来主义系:腾讯的Tencent Service Mesh对开源的产品(如Istio)进⾏定制,强化吸收后再加⼊⾃身特殊的业务逻辑。腾讯选择的Sidecar是Envoy,使⽤C++编写,⽐较符合腾讯的技术栈。其公开的技术并不多,仍然以内部⼩范围使⽤为主。

  • 以UCloud 为代表的适配系:主要也是依赖开源⽅案,但不是完全将其产品引⼊,只是对其中⼏个关键部分添加适配器,以适应企业现有产品,以最⼩的变更成本引⼊Service Mesh 体系。


我们今天主要研究下Istio

Istio简介

Istio架构


微服务架构之 Service Mesh 初体验

实际上Istio 就是Service Mesh 架构的⼀种实现,服务之间的通信(⽐如这⾥的Service A 访问ServiceB)会通过代理(默认是Envoy)来进⾏。

⽽且中间的⽹络协议⽀持HTTP/1.1,HTTP/2,gRPC 或者TCP,可以说覆盖了主流的通信协议。代理这⼀层,称之为数据平⾯。

控制平⾯做了进⼀步的细分,分成了Pilot、Citadel 和Galley,它们的各⾃功能如下:

  • Pilot:为Envoy 提供了服务发现,流量管理和智能路由(AB 测试、⾦丝雀发布等),以及错误处理(超时、重试、熔断)功能。

  • Citadel:为服务之间提供认证和证书管理,可以让服务⾃动升级成TLS 协议。

  • Galley:Galley 是Istio 的配置验证、提取、处理和分发组件。它负责将其余的Istio 组件与从底层平台(例如Kubernetes)获取⽤户配置的细节隔离开来。

为什么使用Istio

通过负载均衡、服务间的身份验证、监控等⽅法,Istio 可以轻松地创建⼀个已经部署了服务的⽹络,⽽服务的代码只需很少更改甚⾄⽆需更改。通过在整个环境中部署⼀个特殊的sidecar 代理为服务添加Istio 的⽀持,⽽代理会拦截微服务之间的所有⽹络通信,然后使⽤其控制平⾯的功能来配置和管理Istio,这包括:

  • 为HTTP、gRPC、WebSocket 和TCP 流量⾃动负载均衡。

  • 通过丰富的路由规则、重试、故障转移和故障注⼊对流量⾏为进⾏细粒度控制。

  • 可插拔的策略层和配置API,⽀持访问控制、速率限制和配额。

  • 集群内(包括集群的⼊⼝和出⼝)所有流量的⾃动化度量、⽇志记录和追踪。

  • 在具有强⼤的基于身份验证和授权的集群中实现安全的服务间通信。

Istio 为可扩展性⽽设计,可以满⾜不同的部署需求。

Istio 核心特性

Istio 以统⼀的⽅式提供了许多跨服务⽹络的关键功能。

流量管理

Istio 简单的规则配置和流量路由允许您控制服务之间的流量和API 调⽤过程。
Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻⽽易举的执⾏重要的任务(如A/B 测试、⾦丝雀发布和按流量百分⽐划分的分阶段发布)。
有了更好的对流量的可视性和开箱即⽤的故障恢复特性,就可以在问题产⽣之前捕获它们,⽆论⾯对什么情况都可以使调⽤更可靠,⽹络更健壮。

安全

Istio 的安全特性解放了开发⼈员,使其只需要专注于应⽤程序级别的安全。

Istio 提供了底层的安全通信通道,并为⼤规模的服务通信管理认证、授权和加密。有了Istio,服务通信在默认情况下就是受保护的,可以让您在跨不同协议和运⾏时的情况下实施⼀致的策略——⽽所有这些都只需要很少甚⾄不需要修改应⽤程序。

Istio 是独⽴于平台的,可以与Kubernetes(或基础设施)的⽹络策略⼀起使⽤。但它更强⼤,能够在⽹络和应⽤层⾯保护pod到pod 或者服务到服务之间的通信。

可观察性


Istio 健壮的追踪、监控和⽇志特性让您能够深⼊的了解服务⽹格部署。

通过Istio 的监控能⼒,可以真正的了解到服务的性能是如何影响上游和下游的;⽽它的定制Dashboard 提供了对所有服务性能的可视化能⼒,并让您看到它如何影响其他进程。

Istio 的Mixer 组件负责策略控制和遥测数据收集。它提供了后端抽象和中介,将⼀部分Istio 与后端的基础设施实现细节隔离开来,并为运维⼈员提供了对⽹格与后端基础实施之间交互的细粒度控制。

所有这些特性都使您能够更有效地设置、监控和加强服务的SLO。当然,底线是您可以快速有效地检测到并修复出现的问题。

平台支持

Istio 独⽴于平台,被设计为可以在各种环境中运⾏,包括跨云、内部环境、Kubernetes、Mesos 等等。您可以在Kubernetes 或是装有Consul 的Nomad 环境上部署Istio。Istio ⽬前⽀持:Kubernetes 上的服务部署/基于Consul 的服务注册/服务运⾏在独⽴的虚拟机上

Istio 快速入门

搭建 kubernetes 集群

Istio运⾏在kubernetes平台是最佳的选择,所以我们先搭建kubernetes环境。

准备3台Centos7虚拟机:node1 192.168.31.106 node1 192.168.31.106 node3 192.168.31.108

前置工作

搭建K8S之前,需要⼀些前置的准备⼯作,否则不能完成集群的搭建。


 
#修改主机名hostnamectl set-hostname node2hostnamectl set-hostname node3
#更新yum源,并且完成yum update操作mv/etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backupwget -O/etc/yum.repos.d/CentOS-Base.repohttps://mirrors.aliyun.com/repo/Centos-7.repoyum makecacheyum -yupdate
#安装dockeryum install -yyum-utils device-mapper-persistent-data lvm2yum-config-manager --add-repohttps://mirrors.aliyun.com/dockerce/linux/centos/docker-ce.repoyum makecache fastyum -yinstall docker-ce
#启动docker服务systemctl startdocker.service#开机⾃启systemctl enable docker.service
#添加docker阿⾥云加速器sudo mkdir -p/etc/dockersudo tee/etc/docker/daemon.json <<-'EOF'{"registry-mirrors": ["https://c6n8vys4.mirror.aliyuncs.com"]}EOF
sudo systemctl daemon-reloadsudo systemctl restartdocker
#测试⼀下,看下载速度怎么样docker pull redisdocker rmi redis:latest
#关闭防⽕墙systemctl stopfirewalld.servicesystemctl disable firewalld.service
#添加hosts映射vim/etc/hosts192.168.31.106 node1192.168.31.107 node2192.168.31.108 node3
scp /etc/hosts node2:/etc/scp /etc/hosts node3:/etc/
#设置node1到node2、node3免登陆ssh-keygen #⼀路下⼀步操作ssh-copy-id node2ssh-copy-id node3
#测试sshnode2sshnode3
集群搭建#修改系统参数# 将SELinux 设置为permissive 模式(相当于将其禁⽤)setenforce 0sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/'/etc/selinux/config
# 禁⽤swap⽂件,编辑/etc/fstab,注释掉引⽤swap 的⾏vim/etc/fstabswapoff -a
# 设置⽹桥参数vim/etc/sysctl.confnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward = 1net.ipv4.tcp_tw_recycle = 0scp /etc/sysctl.conf node2:/etc/scp /etc/sysctl.conf node3:/etc/
#⽴即⽣效sysctl -p
#安装kubectlvim/etc/yum.repos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled=1gpgcheck=0yum list kubectl –showduplicatesyum install -ykubectl.x86_64kubectl versionyum install -ykubelet kubeadm --disableexcludes=kubernetes
#拉取所需要的镜像kubeadm config images pull --image-repository=registry.cnhangzhou.aliyuncs.com/itcast --kubernetes-version=v1.18.6
#如果拉取失败,尝试这个:kubeadm config images pull --image-repository=lank8s.cn --kubernetes-version=v1.18.6#开始初始化,如果使⽤lank8s.cn拉取的镜像,需要指定--image-repository=lank8s.cnkubeadm init --apiserver-advertise-address 192.168.31.106 --pod-networkcidr=10.244.0.0/16 --image-repository=registry.cn-hangzhou.aliyuncs.com/itcast--kubernetes-version=v1.18.6#当看到Your Kubernetes control-plane has initialized successfully! 说明初始化成功了!
#拷⻉admin.conf到home⽬录,否则出错:The connection to the server localhost:8080was refused - did you specify the right host or port?mkdir -p $HOME/.kubesudo cp -i/etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
#设置⽹络kube-flannel.yml ⽂件在资料中kubectl apply -fkube-flannel.yml
#测试[root@node1 k8s]# kubectl get nodesNAME STATUS ROLES AGE VERSIONnode1 Ready master 23m v1.18.6
#将node2、node3加⼊到集群,token要替换成⾃⼰的kubeadm join 192.168.31.106:6443 --tokenekw4eu.cfi77sji1jyczhj6 --discoverytoken-ca-cert-hashsha256:21de4177eaf76353dd060f2a783c9dafe17636437ade020bc40d60a8ab903483
#测试[root@node1 k8s]# kubectl get nodesNAME STATUS ROLES AGE VERSIONnode1 Ready master 31m v1.18.6node2 Ready <none> 6m46s v1.18.6node3 Ready <none> 2m21s v1.18.6
#说明集群组件成功了#如果需要删除集群,执⾏kubeadm reset ,3台机器都需要执⾏#查看正在执⾏的podkubectl getpod --all-namespaces -owide



查看正在执⾏的pod,kubectl get pod --all-namespaces -o wide

微服务架构之 Service Mesh 初体验

搭建 Istio 环境

下载Istio

下载Istio,下载内容将包含:安装⽂件、示例和istioctl 命令⾏⼯具。

  1. 访问 Istio release ⻚⾯下载与您操作系统对应的安装⽂件。在macOS 或Linux 系统中,也可以通过以下命令下载最新版本的Istio:


 
   
   
 

$ curl -Lhttps://istio.io/downloadIstio | sh -