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

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: 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/*"


相关文章
|
2月前
|
安全 测试技术 开发者
探索服务网格技术:Istio的奥秘与力量
【6月更文挑战第1天】本文介绍了服务网格技术的代表Istio,它是处理服务间通信的基础设施层,由Google、IBM和Lyft联合开发。Istio提供流量管理、安全和可观察性等功能,支持灰度发布、蓝绿部署等,并确保通信安全。适用于微服务治理、多云环境和复杂网络拓扑,尤其适合安全敏感应用。理解Istio有助于解决微服务架构中的挑战。
|
3月前
|
敏捷开发 运维 监控
探索微服务架构下的服务网格
【5月更文挑战第29天】 在现代软件开发的复杂多变环境中,微服务架构已成为构建分布式系统的热门选择。随着其应用的广泛化,服务网格(Service Mesh)这一概念应运而生并迅速崛起,它旨在提供一种透明且高效的方式来管理服务间的通信。本文将深入探讨服务网格的核心组件、运作机制以及如何通过服务网格优化微服务架构。我们还将讨论服务网格引入的挑战与克服这些挑战的策略,为采用微服务的企业提供指导和见解。
|
17天前
|
Kubernetes 安全 Cloud Native
解锁安全新纪元:利用服务网格Istio,打造全链路mTLS加密隧道,从入口网关到出口网关,守护数据安全的每一步
【8月更文挑战第2天】随着云原生技术的发展,服务网格(Service Mesh)如Istio已成为微服务架构的核心,通过双向TLS(mTLS)确保通信安全。首先,在Kubernetes部署Istio以管理服务通信。接着,配置入口网关实现所有入向流量的加密处理,防止数据泄露。最后,通过配置Sidecar代理如Envoy,确保服务网格安全访问外部mTLS服务,从而构建起全链路的数据安全防护。
34 11
|
9天前
|
运维 Cloud Native Android开发
云原生之旅:容器化与微服务架构的融合之道安卓应用开发入门指南
本文将深入探讨云原生技术的核心要素——容器化和微服务架构,并揭示它们如何共同推动现代软件的开发与部署。通过实际案例分析,我们将看到这两种技术如何相辅相成,助力企业实现敏捷、可扩展的IT基础设施。文章旨在为读者提供一条清晰的道路,指引如何在云原生时代利用这些技术构建和优化应用。 本文将引导初学者了解安卓应用开发的基本概念和步骤,从安装开发环境到编写一个简单的“Hello World”程序。通过循序渐进的讲解,让读者快速掌握安卓开发的核心技能,为进一步深入学习打下坚实基础。
19 1
|
1月前
|
Kubernetes Cloud Native 持续交付
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。
云原生架构的核心组成部分通常包括容器化(如Docker)、容器编排(如Kubernetes)、微服务架构、服务网格、持续集成/持续部署(CI/CD)、自动化运维(如Prometheus监控和Grafana可视化)等。
|
20天前
|
敏捷开发 设计模式 运维
探索微服务架构中的服务网格
【7月更文挑战第30天】在现代软件工程中,微服务架构因其灵活性和可扩展性而备受推崇。然而,随着系统规模的扩大,服务之间的通信和管理变得日益复杂。服务网格作为解决这一问题的新兴技术,提供了一种透明、可靠的服务到服务通信方式。本文将深入探讨服务网格的核心概念、实现原理以及其在微服务架构中的应用实践,为读者呈现一个关于如何利用服务网格优化微服务间通信的全景视图。
28 0
|
2月前
|
Kubernetes 监控 负载均衡
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
本文介绍了服务网格(Service Mesh)的概念及其在微服务架构中的重要性。微服务强调围绕业务构建团队和去中心化的数据管理,带来更高的灵活性和扩展性。然而,随着服务数量增加,网络通信成为挑战,包括服务发现、路由和安全等问题。 Service Mesh如Istio应运而生,通过边车代理解决服务间通信,提供服务发现、负载均衡、智能路由、安全和监控等功能。它与Kubernetes结合,增强了容器环境的服务管理能力。Istio的bookinfo示例展示了其在多语言微服务中的应用,简化了代码中的服务调用逻辑,使开发更专注于业务本身。
339 3
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
|
2月前
|
存储 搜索推荐 Java
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
41 2
|
3月前
|
负载均衡 安全 开发者
探索微服务架构中的服务网格
【5月更文挑战第25天】 在现代软件工程实践中,微服务架构已成为构建和部署分布式系统的主流方式。随着其流行度的提升,管理这些微服务之间的交互变得日益复杂。服务网格(Service Mesh)作为一种基础设施层,旨在处理服务间的通信,并提供服务发现、负载均衡、故障管理等功能。本文将探讨服务网格在微服务体系结构中的作用,以及如何利用它来优化分布式系统的可靠性和性能。
|
3月前
|
运维 负载均衡 监控
探索微服务架构下的服务网格
【5月更文挑战第17天】 在当代软件开发领域,微服务架构已成为构建可扩展、灵活且容错的系统的首选模式。然而,随之而来的复杂性问题也日益凸显,特别是在服务间的通信管理上。服务网格(Service Mesh)作为一种新兴的解决方案,专门处理服务到服务的通信问题,旨在提供一种更加智能和动态的方式来管理微服务环境中的流量和服务依赖。本文将深入探讨服务网格的概念、优势以及如何在微服务架构中实现高效通信。