AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

Istio 服务网格路由入门

  • 2018-12-04
  • 本文字数:6511 字

    阅读完需:约 21 分钟

Istio服务网格路由入门

摘要: 在本教程中,我们将使用 Istio 演示服务网格最强大的特性之一:“以请求为基准的路由”。这个特性允许把具有指定 HTTP 头标记的任意请求路由到特定的目标,这只有在(OSI)第 7 层代理中才可能实现。没有哪个第 4 层的负载均衡器或代理可以实现此功能。

本文要点

  • 本教程将演示如何在 Kubernetes 集群中安装和使用 Istio 服务网格,并讨论如何充分利用 Istio 的路由功能。

  • 探讨第 4 层和第 7 层网络代理之间的区别,并了解如何充分利用 L7 代理的好处。

  • 用户可以借助 Istio 的可扩展性和服务网格的一般功能实现路由场景,节省大量的时间和资源。


在本教程中,我们将使用Istio演示服务网格最强大的特性之一:“以请求为基准的路由”。这个特性允许把具有指定 HTTP 头标记的任意请求路由到特定的目标,这只有在(OSI)第7层代理中才可能实现。没有哪个第 4 层的负载均衡器或代理可以实现此功能。


如果你想继续阅读本文,我们假设你有一个正在运行的 Kubernetes 集群。对于本教程来说,一个包含 1 个主节点和 2 个工作节点的小集群就足够了。

Istio 是什么?

Istio 是一个服务网格。它由控制平面和数据平面组成。对于数据平面,它使用 Envoy 代理。Envoy 本身是一个 L7 代理和通信总线,专为基于微服务的现代化体系结构而设计。关于 Envoy 代理的更多信息,有大量的文档可供查阅。关于 Istio 是什么,官方文档 也提供了一个很好的解释。



图 1:使用 Istio Pilot 把路由配置注入作为服务“挎斗(sidecar )”运行的 Envoy 代理

以请求为基准的路由

Istio 提供高级的流量管理功能。以请求为基准的路由特性允许我们定义针对传入请求的复杂规则,并决定如何处理请求。以下是可能的用例:


  1. 金丝雀测试——将一小部分用户流量重定向到新的服务版本;

  2. 向不同的用户提供不同的版本——不同价格计划或来自不同地区的用户可能由不同的环境提供服务(例如,这可能是实现 GDPR 要求的一部分);

  3. A/B 测试;

  4. 逐步滚动。


本教程将介绍如何逐步滚动。

步骤 0:安装一个 Kubernetes 集群

为了创建一个集群,你可以使用任何 Kubernetes 解决方案。在本教程中,我们将使用免费的Kublr演示程序部署一个集群。

步骤 1:安装 Istio 控制平面

一种选择是遵照官方的Istio快速入门教程 ,在 Kubernetes 集群中安装控制平面。安装步骤取决于你本地的机器类型(Mac、Linux、Windows),因此我们不会在这里重复安装本地 istioctl 应用程序和 kubectl 的标准步骤,这两个 CLI 工具将用于管理 Kubernetes 和 Istio。


下面是为已经熟悉 Kubernetes 的读者做的一个不那么详细的说明(如果这些信息不够,那么我们建议你遵照官方指南按步骤完成):


  1. 安装 Kubernetes 集群(使用上面列出的其中一种方法,或者使用已有的测试/开发集群) ;

  2. 在本地安装 kubectl https://kubernetes.io/docs/tasks/tools/install-kubectl/ (我们将使用它管理 Kubernetes 集群);

  3. 从 GitHub 发布页面安装 istioctl (用于把 Envoy 代理注入到 pod 以及设置路由规则和策略),安装很简单:

  4. a. 对于 Mac 或 Linux,运行 curl -L https://git.io/getLatestIstio | sh -;

  5. b. 对于 Windows,只要从 zip 压缩包中提取文件,并把二进制文件复制到 PATH(可以简单地复制到 c:\windows\system32\)或者从/bin/目录下运行所有的 istioctl.exe 命令;

  6. c. 切换到提取出的文件所在的文件夹,使用 kubectl apply -f install/kubernetes/istio-demo.yaml 进行安装。


