Istio入门——了解什么是服务网格以及如何在微服务体系中使用

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: Istio入门——了解什么是服务网格以及如何在微服务体系中使用


最近几年,软件体系结构领域发生了巨大的变化。我们都见证了这一重大转变,就是将大型的整体应用程序和粗粒度应用程序分解为被称为微服务的细粒度部署单元,主要通过同步REST和gRPC接口以及异步事件和消息传递进行通信。这种架构的好处很多,但缺点同样明显。在“旧世界”中曾经很简单的软件开发过程,例如调试,概要分析和性能管理,现在变得复杂了一个数量级。此外,微服务架构也带来了自己独特的挑战。

服务更具流动性和弹性,并且跟踪它们的实例、它们的版本和依赖关系是一项艰巨的挑战,随着微服务的发展,它的复杂性迅速增加。最重要的是,单个服务可能会孤立地失败,并且这种失败会由于不可靠的网络而进一步加剧。如果系统足够大,则在任何给定时间点,部分系统可能会遭受轻微故障,可能会影响一部分用户,而这往往是在操作员不知情的情况下发生的。拥有如此众多的“活动部件”,如何应对这些挑战并确保系统平稳运行而又既不影响客户,又能避免让开发人员精疲力尽呢?

随着微服务的日益普及,该行业一直在稳步提出各种模式和最佳实践,这些模式和最佳实践使整个体验更佳。弹性模式服务发现容器编排Canary版本可观察性模式BFFAPI网关…这些是从业人员将用来构建更健壮和可持续的分布式系统的概念。但是这些概念仅仅是抽象概念和模式,它们需要有人在系统中的某个地方实现它们。很多时候,那个“某人”就是,“某个地方”便是处不在

一、开始之前


本文旨在提供对Istio的“温和”介绍。所谓“温和”,不是指快速。我们将从基本概念入手,然后浏览一下如何将它们与增量示例结合在一起。请尝试按照顺序执行这些示例,因为某些示例将取决于前面的示例。到最后,您应该了解Istio是什么,可以在哪里使用它,并有信心自己使用它。

本文介绍的材料在Kubernetes知识范围内将被分类为中级或高级。因此对Kubernetes和Docker的掌握至关重要:您应该对Kubernetes核心概念有透彻的实践了解,具有部署和管理容器化工作负载的能力,并可以轻松地使用kubectl导航和更改Kubernetes集群的状态。



二、介绍Istio


Istio是一个服务网格—一种应用程序感知的基础结构层,用于促进服务到服务的通信。“应用程序感知”是指服务网格在某种程度上了解服务通信的本质,可以以增量的方式进行干预。例如,服务网格可以实现弹性模式(重试,断路器),更改流量(调整流量,影响路由行为),以及添加大量全面的安全控制措施。Istio本质上了解服务之间传递的流量,因此还可以提供细粒度的仪表和遥测见解,从而为原本不透明的分布式系统提供一定程度的可观察性。

注意:*服务网格是指*OSI参考模型中的第7层协议,但也可以配置为在第3层和第4层运行。

Istio得到了Google,IBM和Lyft的支持,并且是目前使用最广泛的服务网格体系结构。Kubernetes最初由Google设计,也很好地融入了Istio。因此将Istio标记为“ Kubernetes-native服务网格”将是合理的。

它怎么运行的

像大多数服务网格实现一样,Istio用称为sidecar的代理容器补充了现有的应用程序容器。Sidecar代理是经过特殊配置的Envoy实例,可拦截进入和离开服务容器的网络流量,并通过专用网络重新路由流量,如下所示。

Sidecar代理是针对延迟和吞吐量进行了优化的轻量级组件,具有最小的配置和路由智能。路由决策是基于由单独的控制平面(服务网格的隐喻“大脑”)托管的策略做出的。控制平面包括部署在Kubernetes集群中的一组专用组件-与任何其他容器化应用程序一样,驻留在专用istio-system名称空间中。控制平面的组件有意与数据平面分离,这些元素直接执行应用程序容器的网络流量实际路由和接口。下图说明了这种分离。

