“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

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:283080
用户头像

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

关注

评论 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
回复
查看更多回复
没有更多了
发现更多内容

借我 1 小时,与 1000 人一起参与开源

腾源会

开源 腾源会

AntDB基于WAL日志的DML数据闪回实现

亚信AntDB数据库

AntDB 国产数据库 AISWare AIDB

五分钟给你的 gRPC 服务加上 HTTP 接口

万俊峰Kevin

Go 微服务 gRPC web开发 go-zero

Promise.allSettled 的 Polyfill 处理

Jerry Wang

JavaScript Promise Async 8月月更 web编程

少儿编程是智商税吗?不花钱让孩子赢在起跑线!

博文视点Broadview

怎么分辨企业转型是“真数字化”还是 “伪数字化”?

雨果

数字化转型

Linux 6.0 第一个候选版本发布

雨果

Liunx

应用缺少POI数据,如何开发地点深度信息?

HMS Core

阿里云鲍文乐:基于事件的自动化运维最佳实践

阿里云弹性计算

事件 自动化运维 CloudOps

美国商务部宣布:EDA等四项技术实施新的出口管制,8月15日生效!

雨果

芯片技术

JSON 之父:JavaScript 已经成为了进步的障碍

雨果

JavaScript

C#/VB.NET 替换 PDF 文件上的现有图像

在下毛毛雨

C# .net PDF 替换图像

预约直播 | 基于预训练模型的自然语言处理及EasyNLP算法框架

阿里云大数据AI技术

深度学习 阿里云 算法框架

开源一夏 | 使用 JavaScript 将文本转换为文件

海拥(haiyong.site)

JavaScript GitHub 开源 前端 8月月更

组件解析:基础组件button的实现

独来独往

大前端 低代码 可视化 组件化 低代码平台

阿里最新的Spring Boot项目开发实战手册,掀起了项目实战变革狂潮

Java面试那些事儿

Java 编程 程序员 面试 架构师

腾讯发布第二季度财报,腾讯云数据库收入同比增长超过30%

科技热闻

CSS

武师叔

8月月更

从入门到高手,数据从业者成长一般经过哪些阶段?

雨果

数据工程师必备技能

Node 之父着急宣布Deno 将迎来重大变革,疑为针对最近大火的“Bun”

雨果

node.js

区块链带你避“坑”,电信诈骗退!退!退!

旺链科技

区块链 产业区块链 电信诈骗

如何在企业数字化团队内部实现分析建模过程全要素的可获得与成果可复现

ModelWhale

团队协作 数字化转型 全要素场景 代码复现 金融场景

为Bert注入知识的力量 Baidu-ERNIE & THU-ERNIE & KBert

了不起的程序猿

Java 编程 后端 java程序员 BERT

迄今为止最完整的DDD实践

阿里技术

DDD 经验分享

GitHub标星139K的:“嵌入式Linux系统开发教程”

收到请回复

Java Linux 程序员 嵌入式 #运维

设备管理|风机的日常运行与维护

PreMaint

企业设备管理 预测性维护 设备健康管理 风机的日常运维

一文搞定架构思维,DFD 的结构化分析,只需明白这3点

老崔说架构

Go-Excelize API源码阅读(十三)—— GetSheetVisible、SetSheetFormatPr

Regan Yue

Go 开源 源码解析 8月日更 8月月更

什么是文件存储?与对象存储有什么区别?

wljslmz

文件存储 8月月更

数据工程师越做越有成就感的7点经验分享

雨果

数据工程师

泄露了,Alibaba697页的MySQL应用实战与性能调优手册,太强了

Java编程日记

Java 编程 程序员 面试 架构师

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