你需要一个 Kubernetes 客户端配置文件以及访问集群仪表板。创建集群的方法不同,获取它们的方式也有所不同。由于我们的示例集群是用 Kublr 部署的,你可以在 Kublr 仪表板中找到以下链接,并将配置文件下载到~/.kube/config (在 Windows 上是 %USERPROFILE%/.kube/config),然后导航到 Kubernetes 仪表板:



使用配置文件中的凭据(找到“username: admin”,并使用该用户及其列出的密码登录到仪表板)。你应该会看到如下所示的仪表板,单击侧边栏中的“NAMESPACES”将显示以下 3 个默认名称空间:



Istio 组件将安装到它们自己的名称空间中。导航到你下载的 Istio 发布存档,提取并运行:kubectl apply -f install/kubernetes/ Istio -demo.yaml。


你会看到创建了许多组件,每个组件在 Istio 官方文档中都有介绍,或者,你可以打开 yaml 文件查看注释—每个资源都记录在该文件中。然后我们可以浏览命名空间,并检查是否一切都创建成功:



点击 istio-system 命名空间,确保在组件创建过程中没有错误或问题。它看起来应该是下面这个样子:



大约有 50 个事件;你可以滚动查看“成功”状态,并注意是否有错误。如果出现错误,你可以在 Istio GitHub 问题页面上发布 Bug 报告,向开发人员指出问题。


我们需要找到“istio-ingress”服务的入口点,以便知道将流量发送到哪里。导航到侧栏中的“istia-system”命名空间。如果在创建后没有看到这个命名空间,只需刷新浏览器页面,然后选择该命名空间,单击“Services”,找到外部端点,如下图所示:



在我们的例子中,它是一个 AWS 弹性负载均衡器,但是,你可能会看到一个 IP 地址,这取决于集群设置。我们将使用这个端点地址访问我们的演示用 Web 服务。

步骤 2:使用 Envoy Proxy Sidecar 部署演示用 Web 服务

现在我们终于到了本教程最有趣的部分。让我们研究下该服务网格的路由功能。首先,我们将部署两个演示用 Web 服务:“blue”和“green”,就像我们在前一个教程中所做的那样。


把以下内容复制到名为 my-websites.yaml 的文件中:




apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v1 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-1 spec: containers: - name: website-version-1 image: kublr/kublr-tutorial-images:v1 resources: requests: cpu: 0.1 memory: 200---apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v2 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-2 spec: containers: - name: website-version-2 image: kublr/kublr-tutorial-images:v2 resources: requests: cpu: 0.1 memory: 200---apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v3 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-3 spec: containers: - name: website-version-3 image: kublr/kublr-tutorial-images:v3 resources: requests: cpu: 0.1 memory: 200---apiVersion: v1kind: Servicemetadata: name: websitespec: ports: - port: 80 targetPort: 80 protocol: TCP name: http selector: app: website
复制代码


请注意,当你想要把 Envoy sidecar 和 pod 一起使用时,应提供“app”标签(供请求跟踪特性使用),而且服务定义中的“spec.ports.name”必须正确命名(http、http2、grpc、redis、mongo),否则,Envoy 将把该服务流量作为普通的 TCP 服务对待,你将无法在那些服务中使用 7 层特性!


此外,pod 只能作为集群中单个“服务”的目标。正如你上面看到的那样,定义文件有三个简单的部署,每个部署使用 Web 服务的不同版本(v1/v2/v3),而这三个简单的服务,每个都指向相应的部署。