笔记:*Sidecar代理模式不是服务网格实现的唯一方法。由Netflix技术套件首创的另一种方法是使用客户端库(Ribbon,Hysterix,Eureka和Archaius)来填充数据平面的角色,并从集中控制平面获取路由提示。这种方法的好处是,与容器编排引擎(或者实际上完全是容器)无关,它可以以嵌入式形式部署在传统的无容器应用程序中。Netflix库的好处也是它的缺点-它们需要对应用程序进行侵入式更改,并为有限的编程语言提供支持,这些编程语言主要针对JVM。

毫不奇怪,基于Sidecar的服务网格在运营和DevOps团队中得到了广泛采用-在现代服务网格设计中,业务逻辑和基础架构之间的高度分离得以实现。




三、核心概念

Istio扩展了具有几种特定于Istio的资源类型的 Kubernetes设置的命名法。作为Kubernetes原生服务网格,Istio使用自定义资源定义(CRDs)来实现这些概念。CRDs文件更多的是使用YAML声明配置片段和使用kubectl进行管理,类似于内置的类型,如PodServiceDeployment

Virtual services

一个虚拟服务指定请求是如何入站到一个特定的虚拟主机,并路由到底层的目的地。

虚拟服务将服务使用者与服务提供商之间的耦合程度降到了传统的Kubernetes服务所无法达到的程度,而传统的Kubernetes服务则是基本的负载平衡器。虚拟服务的典型用例包括将请求流量分区到服务的不同版本,这些版本指定为服务子集

客户端在不了解底层提供程序实现的情况下将请求发送到虚拟服务,然后Envoy根据虚拟服务配置中定义的规则将流量转发到不同版本。例如,“ X%的呼叫转到新版本”“这些用户的呼叫转到Y版本”。精明的读者将把这些用例视为“canary”的部署,其中逐步增加了对新服务版本的访问量,以缓解大爆炸版本的风险。

除了将流量分配给多个基础提供商实现之外,虚拟服务还允许您做相反的工作-将多个完全不同的服务组合到一个虚拟服务中。换句话说,虚拟服务可以充当基本的聚合层,从而消除了对专用反向代理(例如NGINX)的需求。

精心计划的虚拟服务还可以促进Strangler Pattern。假设服务合同不变,细粒度的服务路由规则可以针对各个端点,一旦原始端点在整体上已过时,就将请求流量转移到微服务风格的实现中。将匹配规则与基于百分比的流量策略相结合,可以透明地在提供方安排逐步迁移,而服务使用者则不需要做什么。

下面的代码片段提供了虚拟服务的简单示例。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- shoppingcart
http:
- match:
  - headers:
      end-user:
        exact: emil.koutanov
  route:
  - destination:
      host: shoppingcart
      subset: v3
- route:
  - destination:
      host: shoppingcart
      subset: v3
    weight: 25
  - destination:
      host: shoppingcart
      subset: v2
    weight: 75

hosts将虚拟服务绑定到用户可寻址的目的地。换句话说,它充当调用虚拟服务的触发器。这些目标可以是固定的IP地址,DNS名称或服务名称-后者可以是简短的Kubernetes名称或FQDN(完全合格的域名)。*还支持通配符前缀(由字符表示)-在子域上触发虚拟服务。指定的主机实际上不需要解析为任何现有服务名称;您可以指定要匹配的任意主机。

注意:*主机匹配模型的灵活性是一把双刃剑。因为主机名可以是任意的,所以Istio不会进行任何形式的健全性检查。例如,如果上例中的主机名拼写错误为“ shopingcart”,则Istio将很乐意应用该配置。稍后,当客户端尝试调用正确命名的*shoppingcart*主机时,请求将被直接路由到服务-我们的虚拟服务规则将无效。*

http介绍了路由规则-匹配条件和用于路由发送到主机字段中指定的目标的HTTP / 1.1,HTTP / 2和gRPC通信的条件和操作。(您也可以使用tcptls部分配置TCP和未终止TLS流量的路由规则。)

路由规则由要转发流量的目的地以及零个或多个匹配条件组成。在上面的示例中,第一个规则仅匹配来自user的请求emil.koutanov。路由规则是按照严格的从上到下的顺序进行评估的:第一个匹配的规则将被执行,如果不匹配,则进入下一个规则。

