为微服务引入Istio服务网格(上)
Posted 大魏分享
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为微服务引入Istio服务网格(上)相关的知识,希望对你有一定的参考价值。
版权说明:本文由高晓雪参照如下文档翻译。魏新宇根据高晓雪的翻译文档,做了适当的注解和文字矫正。
https://developers.redhat.com/download-manager/file/istio_mesh_for_microservices_r1.pdf
本文适合对istio的读者提供泛读参考,对istio理解较深的读者,建议直接阅读英文原文。本系列分上下两篇:上篇为1-3章内容,下篇为4-7章内容。
目录
为微服务引入Istio服务网格
1.介绍
1.1.更快的挑战
1.2.认识Istio
1.3.了解Istio组件
1.3.1.数据平面
1.3.2.控制平面
2.安装和入门
2.1.命令行工具安装
2.2.Kubernetes / OpenShift安装
2.3.Istio安装
2.3.1.安装Istio命令行工具
2.4.Java微服务安装示例
2.4.1.浏览代码库
2.4.2.建立和部署客户服务
2.4.3.构建和部署首选项服务
2.4.4.建立和部署推荐服务
2.4.5.构建和部署到Kubernetes
3.交通管制
3.1. 更高级的金丝雀版
3.3.1.交通路由
3.3.2.路由到特定版本的部署
3.3.3.基于头的路由
3.2.黑暗发射
3.3.出口
4.服务弹性
4.1.负载平衡
4.2.超时
4.3.重试
4.4.断路器
4.5.池射出
4.6.组合:断路器+池弹出+重试
5.混沌测试
5.1.HTTP错误
5.2.延迟
6.观测
6.1.跟踪
6.2.指标
7.安全
7.1.黑名单
7.2.白名单
7.3.结论
1. 介绍
如果您正在寻找有关详细的Istio的服务网格平台介绍,请参阅本书。本书面向基于微服务架构风格的动手应用程序架构师和开发团队负责人,专注于云应用程序的应用程序。本书假定您已经有过使用Docker的实践经验,虽然Istio将可用于多种Linux容器编排解决方案,但本书的重点主要针对Kubernetes/OpenShift上的Istio。在本书中,我们将交替使用术语Kubernetes和OpenShift。(Open-Shift是红帽支持的Kubernetes发行版。)
如果您需要Java微服务的介绍(涵盖Spring Boot,WildFly Swarm和Dropwizard),请参阅适用于Java开发人员的微服务(O'Reilly)。
另外,如果您对反应式微服务感兴趣,那么一个很好的开始就是在Java中构建反应式微服务(O'Reilly),因为它专注于Java虚拟机的反应式工具包Vert.x。
此外,本书假定您对Kubernetes/OpenShift有一定的了解;如果情况并非如此,OpenShiftfor Developers(O'Reilly)是关于该主题的优秀免费电子书。我们将通过OpenShift的视角部署、交互和配置Istio,但是,我们使用的命令也可以移植到vanillaKubernetes。
首先,我们讨论Istio可以帮助开发人员解决并描述Istio主要组件的挑战。
1.1. 更快的挑战
作为一个软件开发社区,在数字化转型的时代,您已经开始对更好的服务客户和用户进行不懈的追求。今天的数字创作者,应用程序员,不仅基于敏捷原则演变成更快的开发周期,而且还在追求更快的部署时间。虽然单片代码库和生成的应用程序可以在每月一次甚至每周一次的快速剪辑中进行部署,但通过将应用程序分解为更小的团队规模的单元,可以实现更快的“生产”速度,每个都有其独立的工作流程,治理模型和部署管道。业界已将此方法定义为微服务架构。
关于与微服务相关的各种挑战已经写了很多,因为它首次引入了许多团队的分布式计算的谬误。头号谬论是“网络可靠”。微服务在网络上显着通信 - 微服务之间的连接。这是过去几十年来大多数企业软件的基本改变。当您将网络依赖性添加到您的应用程序逻辑时,您已经邀请了大量的潜在危险,如果与您所建立的连接数目不成指数关系,则危害会成比例增长。
此外,您现在每隔几个月就要从单一部署转向潜在的几十个软件部署,即使不是每天都这样,也会带来许多新的挑战。一个简单的例子是,您如何设法创建更加无缝的部署模型,以允许将源代码管理器(例如Git)中的代码检入到工作流的各个阶段,从开发到代码审查,再到QA,安全审计/审查,登台环境,最终进入生产环境。
一些大型网络公司不得不放置框架和库,以帮助缓解不可靠的网络和许多代码部署每天的一些挑战。例如,像Netflix这样的公司创建了像NetflixOSS Ribbon,Hystrix和Eureka这样的项目来解决这些类型的问题。其他如Twitter和谷歌最终也做了类似的事情。他们创建的这些框架非常适合语言和平台,在某些情况下,很难引入用编程语言编写的新服务,而这些服务没有得到他们创建的弹性框架的支持。每当这些弹性框架得到更新时,应用程序还需要进行更新以保持锁定状态。最后,即使他们为每种可能的语言或框架排列创建了这些弹性框架的实现,但它们在尝试维护此功能并应用功能时会产生大量开销。在尝试在多种框架和语言中实现时,获得这些弹性框架是正确的。这样做意味着努力,错误和不统一的行为集合的冗余。至少在Netflix的例子中,这些库是在虚拟机(VM)是主要可部署单元并且能够标准化的时候创建的单一的云平台和单一的编程语言。大多数公司不能也不会这样做。
Linux容器(例如Docker)和Kubernetes / OpenShift的出现是DevOps团队通过关注通过自动化管道的每个阶段快速流动的不变图像实现更高速度的基本促成因素。开发团队如何管理他们的管道现在独立于容器内运行的语言或框架。OpenShift使我们能够提供更好的弹性和全面管理一组复杂的分布式多语言工作负载.OpenShift确保开发人员可以轻松部署和管理数百个甚至数千个单独的服务。这些服务被打包为运行在Kubernetes窗格中的容器,其中包含各自的语言运行时(例如Java虚拟机,CPython和V8)以及所有必需的依赖项,通常以语言特定框架(例如Spring和Express)和库(例如,罐子和npms)。然而,OpenShift并没有涉及每个应用程序组件在单个Pod中运行时是如何相互交互的。这是建筑师和开发人员发现自己的十字路口。快速部署和管理polyglot服务的工具和基础架构正在变得成熟,但是当我们谈论这些服务如何交互时,我们错过了类似的功能。这就是Istio等服务网格功能允许您,应用程序开发人员,构建更好的软件并提供比以往更快的速度。
1.2. 认识Istio
Istio是一个服务网格的实现。服务网格是服务之间的连接组织,可增加流量控制,服务发现,负载平衡,弹性,可观察性,安全性等附加功能。服务网格允许应用程序从应用程序库中卸载这些功能,并允许开发人员专注于区分业务逻辑。Istio从头开始设计跨部署平台,但它具有一流的集成和对Kubernetes的支持。
像Kubernetes生态系统中的许多免费开源项目一样,“Istio”是一个希腊航海术语,意思是帆 - 很像“Kubernetes”本身就是希腊语中的舵手或船舶驾驶员。随着Istio的出现,服务网格的概念兴起,Kubernetes/ OpenShift已经离开了Istio开始的地方。 Istio为开发人员和架构师提供了更丰富和更具声明性的服务发现和路由功能。
在Kubernetes / OpenShift本身为您提供默认循环负载平衡的情况下,Istio允许您在网格中的所有服务之间引入独特的细粒度路由规则。Istio还为我们提供了更高的可观察性,更深入地深入了解各种分布式微服务的网络拓扑,了解它们之间的流程(跟踪)并能够立即查看关键指标。
如果网络实际上并不总是可靠的,那么我们微服务之间的关键联系不仅需要受到更严格的审查,而且还需要更严格的应用。Istio为我们提供网络级弹性功能,如重试,超时和实现各种断路器功能。
Istio还为开发人员和架构师提供了深入研究混沌工程的基本解释的基础。在第5章中,我们将描述Istio驱动混沌注入的能力,以便您可以看到您的整体应用程序和其潜在的数十个相互依存的微服务实际上是多么的有弹性和强大。
在开始讨论之前,我们要确保您对Istio有基本的了解。以下部分将为您提供Istio基本组件的概述。
1.3. 了解Istio组件
大魏注:
K8S的最小调度单元是pod而不是容器。在绝大多数情况下,一个pod中只有一个容器。但在Istio模式下,一个pod将会包含两个容器。
Istio的数据平面创建了一个跨平台的服务网格来解决常见的微服务架构问题,如其中包括很多:通信,负载平衡,流量路由,指标,配额,身份验证,速率限制,断路器,超时,自动重试,等等。Istio的数据平面采取sidecars的方式,也就是在一个pod的主容器旁边,增加一个istio的proxy。
========================================================
Istio服务网主要由两个主要部分组成:数据平面和控制平面,如图1-1所示。
图1-1数据平面和控制平面
1.3.1. 数据平面
数据平面以拦截所有入站(入站)和出站(出站)网络流量的方式实现。 你的业务逻辑、你的应用程序、你的微服务可以不必关注底层的网络流量管理。您的微服务可以使用简单的框架功能在整个网络上调用远程HTTP端点(例如,Spring的RestTemplate和JAX-RS客户端),并且大多数人仍然不知道现在正在自动应用许多有趣的交叉问题。图1-2描述了Istio出现之前的典型微服务。
图1-2
在Istio之前Istio服务网格的数据平面由两个简单的概念组成:服务代理和sidecar容器,如图1-3所示。
图1-3 通过特使sidecar(istio-proxy)
让我们探索每个概念。
服务代理
服务代理是应用程序服务依赖其他功能的代理。只要需要与外界通信(即通过网络),服务就会通过服务代理进行调用。该代理充当中介或拦截器,可以添加自动重试,超时,断路器,服务发现,安全性等功能。 Istio的默认服务代理基于Envoy Proxy。
Envoy Proxy是由Lyft公司开发的Layer 7代理(参见Wikipedia上的OSI模型),该公司目前在生产中使用它来处理每秒数百万的请求(等等)。 它是用C ++编写,是一个经过测试、高性能和轻量级工具。它为HTTP1.1,HTTP2,gRPC提供了负载平衡、收集请求级度量、跟踪跨度、主动和被动健康检查、服务发现等功能。您可能会注意到Istio的一些功能与Envoy重叠。
Istio使用Envoy来实现这些功能只是简单地解释了这一事实。
但是Istio如何将Envoy作为服务代理部署?可以像其他受欢迎的代理一样部署服务代理,其中许多服务的请求通过单个代理得到服务。 Istio通过称为边车的部署技术将服务代理功能尽可能地接近应用程序代码。
Sidecar
当Kubernetes /OpenShift诞生时,他们并没有像您期望的那样将Linux容器称为可运行/可部署单元。 相反,pod诞生了,它是您在Kubernetes / OpenShift世界中管理的主要对象。为什么选择pod?有人认为这是1956年电影入侵身体抢救者的一些参考,但它实际上是基于一族或一群鲸鱼的概念。鲸鱼是与Docker开源项目相关的早期图像 - 最受欢迎的Linux它的时代的容器解决方案。所以,一个pod可以是一组Linux容器。
sidecar是另一个Linux容器,它直接与您的业务逻辑应用程序或微服务容器并存。
不像现实世界的边车挂在摩托车的侧面,本质上是一个简单的附加功能,这辆边车可以接管车把和油门。
借助Istio,第二个名为“istio-proxy”(又名Envoy服务代理)的Linux容器可以手动或自动地与主业务逻辑容器一起注入。sidecar负责拦截来自业务逻辑容器的所有入站(入站)和出站(出站)网络流量,这意味着可以应用新的策略来重新路由流量(进出),应用策略(如访问控制列表(ACL))或速率限制,还可以抓取监视和跟踪数据(混音器),甚至引入一些混乱,如网络延迟或HTTP错误响应。
1.3.2. 控制平面
控制平面负责成为配置和策略的权威来源,并使数据平面可用于可能由散布在多个节点上的数百个吊舱组成的群集。 Istio的控制平面包含三个主要的Istio服务:Pilot,Mixer和Auth。
飞行员
Pilot负责管理整个车队以及在您的Kubernetes/ OpenShift群集上运行的所有微服务。 Istio Pilot负责确保每个独立和分布式微服务(包装为Linux容器并位于其容器中)具有当前整体拓扑结构和最新“路由表”的视图。
Pilot提供了诸如服务发现的功能以及对RouteRule和DestinationPolicy的支持。RouteRule是什么给你的细粒度的请求分布。我们将在第3章更详细地介绍这一点。DestinationPolicy可帮助您通过超时,重试,断路器等来解决弹性问题。我们在第4章讨论目的地政策。
混合器
正如其名称所暗示的,Mixer是将Istio服务融合在一起的服务。每个分布式istio-代理将其遥测传回混音器。此外,Mixer还维护整套微服务或Pod的使用和访问策略的规范模型。使用混音器,您可以创建ACL(白名单和黑名单),您可以应用速率限制规则,甚至可以捕获自定义指标。 Mixer具有可插拔的后端架构,该架构通过新的插件和合作伙伴迅速发展,将以许多新颖有趣的方式扩展Mixer的默认功能。 Mixer的许多功能都超出了本书的范围,但我们在第6章讨论了可观察性,第7章讨论了安全性。
如果您想进一步探索Mixer,请参阅上游项目文档以及由Red Hat团队维护的Java微服务Istio教程。
验证
Istio Auth组件也称为Istio CA,负责证书签名,证书颁发和撤销/轮换。 Istio向所有微服务颁发x509证书,允许这些服务之间的相互传输层安全性(mTLS),透明地加密所有流量。它使用构建在底层部署平台中的身份并将其构建到证书中。此身份允许您执行策略。
2.安装和入门
2.1.命令行工具安装
在本节中,我们向您展示如何开始使用Kubernetes上的Istio。 无论如何,Istio并没有与Kubernetes绑定在一起,事实上,它的目的是不受任何部署基础设施的影响。 Kubernetes是运行Istio的理想之地,它支持sidecar部署概念。随意使用你希望的任何Kubernetes发行版,但是在这里我们使用了minishift,这是一个名为OpenShift的Kubernetes企业发行版的开发者风格。作为开发者,你可能已经有了一些这样的工具,但为了完整起见,这里是您将需要的工具:
minishift
Docker for Mac/Windows
kubectl
oc client tools for your OS (note: “minishift oc-env” will output the path to
the oc client binary)
mvn
stern for easily viewing logs
siege for load testing
istioctl (will be installed via the steps that follow momentarily)
curl, tar part of your bash/cli shell
Git
2.2.Kubernetes/ OpenShift安装
当你引导minishift时,你需要记住你会创建很多服务。您将安装Istio控制平面,一些支持指标和可视化应用程序以及您的示例服务。为此,用于运行Kubernetes的虚拟机(VM)将需要足够的资源。虽然我们推荐8GB RAM和3个CPU用于虚拟机,但我们已经看到本书中包含的示例在4 GB RAM和2个CPU上成功运行。(需要记住的一点是:在minishift中,默认的pod限制设置为CPU数量的10倍。)
安装minishift之后,您可以使用以下脚本来引导环境:
#!/bin/bash
# add the location ofminishift executable to PATH
# I also keep other handytools like kubectl and kubetail.sh
# in that directory
exportMINISHIFT_HOME=~/minishift_1.12.0
exportPATH=$MINISHIFT_HOME:$PATH
minishift profile settutorial
minishift config set memory8GB
minishift config set cpus 3
minishift config setvm-driver virtualbox
minishift config setimage-caching true
minishift addon enableadmin-user
minishift config setopenshift-version v3.7.0
minishift start
当环境正确启动后,您应该能够设置您的环境以访问minishift的Docker守护程序,并登录到Kubernetes集群:
eval $(minishift oc-env)
eval $(minishift docker-env)
oc login $(minishift ip):8443 -u admin -p admin
如果到目前为止一切都成功了,你应该可以运行下面的命令:
$ ocget node
NAME STATUS AGE VERSION
Localhost Ready 1d v1.7.6+a08f5eeb62
如果您一路上有错误,请查看istio教程的当前步骤,并可能提出GitHub问题。
2.3.Istio安装
Istio发行版捆绑了必要的二进制命令行界面(CLI)工具,安装资源和示例应用程序。您应该下载Istio 0.5.1发行版:
curl-L https://github.com/istio/istio/releases/download/0.5.1/istio-0.5.1
-osx.tar.gz| tar xz
cdistio-0.5.1
现在你需要准备你的OpenShift /Kubernetes环境。 OpenShift具有针对安全,多租户运行时的一系列功能,因此具有严格的安全限制。要安装Istio,暂时可以放松OpenShift安全限制。 Istio社区正在努力使Istio更安全,更符合现代企业安全要求的期望,努力实现“默认安全”,不会有开发人员的痛苦。
现在,为了理解Istio并在OpenShift上运行这些示例,让我们放松这些安全限制。使用oc命令行工具,运行以下命令:
oc adm policyadd-scc-to-user anyuid -z istio-ingress-service-account
-n istio-system
oc adm policyadd-scc-to-user anyuid -z default -n istio-system
oc adm policyadd-scc-to-user anyuid -z prometheus -n istio-system
现在你可以安装Istio。从Istio发行版的根文件夹运行以下命令:
oc create -finstall/kubernetes/istio.yaml
oc project istio-system
这将安装所有必要的Istio控制面组件,包括IstioPilot,Mixer和Auth。您还应该安装一些对度量收集,分布式跟踪以及我们服务的整体可视化有用的协同服务。从Istio发行版的根文件夹运行以下命令:
oc apply -finstall/kubernetes/addons/prometheus.yaml
oc apply -f install/kubernetes/addons/grafana.yaml
oc apply -finstall/kubernetes/addons/servicegraph.yaml
oc process -fhttps://raw.githubusercontent.com/jaegertracing/jaeger-
openshift/master/all-in-one/jaeger-all-in-one-template.yml| oc create -f -
这为度量收集安装了Prometheus,度量仪表板用于Grafana,用于简单可视化服务的Servicegraph和用于分布式跟踪支持的Jaeger。
最后,因为我们使用的是OpenShift,所以您可以通过OpenShiftRouter直接公开这些服务。
oc expose svc servicegraph
oc expose svc grafana
oc expose svc prometheus
oc expose svc istio-ingress
此时,所有Istio控制面组件和伴随服务都应该启动并运行。您可以通过运行以下来验证这一点:
ocget pods
NAME READY STATUS RESTARTS AGE
grafana-3617079618-4qs2b 1/1 Running 0 4m
istio-ca-1363003450-tfnjp 1/1 Running 0 4m
istio-ingress-1005666339-vrjln 1/1 Running 0 4m
istio-mixer-465004155-zn78n 3/3 Running 0 5m
istio-pilot-1861292947-25hnm 2/2 Running 0 4m
jaeger-210917857-2w24f 1/1 Running 0 4m
prometheus-168775884-dr5dm 1/1 Running 0 4m
servicegraph-1100735962-tdh78 1/1 Running 0 4m
2.3.1.安装Istio命令行工具
您需要做的最后一件事是在命令行上使istioctl可用。 istioctl是Istio命令行工具,您可以使用它手动注入istio-proxy边车以及创建,更新和删除Istio资源文件。当您解压Istio发行版时,您将拥有一个名为/ bin的文件夹,其中包含istioctl二进制文件。你可以像这样将它添加到你的路径中:
exportISTIO_HOME=~/istio-0.5.1
exportPATH=$ISTIO_HOME/bin:$PATH
现在,在命令行中,您应该能够输入以下内容并查看有效的响应:
istioctl version
Version: 0.5.1
GitRevision:c9debceacb63a14a9ae24df433e2ec3ce1f16fc7
User: root@211b132eb7f1
Hub: docker.io/istio
GolangVersion: go1.9
BuildStatus: Clean
此时,您已准备好继续安装示例服务。
2.4.Java微服务安装示例
为了有效演示Istio的功能,您需要使用一组相互交互和通信的服务。在本节中,我们与您合作的服务是为网站(考虑零售,金融,保险等)虚拟和简单地重新创建客户门户网站。在这些情况下,客户服务将允许客户为网站的某些方面设置偏好。这些偏好将有机会从提供建议的推荐引擎中获得推荐。沟通的流程如下所示:
Customer >Preference > Recommendation
从这一点来看,最适合你的是本书附带的源代码。您可以从https://github.com/redhat-developer-demos/istio-tutorial检出源代码并切换到分支书,如下所示:
git clonehttps://github.com/redhat-developer-demos/istio-tutorial.git
cd istio-tutorial
git checkout book
2.4.1.浏览代码库
如果您导航到刚刚克隆的istio-tutorial子文件夹,则应该会看到少数文件夹。您应该看到客户,首选项和建议文件夹。这些文件夹分别包含我们将用来演示Istio功能的相应服务的源代码。
客户和偏好服务都是Java SpringBoot实现。看看源代码。您应该看到REST服务的相当直接的实现。例如,以下是客户服务的端点:
@RequestMapping("/")
publicResponseEntity<String> getCustomer() {
try {
String response =restTemplate.getForObject(remoteURL,
String.class);
return ResponseEntity.ok(String.format(RESPONSE_STRING_FORMAT,
response.trim()));
} catch(HttpStatusCodeException ex) { .... }
}
我们暂时排除了异常处理。您可以看到,此HTTP端点只是调用优先服务,并返回来自首选项的响应,前提是固定的customer =>%s字符串。请注意,除了Spring的RestTemplate之外,我们没有使用额外的库。
=====================================================================
大魏注:
在Istio出现之前,微服务之间的调用,经常需要写到应用的源码中,这样的弊端显而易见,如果微服务之间的调用出现任何变更,需要修改源码。而在istio的模式下,开发人员只需要关注应用代码本身。
例如,我们看一段代码,java调用hytrix实现限流,需要在代码中引用hytrix,更要命的是,限流的参数需要写到源码里。
而Istio,面向的是PaaS的4-6层。这样,开发人员只需要关注大麦本身即可。微服务之间的调用,通过修改yaml文件,而非修改源码实现。
====================================================================
我们不会在断路,重试,客户端负载平衡库等方面封装这些调用。我们不添加任何特殊的请求跟踪或请求镜像功能。这是一个关键点。我们希望您编写的代码可以让您构建强大的业务逻辑,而无需将应用程序网络问题与您的代码库和依赖关系树结合在一起。
在前面的例子中,为了简洁起见,我们忽略了异常处理,但异常处理也是代码的重要部分。大多数语言提供了一些检测和处理运行时失败的机制。当你尝试调用你的代码中的方法,你知道可能会失败,你应该注意捕捉这些特殊的行为并适当地处理它们。在客户HTTP端点的情况下,您尝试通过网络拨打首选服务。这个调用可能会失败,你需要用一些异常处理来包装它。您可以在这个异常处理程序中执行有趣的事情,例如进入缓存或调用其他服务。例如,我们可以设想开发人员在执行商业逻辑类型的事情时,如果他们无法获得喜欢返回罐头首选项的列表等等。这种类型的替代路径处理有时被称为面对负路径行为的后备。你不需要特殊的库来为你做这件事。
如果您仔细阅读客户服务的代码库,您可能会偶然发现两个名为HttpHeaderForwarderHandlerInterceptor和HttpHeaderForwarderClientHttpRequestInterceptor的类。这些类一起工作来拦截用于跟踪的任何传入标头,并将它们传播给下一个下游请求。这些头文件是OpenTracing头文件,并在这个不可变变量中定义:
private static final Set<String> FORWARDED_HEADER_NAMES =
ImmutableSet.of(
"x-request-id",
"x-b3-traceid",
"x-b3-spanid",
"x-b3-parentspanid",
"x-b3-sampled",
"x-b3-flags",
"x-ot-span-context",
"user-agent"
);
这些头文件用于将请求关联在一起,将跨度提交给跟踪系统,并可用于请求/响应时序分析,诊断和调试。尽管我们的小帮手拦截器负责将x-b3- *标题进行混洗,但不直接与跟踪系统进行通信。实际上,您不需要在应用程序代码或依赖关系树中包含任何跟踪库。当您传播这些标头时,Istio足够聪明,可以识别它们并将适当的跨度提交给跟踪后端。在本书中的示例和用例中,我们使用云本机计算基金会(CNCF)的Jaeger Tracing项目。您可以通过http://jaegertracing.io/了解有关JaegerTracing的更多信息。您在前一节中将Jaeger安装为Istio安装的一部分。
现在您已经仔细阅读了代码库,让我们构建这些应用程序并在Kubernetes / Openshift部署系统的容器中运行它们。
在部署服务之前,请确保您创建目标名称空间/项目并应用正确的安全权限:
oc new-project tutorial
oc adm policyadd-scc-to-user privileged -z default -n tutorial
2.4.2.建立和部署客户服务
现在,我们来构建和部署客户服务。确保您已登录到您之前安装的minishift,在Istio安装部分。您可以使用以下命令验证您的状态:
oc status
导航到客户目录并像创建Maven Java项目一样构建源代码:
cd customer
mvn clean package
现在你已经建立了你的项目。接下来,您将将应用程序打包为Docker镜像,以便您可以在Kubernetes上运行它:
docker build -t example/customer .
这会将您的客户服务建立为泊坞窗图像。您可以使用以下命令查看Docker生成命令的结果:
docker images |grep example
在customer / src /main / kubernetes目录中,有两个名为Deployment.yml和Service.yml的Kubernetes资源文件。部署该服务,并在注入Istio sidecar代理的同时部署应用程序。尝试运行以下命令以查看部署中注入的边车的外观:
istioctl kube-inject -f src / main / kubernetes /Deployment.yml
检查此输出并将其与未更改的Deployment.yml进行比较。你应该看到已经注入的sidecar,看起来像这样:
- args:
- proxy
- sidecar
- --configPath
- /etc/istio/proxy
- --binaryPath
- /usr/local/bin/envoy
- --serviceCluster
- customer
- --drainDuration
- 2s
- --parentShutdownDuration
- 3s
- --discoveryAddress
- istio-pilot.istio-system:15003
---discoveryRefreshDelay
- 1s
- --zipkinAddress
- zipkin.istio-system:9411
- --connectTimeout
- 1s
- --statsdUdpAddress
- istio-mixer.istio-system:9125
- --proxyAdminPort
- "15000"
- --controlPlaneAuthPolicy
- NONE
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
image: docker.io/istio/proxy:0.5.1
imagePullPolicy: IfNotPresent
name: istio-proxy
resources: {}
securityContext:
privileged: false
readOnlyRootFilesystem: true
runAsUser: 1337
volumeMounts:
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /etc/certs/
name: istio-certs
readOnly: true
您会看到第二个容器注入到您的部署中,其中包含用于查找Istio控制平面的配置,安装在任何其他机密中的卷挂载,您应该看到此容器的名称是istio-proxy。现在您可以创建Kubernetes服务并将边车注入您的部署中:
oc apply -f <(istioctlkube-inject -f
src/main/kubernetes/Deployment.yml)-n tutorial
oc create -fsrc/main/kubernetes/Service.yml -n tutorial
由于客户是最前端的微服务(客户>首选项>推荐),因此您应该添加一个OpenShift Route来公开该端点:
oc expose service customer
curlcustomer-tutorial.$(minishift ip).nip.io
您应该看到以下错误,因为偏好和建议尚未部署:
customer => I/O error on GET request for "http://preference:8080":
preference; nested exception is java.net.UnknownHostException:preference
现在,您可以在此示例中部署其余的服务。
2.4.3.构建和部署首选项服务
就像您为客户服务所做的一样,在本节中,您将构建,打包并部署您的偏好服务:
cd preference
mvn clean package
docker build -texample/preference .
您也可以像以前为客户服务所做的那样,将Istio sidecar代理注入到您的部署中以用于首选项服务:
oc apply -f <(istioctlkube-inject -f
src/main/kubernetes/Deployment.yml)-n tutorial
oc create -fsrc/main/kubernetes/Service.yml
最后,再次尝试纠正您的客户服务:
curl customer-tutorial.$(minishift ip).nip.io
响应仍然失败,但这次有点不同:
customer => 503 preference=> I/O error on GET request for
"http://recommendation:8080":recommendation; nested exception is
java.net.UnknownHostException:recommendation
这次失败是因为偏好服务无法到达推荐服务。因此,您将在下一步构建和部署推荐服务。
2.4.4.建立和部署推荐服务
让我们的服务完全合作的最后一步就是部署推荐服务。 就像在以前的服务中一样,您将通过以下几个步骤来构建,打包和部署到Kubernetes上:
cd recommendation
mvn clean package
docker build -texample/recommendation:v1 .
oc apply -f <(istioctlkube-inject -f
src/main/kubernetes/Deployment.yml)-n tutorial
oc create -fsrc/main/kubernetes/Service.yml
oc get pods -w
在Ready列下查找“2/2”。 Ctrl-C打破等待,现在当你卷曲时,你会看到更好的回应:
curlcustomer-tutorial.$(minishift ip).nip.io
customer => preference=> recommendation v1 from '99634814-sf4cl': 1
成功! 三种服务之间的呼叫链按预期工作。 现在您已经可以互相通话了,我们继续讨论Istio的一些核心功能以及它为解决服务之间出现的问题带来的力量。
2.4.5.构建和部署到Kubernetes
Kubernetes部署和管理已经构建为Docker容器的应用程序。 在前面的例子中,您在每个步骤中都将应用程序构建并打包到Docker容器中。 docker build和oc create -f someyaml.yml的完全手动部署过程有其他选择。 这些替代品包括oc新应用程序和称为源到图像(S2I)的功能。 S2I是一个OpenShift-only功能,与vanillaKubernetes不兼容。还有一个fabric8-maven-plugin,它是Java应用程序的maven插件。fabric8-maven-plugin允许您在现有的Java工具中轻松地生活,并且仍然构建Docker镜像并与Kubernetes交互,而无需了解Dockerfiles或Kubernetes资源文件。 maven插件自动构建Kubernetes资源文件,您还可以使用它来快速部署,取消部署和调试在Kubernetes中运行的Java应用程序。
3.交通管制
正如我们在前几章中看到的,Istio由一个控制平面和一个数据平面组成。 数据平面由应用程序体系结构中的代理组成。 我们一直在寻找一种称为sidecar的代理部署模式,这意味着每个应用程序实例都有自己的专用代理,所有网络流量在到达应用程序之前都会通过它进行传输。这些边车代理可以单独配置,根据需要进行路由,过滤和扩充网络流量。在本章中,我们将介绍一些您可以通过Istio利用的流量控制模式。您可能认识到这些模式是由像Netflix,亚马逊或Facebook这样的大型互联网公司所实施的模式。
3.1.更高级的金丝雀版
==============================================================================
大魏注:
关于微服务部署方式,我们常说的有:蓝绿部署、滚动部署、灰度发布、灰度上线(dark launch)。我们简单看看它们的特点和区别:
(1) 蓝绿部署:不停止老版本,额外搞一套新版本,等测试发现新版本OK后,删除老版本。
(2) 滚动发布:按批次停止老版本实例,启动新版本实例。
(3) 灰度发布/金丝雀部署(AB test就是一种灰度发布方式):不停止老版本,额外搞一套新版本,常常按照用户设置路由权重,例如90%的用户维持使用老版本,10%的用户尝鲜新版本。不同版本应用共存,经常与A/B测试一起使用,用于测试选择多种方案。
(4) 灰度上线(dark launch):这是产品发布的另一种手段,往往用于需要一次发布的产品。
在istio出现之前,openshift主要通过router来实现这几种部署方式。在router上,可以动态调整一个FQDN后端连接的service的流量比重。
但router的实现方式默认只能实现入口流量的版本控制,无法针对客户端不同(不同的请求、不同的地理位置)来实现版本控制。而Istio可以实现。
=========================================================
金丝雀部署的概念在过去几年中变得相当流行。 “金丝雀部署”这个名字来自“煤矿中的金丝雀”概念。矿工们习惯于将笼中的金丝雀带入矿井,以检测是否存在危险气体,因为金丝雀比人类更容易受到有毒气体的影响。金丝雀不仅会提供精美的音乐歌曲来招待矿工,而且如果它在任何时候都从高处坍塌,矿工们就会迅速离开煤矿。
金丝雀部署具有类似的语义。使用Canary部署,您可以将新版本的代码部署到生产环境,但只允许一部分流量访问它。也许只有beta客户,也许只有你的组织的内部员工,也许只有ios用户,等等。在金丝雀离开之后,您可以监视异常情况,不良行为,服务水平协议(SLA)等方面的变化。如果它没有任何不良行为,则可以开始慢慢部署新版本代码的更多实例。如果它表现出不良行为,可以将其从生产中拉出来。 Canary部署允许您部署更快,但只需进行“糟糕的”代码更改即可实现最小的中断。
默认情况下,Kubernetes为服务后面的所有Pod提供开箱即用的循环负载均衡。如果您只希望所有最终用户流量的10%达到您的最新不可变容器,那么您必须至少有10比1的旧Pod与新Pod相匹配。随着Istio,你可以更加细致。您可以指定只有三个Pod中只有2%的流量路由到最新版本。 Istio还可以让您逐渐增加新版本的整体流量,直到所有最终用户都已迁移完毕,旧版本的应用逻辑/代码可以从生产环境中移除。
3.3.1.交通路由
正如我们之前提到的,Istio允许更细粒度的金丝雀部署。借助Istio,您可以指定控制流向部署的流量的路由规则。具体而言,Istio使用RouteRule资源来指定这些规则。我们来看一个RouteRule的例子:
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-default
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 1
route:
- labels:
version: v1
weight: 100
此RouteRule定义允许您配置一定比例的流量并将其引导至特定版本的推荐服务。在这种情况下,推荐服务的100%流量将始终转到与标签版本v1相匹配的Pod。这里选择pods与基于标签匹配的Kubernetes选择器模型非常相似。因此,尝试与推荐服务进行通信的服务网格中的任何服务都将始终路由到推荐服务的v1版本。
上述的路由行为不仅适用于入口流量,即进入网状网的流量。这适用于网格内的所有服务间通信。正如我们在示例中所说明的那样,这些路由规则适用于服务调用图中可能很深的服务。如果您将服务部署到不属于服务网格的Kubernetes,它将不会看到这些规则,并且将遵守默认的Kubernetes负载平衡规则(如刚刚所述)。
3.3.2.路由到特定版本的部署
为了演示更复杂的路由,以及Canary最终展示的内容,我们来部署我们推荐服务的第2版。首先,您需要对推荐服务的源代码进行一些更改。将com.redhat.developer.demos.recom mendation.RecommendationVerticle中的RESPONSE_STRING_FORMAT字符串更改为如下所示:
private static final String RESPONSE_STRING_FORMAT =
"recommendation v2 from '%s': %d ";
现在做这个代码的构建和包装为v2:
cd recommendation
mvn clean package
docker build -t example/recommendation:v2 .
最后,注入Istio边车代理并将其部署到Kubernetes中:
oc apply -f <(istioctl kube-inject -f
src/main/kubernetes/Deployment-v2.yml) -n tutorial
您可以运行oc get pods -w来观察pods并等待它们全部出现。当所有pods成功运行时,您都会看到类似这样的内容:
NAME READY STATUS RESTARTS AGE
customer-3600192384-fpljb 2/2 Running 0 17m
preference-243057078-8c5hz 2/2 Running 0 15m
recommendation-v1-60483540-9snd9 2/2 Running 0 12m
recommendation-v2-2815683430-vpx4p 2/2 Running 0 15s
此时,如果您控制客户端点,则应该在两个版本的推荐服务中看到流量负载均衡。你应该看到这样的东西:
#!/bin/bash
while true
do curl customer-tutorial.$(minishift ip).nip.io
sleep .1
done
customer => preference => recommendation v1 from'2819441432-qsp25': 29
customer => preference => recommendation v2 from'99634814-sf4cl': 37
customer => preference => recommendation v1 from'2819441432-qsp25': 30
customer => preference => recommendation v2 from'99634814-sf4cl': 38
customer => preference => recommendation v1 from'2819441432-qsp25': 31
customer => preference => recommendation v2 from '99634814-sf4cl':39
现在您可以创建第一个RouteRule并将所有流量路由到推荐服务的v1。您应该导航到您从istio-tutorial目录克隆的源代码的根目录,然后运行以下命令:
istioctl create -f istiofiles/route-rule-recommendation-v1.yml
-n tutorial
现在,如果您尝试查询客户服务,则应该看到所有流量都路由到服务的v1版本:
#!/bin/bash
while true
do curl customer-tutorial.$(minishift ip).nip.io
sleep .1
Done
customer => preference => recommendation v1 from '1543936415':1
customer => preference => recommendation v1 from '1543936415':2
customer => preference => recommendation v1 from '1543936415':3
customer => preference => recommendation v1 from '1543936415':4
customer => preference => recommendation v1 from '1543936415':5
customer => preference => recommendation v1 from '1543936415':6
金丝雀版本推荐v2
现在,所有流量都会转到推荐服务的v1版本,您可以使用Istio发布加那利版本。金丝雀的发布应该占到90%的流量。为此,您需要在新的RouteRule中指定加权路由规则,如下所示:
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-v1-v2
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 5
route:
- labels:
version: v1
weight: 90
- labels:
version: v2
weight: 10
正如您所看到的,您使用此RouteRule将90%的流量发送到v1和10%的流量到v2。关于此RouteRule的一个重要事项是优先值。在前面的示例中,我们将此路由规则设置为5,这意味着它具有比将所有流量路由到v1的早期规则更高的优先级。尝试创建它并查看将负载加载到服务时会发生什么情况:
istioctl create -f istiofiles/route-rule-recommendation-v1_and_v2.yml
-n tutorial
如果您开始像以前的步骤一样针对客户服务发送负载,则您应该看到只有一小部分流量实际上使其成为v2。这是一个金丝雀版本。您应该监视您的日志,指标和跟踪系统,以查看此新版本是否已将任何负面的意外或意外行为引入系统。
继续推出建议v2
此时,如果没有不良行为出现,您应该对我们的推荐服务v2更有信心。然后您可能想要将流量增加到v2。你可以用另一个看起来像这样的RouteRule做到这一点:
apiVersion:config.istio.io/v1alpha2
kind: RouteRule
metadata:
name:recommendation-v1-v2
spec:
destination:
namespace:tutorial
name:recommendation
precedence: 5
route:
- labels:
version: v1
weight: 50
- labels:
version: v2
weight: 50
通过这个RouteRule,我们将打开流量高达50%到v1,50%到v2。请注意,优先级仍然是相同的值(它与金丝雀版本一样,为5),并且路由规则的名称与金丝雀版本(recommendation-v1-v2)相同。当您使用istioctl创建此路由规则时,应该使用replace命令:
istioctl replace-f
istiofiles/route-rule-recommendation-v1_and_v2_50_50.yml-n tutorial
现在您应该可以实时看到交通行为的变化。您应该看到大约一半的流量转到推荐服务的v1,一半转到v2。您应该看到类似以下的内容:
customer =>preference => recommendation v1 from '1543936415': 192
customer =>preference => recommendation v2 from '3116548731': 37
customer =>preference => recommendation v2 from '3116548731': 38
customer =>preference => recommendation v1 from '1543936415': 193
customer =>preference => recommendation v2 from '3116548731': 39
customer =>preference => recommendation v2 from '3116548731': 40
customer =>preference => recommendation v2 from '3116548731': 41
customer =>preference => recommendation v1 from '1543936415': 194
customer =>preference => recommendation v2 from '3116548731': 42
最后,如果此版本的所有内容都保持良好状态,则可以将所有流量切换到推荐服务的第2版。您需要安装将所有流量路由到v2的RouteRule:
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-default
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 1
route:
- labels:
version: v2
weight: 100
您可以像这样替换v1路由规则:
istioctl replace -n tutorial -f
istiofiles/route-rule-recommendation-v2.yml
请注意,此路由规则的优先级设置为1.这意味着前面步骤中使用的trafficcontrolRouteRules(其优先级值设置为5)的优先级仍然较高。确实如此。您需要下一步删除Canary / Rollout路由规则,以便所有流量均与v2路由器相匹配:
istioctl delete routerule-n tutorial recommendation-v1-v2
现在您应该看到推荐服务的所有流量都转到v2:
customer =>preference => recommendation v2 from '3116548731': 308
customer =>preference => recommendation v2 from '3116548731': 309
customer =>preference => recommendation v2 from '3116548731': 310
customer =>preference => recommendation v2 from '3116548731': 311
customer =>preference => recommendation v2 from '3116548731': 312
customer =>preference => recommendation v2 from '3116548731': 313
customer =>preference => recommendation v2 from '3116548731': 314
customer =>preference => recommendation v2 from '3116548731': 315
将路由规则恢复为v1
要清理本节,请替换路由规则以将流量返回到推荐服务的v1版本:
istioctl replace -n tutorial -f
istiofiles/route-rule-recommendation-v1.yml
3.3.3.基于头的路由
您已经了解了如何使用Istio基于服务元数据进行细粒度的路由。您还可以使用Istio根据请求级元数据进行路由。
例如,可以使用匹配谓词根据符合指定标准集的请求设置特定的路由规则。例如,您可能希望根据地理位置,移动设备或浏览器将流量拆分为特定服务。让我们看看如何使用Istio.With Istio,您可以在RouteRule中使用匹配子句来指定谓词.For例如,看看下面的RouteRule:
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-safari
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 2
match:
request:
headers:
user-agent:
regex:".*Safari.*"
route:
- labels:
version: v2
此规则使用基于请求标头的匹配子句,仅当请求包含“Safari”作为用户代理标头的一部分时才会匹配。如果请求与谓词匹配,它将被路由到推荐服务的v2。请注意,它的优先级高于默认路由规则(回想起来,默认路由规则将每个请求路由到v1,优先级为1)。安装规则:
$ istioctl create -f
istiofiles/route-rule-safari-recommendation-v2.yml -n tutorial
让我们试试看:
$ curl customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v1 from '1543936415':465
如果您传入Safari的用户代理标头,则应将其路由到v2:
$ curl -H 'user-agent: Safari'
customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v2 from '3116548731':318
清理路由规则
进入本节之后,您可以清理已安装的所有路由规则。首先,您应该列出您使用istioctl获得的路由规则:
$ istioctl get routerule -n tutorial
NAME KIND NAMESPACE
recommendation-default RouteRule.v1alpha2.config.istio.io tutorial
recommendation-safari RouteRule.v1alpha2.config.istio.io tutorial
现在你可以删除它们了:
istioctl delete routerulerecommendation-safari -n tutorial
istioctl delete routerulerecommendation-default -n tutorial
3.2.灰度上线(dark launch)
灰度上线对不同的人可能意味着不同的事情实质上,灰度上线是对生产的部署,而不会引起客户流量的注意。您可以选择发布给部分客户(如内部或非客户客户),但更广泛的用户群不会看到该版本。另一种选择是将生产流量复制或镜像到具有新部署的集群,并查看它与现场流量相比的表现。这样您就可以将生产质量请求放入新服务中,而不会影响任何实时流量。
例如,您可以说推荐v1采用实时流量,推荐v2将成为您的新部署。您可以使用Istio将流量为v1的流量镜像到v2群集中。当Istio反映交通情况时,它是以一种无忧无虑的方式实现的。换句话说,Istio将从实时流量的关键路径异步执行镜像,将镜像请求发送到测试集群,而不必担心或关心响应。我们来试试看。
你应该做的第一件事是确保当前没有使用路由规则:
istioctl get routerules -n tutorial
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-mirror
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 2
route:
- labels:
version: v1
weight: 100
- labels:
version: v2
weight: 0
mirror:
namespace: tutorial
name: recommendation
labels:
version: v2
您可以看到,这会将所有流量引导至建议的v1,并且无向v2的流量。 在镜像子句中,指定要接收镜像流量的群集。
接下来,验证您在从istio教程收集的源文件的根目录中,然后运行以下命令:
istioctl create -fistiofiles/route-rule-recommendation-v1-mirror-v2.yml
-n tutorial
现在,在一个终端中,尾部推荐v2服务的日志:
oc logs -f `oc get pods|grep recommendation-v2|awk '{ print $1 }'`
-c recommendation
在另一个窗口中,您可以发送请求:
$ curl customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v1 from '1543936415':466
您可以从响应中看到我们按预期击中了推荐服务的v1。如果您观察v2日志的尾部,您还会看到新的分区,因为它正在处理镜像流量。
您可以使用镜像流量来进行强大的预发布测试,但它并非没有其自身的挑战。例如,新版本的服务可能仍然需要与数据库或其他协作者服务进行通信。为了处理微服务领域的数据,请看看Edson Yanaga的“迁移到微服务数据库”一书。有关高级镜像技术的更详细的处理,您可以查看Christian的博客文章“使用Istio服务网格实现微服务的高级交通阴影模式”。
3.3.出口
默认情况下,Istio通过与该服务一起部署的Istio代理引导源自服务的所有流量。该代理评估其路由规则并决定如何最好地提交请求。 Istio服务网格的一个好处是,默认情况下,它会阻止所有出站(群集外)流量,除非您专门明确地创建了路由规则以允许流量流出。从安全角度来看,这是至关重要的。您可以在零信任网络体系结构以及传统的基于边界的安全性中使用Istio。在这两种情况下,Istio都可以帮助防止恶意代理获得单一服务的访问权限,并回拨到命令与控制系统,从而允许攻击者完全访问网络。默认情况下,阻止任何传出访问,并允许路由规则不仅控制内部流量,还控制任何和所有传出流量,无论您的安全状况来自何处,您都可以使安全状况更好地抵御外部攻击。
为了演示,我们将创建一个服务,向外部网站(即httpbin.org)发出呼叫,并查看它在服务网格中的行为。
从您之前克隆的配套源代码的根目录中,转至egress / egresshttpbin文件夹。这是另一个Spring Boot Java应用程序,它具有以下显着功能:
@RequestMapping
public Stringheaders() {
RestTemplaterestTemplate = new RestTemplate();
String url ="http://httpbin.org/headers";
HttpHeadershttpHeaders = new HttpHeaders();
HttpEntity<String>httpEntity =
newHttpEntity<>("", httpHeaders);
StringresponseBody;
try {
ResponseEntity<String>response
=restTemplate.exchange(url, HttpMethod.GET,
httpEntity,
String.class);
responseBody =response.getBody();
} catch(Exception e) {
responseBody =e.getMessage();
}
returnresponseBody + " ";
}
这个HTTP端点在被调用时会呼叫httpbin.org/headers,这是驻留在公共因特网上的服务,它返回发送到HTTP GET / headers端点的标题列表。现在您可以构建,打包并部署并公开此服务:
$ cdegress/egresshttpbin
$ mvn cleanpackage
$ docker build-t example/egresshttpbin:v1 .
$ oc apply -f<(istioctl kube-inject -f
src/main/kubernetes/Deployment.yml)
$ oc create -fsrc/main/kubernetes/Service.yml
$ oc exposeservice egresshttpbin
您应该无法像这样查询服务:
$curl http://egresshttpbin-tutorial.$(minishift ip).nip.io
你应该看到这样的回应:
404Not Found
当!此服务无法与位于群集外部的公共互联网上的服务进行通信!
我们回到源代码的根目录,并创建一个如下所示的出口规则:
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: httpbin-egress-rule
spec:
destination:
service: httpbin.org
ports:
- port: 80
protocol: http
这EgressRule允许您的流量到达外部互联网,但仅限于httpbin.org网站。在这里,您可以创建规则并再次尝试查询您的服务:
istioctl create-f istiofiles/egress_httpbin.yml -n tutorial
你可以像这样列出出口规则:
$istioctl get egressrule
NAME KIND NAMESPACE
httpbin-egress-rule EgressRule.v1alpha2.config.istio.io tutorial
现在您可以尝试再次调整服务:
curl http://egresshttpbin-tutorial.$(minishift ip).nip.io
好极了! 它应该这次工作! IstioEgressRules允许您的服务通过此服务访问外部互联网。如果您在这一步失败了,您可以为istio教程提交GitHub问题。
参考阅读
魏新宇
"大魏分享"运营者、红帽资深解决方案架构师
专注开源云计算、容器及自动化运维在金融行业的推广
拥有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鉴定级)等管理认证。
拥有红帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技术认证。
以上是关于为微服务引入Istio服务网格(上)的主要内容,如果未能解决你的问题,请参考以下文章
读书摘要之十五------Istio服务网格技术解析与实践(上)