现在,我们将使用“istioctl ku -inject”命令 将所需的 Envoy 代理配置添加到这个文件中的 pod 定义中。它将生成一个新的 yaml 文件,其中包含已经准备好使用 kubectl 部署的 Envoy sidecar 的其他组件,运行:istioctl kube-inject -f my-websites。yaml - o my-websites-with-proxy.yaml。


输出文件将包含额外的配置,你可以查看“my-websites-with-proxy.yaml”文件。这个命令使用预定义的 ConfigMap “isti -sidecar-injector”(在我们之前安装 Istio 时安装了它),并将所需的 sidecar 配置和参数添加到部署定义中。当我们部署新文件“my-websites-with-proxy.yaml”时,每个 pod 将有两个容器,一个是演示应用程序和一个是 Envoy 代理。在这个新文件上运行创建命令:kubectl apply -f my-websites-with-proxy.yaml。


按照预期,你将看到以下输出:


deployment "web-v1" created
deployment "web-v2" created
deployment "web-v3" created
service "website" created
复制代码


让我们检查一下这些 pod,看看 Envoy sidecar 是否已经存在:kubectl get pods。


可以看到,每个 pod 有两个容器,一个是网站容器,另一个是代理 sidecar:



此外,你还可以检查 Envoy 代理的日志,运行:kubectl logs -c istio-proxy。


你会看到许多输出,最后几行类似下面这样:


add/update cluster outbound|80|version 1|website.default.svc.cluster.local starting warming
add/update cluster outbound|80|version-2|website.default.svc.cluster.local starting warming
add/update cluster outbound|80|version-3|website.default.svc.cluster.local starting warming
warming cluster outbound|80|version-3|website.default.svc.cluster.local complete
warming cluster outbound|80|version-2|website.default.svc.cluster.local complete
warming cluster outbound|80|version-1|website.default.svc.cluster.local complete

复制代码


这表明,代理 sidecar 健康状况良好,正在那个 pod 中运行。


现在,我们需要部署最小的 Istio 配置资源,将流量路由到我们的服务和 pod,将以下清单保存到一个名为“website-routing.yaml”的文件中:


---apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: website-gatewayspec:  selector:    # 我们希望把哪个pod暴露为Istio路由器    # 该标签指向从istio-demo.yaml文件安装时默认的那个    istio: ingressgateway  servers:  - port:      number: 80      name: http      protocol: HTTP    # 我们在这里指定Kubernetes服务名    # 我们希望使用这个Gateway提供服务    hosts:    - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: website-virtual-servicespec:  hosts:  - "*"  gateways:  - website-gateway  http:  - route:    - destination:        host: website        subset: version-1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:  name: websitespec:  host: website  subsets:  - name: version-1    labels:      version: website-version-1  - name: version-2    labels:      version: website-version-2  - name: version-3    labels:      version: website-version-3

复制代码


这些是 Gateway、VirtualService 和 DestinationRule。这些自定义的 Istio 资源用于管理和配置 Istio -ingressgateway pod 的 Ingress 行为。我们将在下一个教程中更深入地描述它们,并介绍 Istio 配置的技术细节。现在,部署这些资源来访问我们的示例站点:kubectl create -f website-routing.yaml。


下一步是访问我们的演示网站。我们部署了三个“版本”,每个版本显示不同的页面文本和颜色,但是,目前我们只能通过 Istio Ingress 到达版本 1。让我们访问端点,确保 Web 服务已经部署。


查找外部端点,运行:kubectl get services istio-ingressgateway -n istio-system。


或者通过浏览 istio-ingressgateway 服务找到它,如下所示(我们在本教程的开头已经看到过):



点击它可以访问外部端点。你可能会看到几个链接,因为一个链接指向 HTTPS,另一个链接指向负载均衡器的 HTTP 端口。


使我们的“website” Kubernetes 服务仅指向单个部署的确切配置是我们为网站创建的 Istio VirtualService。它告诉 Envoy 代理仅把对“website”服务的请求路由到标签为“version: website-version-1”的 pod(你可能已经注意到,“website”服务的清单只从 pod 中选择一个标签“app: website”,但没有指定从哪个“version”标签选择,所以,如果没有 Envoy 逻辑,则 Kubernetes 服务本身会轮循所有标签为“app: website”的 pod,包括版本 1、2 和 3)。