因此,在我们的示例中,emil.koutanov将始终将用户定向到v3shoppingcart服务。v3在25%的情况下,将为所有其他用户提供服务。由于带有match谓词的规则可能不会被剔除,因此最好的做法是保留最后一个没有match谓词的规则-有效地构成“包罗万象”。

hosts中指定的虚拟名称不同,目标主机必须可解析为真实地址。为目标主机提供简称时,Istio将根据虚拟服务的名称空间添加域后缀。如果目的地位于其他名称空间中,则主机应指定标准服务名称。Istio维护人员建议在生产中使用标准名称,因为这样可以避免潜在的歧义和配置错误。

到目前为止,我们没有看到目的地和子集,而没有过多地关注它们的定义位置。一个目的地规则是一个可选的细粒度政策控制特定目的地的交通。在评估了虚拟服务路由规则之后,将应用目标规则,换句话说,它们将应用到流量的“真实”目标。

目标规则定义为 DestinationRule这种类型的CRD。以下是目标规则的示例。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: shoppingcart-destinationrule
spec:
host: shoppingcart
trafficPolicy:
  loadBalancer:
    simple: RANDOM
subsets:
- name: v2
  labels:
    version: v2
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
- name: v3
  labels:
    version: v3

这个例子应该开始变得更有意义了,实际上它已经完成了。我们在定义中使用的v2v3子集VirtualService仅是引用shoppingcart服务的标记版本。标签是标准的Kubernetes概念-可用于注释Kubernetes资源的自由格式键值对。该version标签将可能出现在metadata该服务的部分Deployment资源定义,并调用相应的目标规则集时会在运行时匹配。

Gateways

网关控制服务网格流量的流入和流出。在幕后,网关是一个Envoy代理实例,该实例以独立配置(未附加到应用程序容器)部署在数据平面的概念边界上。

网关的绝大多数用例都围绕入站流量的管理。以这种能力,网关的行为类似于常规的Kubernetes  ingress 资源。网关和Kubernetes  ingress 之间的主要区别在于,前者被设计为专门与Istio一起使用,而后者则是设计为处理外部流量的标准API。

ingress和 ingress控制器通常独立于服务网格,并且无需任何一个即可运行。从理论上讲,可以部署 ingress控制器并配置 ingress以在流量到达Istio网关之前对其进行路由。此策略对于聚合服务可能很有用,其中某些服务可能使用服务网格进行有线连接,而其他服务可能会按常规部署。

以下代码段是网关定义的示例。


apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: shoppingcart-gateway
spec:
selector:
  istio: ingressgateway
servers:
- port:
    number: 443
    name: https
    protocol: HTTPS
  hosts:
  - shoppingcart.example.com
  tls:
    mode: SIMPLE
    serverCertificate: /tmp/tls.crt
    privateKey: /tmp/tls.key


这个简单的示例接受发往shoppingcart.example.comport的HTTPS流量443。在我们首先将网关绑定到虚拟服务之前,流量无法流入服务网格。扩展我们之前的虚拟服务示例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- shoppingcart
gateways:
- shoppingcart-gateway
http:
- match:
  - headers:
      end-user:
        exact: emil.koutanov
  route:
  - destination:
      host: shoppingcart
      subset: v3
- route:
  - destination:
      host: shoppingcart
      subset: v3
    weight: 25
  - destination:
      host: shoppingcart
      subset: v2
    weight: 75

我们添加到上一个示例中的就是该gateways部分,通过其名称指定了我们的网关。shoppingcart-gateway现在将允许网关上的入口流量流入shoppingcart虚拟服务。

除了处理入口流量外,网关还可以充当离开网状网络的流量的受控出口点。网关将使您限制哪些服务可以访问外部网络并监视允许离开的流量。有几个原因可能导致人们想要在基础结构级别上限制出口,而与底层应用程序无关。

其中主要是合规性-例如,PCI DSS标准要求将来自持卡人数据环境(CDE)的出站流量限制为经过授权的通信,要求采用默认拒绝规则来阻止未指定的流量。另一个常见的原因是减轻攻击,系统中的一个或多个组件可能会受到攻击,并可能试图泄漏敏感数据。

Service entries

Service entry是Istio在其专用服务注册表中维护的服务的内部定义。Service entries并不是经常遇到的事情;您可以在Istio中部署完整的分布式系统,而无需触碰这个概念。尽管如此,它仍被视为Istio的核心概念,至少应该意识到这一点。