要更改我们看到的网站版本,你可以更改 VirtualService 清单的以下部分并重新部署:


 http:
- route:
- destination:
host: website
subset: version-1

复制代码


“subset”是我们从 DestinationRule 中选出的、要路由到的正确目标,我们将在下一个教程中深入学习这些资源。

步骤 3: 逐步滚动

通常,当应用程序的新版本需要使用小部分流量进行测试(金丝雀部署)时,普通的 Kubernetes 方法是使用一个新的、但具有相同 pod 标签的 Docker 镜像创建第二个部署,这会导致向这个 pod 标签发送流量的“服务”也会在第二个部署时新插入的 pod 之间进行平衡。然而,你无法轻易将 10%的流量路由到新部署(要精确达到 10%,你得根据所需的百分比保持两个部署之间的 pod 副本比率, 如 9 个“v1 pods”和 1 个“v2 pod”,或者 18 个“v1 pods”和 2 个“v2 pods”),而且不能使用 HTTP 头将请求路由到特定的版本。


Istio 通过其灵活的 VirtualService 配置解决了这一限制。例如,如果你想使用 90/10 规则来路由流量,很简单,如下所示:


---apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: website-gatewayspec:  selector:    # 我们希望把哪个pod暴露为Istio路由器    # 该标签指向从istio-demo.yaml文件安装时默认的那个    istio: ingressgateway  servers:  - port:      number: 80      name: http      protocol: HTTP    # 我们在这里指定Kubernetes服务名    # 我们希望使用这个Gateway提供服务    hosts:    - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: website-virtual-servicespec:  hosts:  - "*"  gateways:  - website-gateway  http:  - route:    - destination:        host: website        subset: version-1      weight: 90    - destination:        host: website        subset: version-2      weight: 10---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:  name: websitespec:  host: website  subsets:  - name: version-1    labels:      version: website-version-1  - name: version-2    labels:      version: website-version-2  - name: version-3    labels:      version: website-version-3
复制代码


GitHub https://github.com/kublr/istio-blog-sample 上提供了本文的源代码。

小结

我们希望本教程可以让对 Istio、它是如何工作的以及如何利用它进行比较复杂的网络路由有一个良好的高层视角。Istio 简化了那些需要花费更多时间和资源的场景的实现。这是一项任何人在研究服务网格时都应该考虑的强大技术。

关于作者


Oleg Chunikhin 是 Kublr 的首席技术官。他拥有 20 年的软件架构和开发经验。作为 Kublr 的 CTO,他负责制定 Kublr 的技术战略和标准。他在 Kublr 的所有工作中倡导 DevOps 标准,并致力于推动容器技术和自动化应用。Oleg 拥有新西伯利亚州立大学数学学士学位以及应用数学和计算机科学硕士学位,并且是 AWS 认证的软件架构师。



Oleg Atamanenko 是 Kublr 的高级软件架构师,拥有与许多不同技术平台打交道的丰富经验。自 2016 年以来,他一直在使用 Kubernetes,他是一名经过认证的 Kubernetes 管理员,也是 Azure 集群自动伸缩器支持的作者。作为一名软件架构师,他已经工作了超过 13 年,熟悉 Docker、Kubernetes、Amazon Web Services (AWS)、敏捷方法论(Scrum、看板),精通 DevOps 语言:Go lang、Java/Scala、bash、Javascript/TypeScript。Atamanenko 有广泛的原生云环境经验,并在开发分布式系统、容器化遗留系统和在 AWS 上实现无服务器项目方面有丰富的经验。


查看英文原文:


https://www.infoq.com/articles/istio-service-mesh-tutorial


2018-12-04 14:283298
用户头像