Service entries的主要用例集分为以下几大类:

  • 传统应用程序集成:与未部署在Kubernetes中或无法从Istio数据平面直接访问的服务进行通信。
  • 多集群合成:来自多个物理Kubernetes集群的服务的逻辑聚合。
  • 将网格扩展到Kubernetes之外:将部署在物理硬件和VM上的工作负载添加到现有服务网格。
  • 检测外部服务:例如,对外部服务的调用的重试,百分比路由,跟踪等。

注意:*您不需要仅配置服务条目即可访问外部服务,例如*maps.googleapis.com*。默认情况下,Istio egress Envoy代理配置为将请求传递给未知服务。但是,未注册的目的地将无法从适用于Istio增强服务的细粒度流量策略中受益。*

对于服务进入场景的实际示例,请考虑由托管的外部服务,someprovider.com该服务需要相互TLS(mTLS)进行身份验证。一种选择是将X.509证书和签名的PEM密钥部署到我们Kubernetes集群中部署的每个使用者。这带来了后勤方面的挑战:可能会有几个这样的使用者,并且每个使用者都需要对应用程序代码进行潜在的侵入性更改以支持mTLS的使用。

最重要的是,我们必须分发和旋转关键材料。通过配置Istio作为前向代理,将来自我们数据平面的流量透明封装到TLS隧道中,充当mTLS终结器,可以解决此难题。请参阅下面的资源定义。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-serviceentry
spec:
hosts:
- someprovider.com
ports:
- number: 443
  name: https
  protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: external-destinationrule
spec:
host: someprovider.com
trafficPolicy:
  tls:
    mode: MUTUAL
    clientCertificate: /etc/certs/myclientcert.pem
    privateKey: /etc/certs/client_private_key.pem
    caCertificates: /etc/certs/rootcacerts.pem

已经定义了两个资源:服务条目和相应的目标规则。前者的作用相对较小-它someprovider.com作为服务条目注册,并将其置于Istio的范围内。后者承担了繁重的工作-指定身份验证模式,用于验证提供者的CA证书以及用于验证客户端的私钥和证书。

Sidecars

我们之前曾提到过边车是Istio服务网格体系结构的定义元素。确实,不起眼的Envoy代理小工具是Istio生态系统中众所周知的主力军,由控制平面自行决定在数据平面中移动流量。

sidecars与服务入口在同一条船上,因为您可能会在构建过程中获得公平的方式,而无需直接处理它们。常规将Sidecar注入到应用程序Pod中,而用户的参与很少,并且将继承默认配置,该配置可以直接使用。默认情况下,Istio将配置网格中的所有Sidecar代理以到达每个工作负载实例,并接受与工作负载关联的所有端口上的流量。

出于以下原因,可以明确修改Sidecar配置:

  • 限制Envoy代理接受的端口和协议集。
  • 限制Envoy代理可以访问的服务集。

通过使用,可以将Sidecar配置应用于整个名称空间或特定的工作负载workloadSelector。这产生了范围界定规则。当确定要应用到特定工作负载实例的Sidecar配置时,将优先使用配置无效的Sidecar资源。此外,名称空间最多可以具有一个没有的sidecar配置。如果本地名称空间中没有任何sidecar配置匹配,则在名称空间(或配置的根Istio名称空间)中定义的全局默认配置将生效。

为了使事情变得更加复杂,如果两个或更多带有选择相同工作负载实例的Sidecar配置,则系统的行为是不确定的。workloadSelector``workloadSelector``workloadSelector``istio-system``workloadSelector

全局默认配置是相当宽松的。您可以通过运行以下命令查看默认值:

kubectl get sidecar default -n istio-system -o yaml

导致:

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
annotations:
  kubectl.kubernetes.io/last-applied-configuration: |
    *** omitted for brevity ***
creationTimestamp: "2019-12-25T01:32:02Z"
generation: 1
labels:
  operator.istio.io/component: IngressGateway
  operator.istio.io/managed: Reconcile
  operator.istio.io/version: 1.4.0
  release: istio