发布了 1008 篇内容, 共 412.2 次阅读, 收获喜欢 346 次。

关注

评论 9 条评论

发布
用户头像
1
2018-12-04 14:40
回复
1
2018-12-04 14:40
回复
1
2018-12-04 14:40
回复
1
2018-12-04 14:40
回复
查看更多回复
没有更多了
发现更多内容

一周信创舆情观察(10.18~10.24)

统小信uos

netty系列之:netty实现http2中的流控制

程序那些事

Java Netty HTTP 程序那些事 http2

2021终拿下阿里(P7岗)主动分享:5000字面经总结

编程 程序员 程序人生

Linux内核漏洞精准检测如何做?SCA工具不能只在软件层面

华为云开发者联盟

Linux 二进制 漏洞 SCA工具

云短信服务孰优孰劣?博睿数据9月云短信评测报告

博睿数据

你未必知道的 WebRTC – 前世、今生、未来

FinClip

WebRTC

ffmpeg 推拉流示例

webrtc developer

20张图!常见分布式理论与解决方案

Java 架构 面试 分布式 后端

律所CRM软件,适用于律师事务所的系统

低代码小观

CRM 管理系统 事务管理 律所 CRM系统

程序员:平安Java岗面试耗尽了我毕生所学,想了想,还是去字节吧

Java 编程 程序员

银行网点业绩增长缓慢,中科柏诚本地生活高效解决

联营汇聚

演讲VIDEO大放送|如何打造实景三维高效业务支撑架构

焱融科技

云计算 分布式 GIS 高性能 文件存储

一张图彻底搞懂Spring循环依赖

Tom弹架构

Java 架构 Spring Framework

月度发布 | 极狐GitLab14.4版本:禅道集成、预设动态安全扫描DAST和集成错误跟踪功能等新功能上线!

极狐GitLab

2021年1-9月墨天轮最受欢迎的20篇技术文章

墨天轮

MySQL 数据库 oracle

倒计时1天|StarRocks Summit 2021,为您揭开数据分析的秘密!

保姆级教程,从概念到实践帮你快速上手 Apache APISIX Ingress

API7.ai 技术团队

云原生 k8s Apache APISIX ingress

说出来你可能不信,华为技术官珍藏版:SpringBoot全优笔记,限时开源了

Java 程序员 架构 后端 springboot

应用开发专家一席谈:开发低代码,上手低门槛,AppCube使能Citizen Developer,人人都是开发者

华为云开发者联盟

开发者 软件开发 低代码 AppCube 应用开发

JSON必知必会【PDF+视频教程】

FunTester

json 教程 视频 接口测试 FunTester

AISWare AntDB 亚信科技数据库产品特性解读——平滑弹性扩展 (二)

亚信AntDB数据库

微软黑客马拉松@您,低代码风云再赛!

微软商业应用

低代码 Power Platform 黑客马拉松 黑客松

精益求精,零代码训练营第五期顺利结业

明道云

鸿蒙轻内核M核的故障管家:Fault异常处理

华为云开发者联盟

鸿蒙 异常 故障 Fault异常处理 Fault

客户服务CRM系统,提供优质客户服务

低代码小观

软件 CRM 管理工具 客户服务

爱奇艺iOS稳定性测试实践

爱奇艺技术产品团队

ios 测试 稳定性

渗透测试之破解详细演示

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

等保办是啥单位?属于哪个系统?有什么作用?

行云管家

网络安全 信息安全 数据安全 等级保护 等保测评

保障公有云资源安全运维小技巧-使用内网!

行云管家

公有云 内网穿透 内网 云资源 IT运维

阿里教学篇:一切从代码出发,Spring Boot从入门到源码到项目

Java Spring Cloud Spring Boot

WebRTC(66 - 96)Release Notes

webrtc developer

WebRTC

Istio服务网格路由入门_大前端_Oleg Chunikhin_InfoQ精选文章