name: default
namespace: istio-system
resourceVersion: "4527"
selfLink: /apis/networking.istio.io/v1alpha3/namespaces/istio-system/sidecars/default
uid: 5cee1cb3-1d48-11ea-84b7-025000000001
spec:
egress:
- hosts:
  - '*/*'


以下对全局默认配置的示例修订将出口流量仅限制为同一名称空间中的其他工作负载以及名称空间中的服务istio-system

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default
namespace: istio-system
spec:
egress:
- hosts:
  - "./*"
  - "istio-system/*"


相关文章
|
14天前
|
Cloud Native 持续交付 云计算
云原生入门指南:从容器到微服务
【10月更文挑战第28天】在数字化转型的浪潮中,云原生技术成为推动现代软件开发的关键力量。本篇文章将带你了解云原生的基本概念,探索它如何通过容器化、微服务架构以及持续集成和持续部署(CI/CD)的实践来提升应用的可伸缩性、灵活性和可靠性。你将学习到如何利用这些技术构建和部署在云端高效运行的应用,并理解它们对DevOps文化的贡献。
36 2
|
16天前
|
监控 安全 Cloud Native
云原生安全:Istio在微服务架构中的安全策略与实践
【10月更文挑战第26天】随着云计算的发展,云原生架构成为企业数字化转型的关键。微服务作为其核心组件,虽具备灵活性和可扩展性,但也带来安全挑战。Istio作为开源服务网格,通过双向TLS加密、细粒度访问控制和强大的审计监控功能,有效保障微服务间的通信安全,成为云原生安全的重要工具。
38 2
|
17天前
|
Kubernetes 关系型数据库 MySQL
Kubernetes入门:搭建高可用微服务架构
【10月更文挑战第25天】在快速发展的云计算时代,微服务架构因其灵活性和可扩展性备受青睐。本文通过一个案例分析,展示了如何使用Kubernetes将传统Java Web应用迁移到Kubernetes平台并改造成微服务架构。通过定义Kubernetes服务、创建MySQL的Deployment/RC、改造Web应用以及部署Web应用,最终实现了高可用的微服务架构。Kubernetes不仅提供了服务发现和负载均衡的能力,还通过各种资源管理工具,提升了系统的可扩展性和容错性。
51 3
|
30天前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
1月前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
53 8
|
1月前
|
自然语言处理 监控 Cloud Native
探索微服务架构中的服务网格Service Mesh
【10月更文挑战第7天】服务网格(Service Mesh)是微服务架构中的关键组件,通过在每个服务实例旁部署Sidecar代理,实现服务间通信的管理、监控和安全增强。本文介绍了服务网格的基本概念、核心组件、优势及实施步骤,探讨了其在现代开发中的应用,并提供了实战技巧。
|
15天前
|
监控 API 持续交付
后端开发中的微服务架构:从入门到精通
【10月更文挑战第26天】 在当今的软件开发领域,微服务架构已经成为了众多企业和开发者的首选。本文将深入探讨微服务架构的核心概念、优势以及实施过程中可能遇到的挑战。我们将从基础开始,逐步深入了解如何构建、部署和管理微服务。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的建议。
34 0
|
1月前
|
Kubernetes 负载均衡 安全
Istio在微服务中释放服务网格的力量
Istio在微服务中释放服务网格的力量
50 4
|
3月前
|
开发者 项目管理 开发工具
震惊!单人开发者如何成功过渡到团队协作?Xamarin 项目管理经验大揭秘,让你的开发之路一帆风顺!
【8月更文挑战第31天】Xamarin 是移动应用开发领域的热门跨平台工具,适用于个人开发者及团队。个人开发时需明确需求、运用版本控制(如 Git)并合理规划项目结构以增强代码可维护性。团队协作时,则需建立有效沟通渠道、统一代码规范、严格版本控制及合理分配任务,以提升开发效率与项目质量。
63 1
|
3月前
|
Cloud Native 云计算 微服务
云原生入门指南:从零开始构建微服务
【8月更文挑战第31天】在数字化浪潮中,云原生技术正引领着软件开发的未来。本文旨在为初学者揭开云原生的神秘面纱,通过一个简易微服务的搭建过程,展示云原生应用的构建和部署。我们将从概念理解到实际操作,一步步带领读者走进云原生的世界,探索其背后的哲学与实践之美。