本教程已加入 Istio 系列:https://istio.whuanle.cn

5,出入口网关

Istio 可以管理集群的出入口流量,当客户端访问集群内的应用时, Istio 可以将经过 istio-ingressgateway 的流量实现负载均衡和熔断等一系列功能。

可是,如果集群内的一个应用要访问 google.com ,那么我们可以给内部所有请求了 google.com 的流量设置负载均衡吗?答案是可以,Istio 提供了 istio-egressgateway 实现这种功能。因为 Pod 中的容器要访问网络时,会被 Envoy 拦截,Envoy 可以很容易地分析这些请求,然后通过一系列手段影响着请求的行为。

在本章中,将会简单说一下 istio-ingressgateway 和 istio-egressgateway。

istio-ingressgateway

入口网关指的是从外部经过 istio-ingressgateway 流入集群的流量,需要创建 Gateway 绑定流量。

关于 istio-ingressgateway 经过前面几章的学习,大家应该不陌生了。

istio-ingressgateway 由 Pod 和 Service 组成。 istio-ingressgateway 本身就是一个网关应用,你可以把它当作 Nginx、Apisix、Kong ,你可以从各种各种网关应用中找到与 istio-ingressgateway 类似的概念。

作为一个应用,它需要对外开放一些端口,只有当流量经过这些端口时, istio-ingressgateway 才会起作用。为了在 Kubernetes 中暴露端口, istio-ingressgateway 还有一个 Service 对象。

有了 istio-ingressgateway 之后,我们可以通过 Istio Gateway 监控一些域名或IP,然后暴露集群内部的服务 。

Gateway 的概念跟 Nginx 有很多相似之处。

比如从配置上看, Gateway 跟 Nginx 如果要监控某个入口流量,它们的配置如下:

Nginx:

  1. server {
  2. listen 80;
  3. server_name example.org www.example.org;
  4. #...
  5. }

Gateway:

  1. servers:
  2. - port:
  3. number: 80
  4. name: http
  5. protocol: HTTP
  6. hosts:
  7. - example.org
  8. - www.example.org

这些配置指定了 Gateway 和 Nginx 只监控哪些流量。

紧接着,监控到指定入口的流量之后,需要将流量转发到集群内的应用中。

Nginx 可以直接在同一个配置文件里面设置:

  1. server {
  2. listen 80;
  3. server_name example.org www.example.org;
  4. #...
  5. }
  6. location /some/path/ {
  7. proxy_pass http:/bookinfo:9080/;
  8. }

而 Gateway 需要使用 VirtualService 指定流量转发到哪里,并且 VirtualService 还可以进一步筛选入口地址。

  1. spec:
  2. hosts:
  3. - "www.example.org"
  4. gateways:
  5. # 绑定 Gateway
  6. - mygateway
  7. http:
  8. route:
  9. - destination:
  10. host: bookinfo
  11. port:
  12. number: 9080

所以总结起来,Istio 的做法是 Gateway 监控入口流量,通过 VirtualService 设置流量进入的策略,并指向 Service。而 DestinationRule 则定义了流量流向 Pod 的策略

部署服务

下面我们将使用 httpbin 服务作为示例,如何一步步配置在外部访问 httpbin 服务。

首先部署一个 httpbin 服务,这个 httpbin 服务很简单,包含了 Service 和 Deployment 。

httpbin.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: httpbin
  5. ---
  6. apiVersion: v1
  7. kind: Service
  8. metadata:
  9. name: httpbin
  10. labels:
  11. app: httpbin
  12. service: httpbin
  13. spec:
  14. ports:
  15. - name: http
  16. port: 8000
  17. targetPort: 80
  18. selector:
  19. app: httpbin
  20. ---
  21. apiVersion: apps/v1
  22. kind: Deployment
  23. metadata:
  24. name: httpbin
  25. spec:
  26. replicas: 1
  27. selector:
  28. matchLabels:
  29. app: httpbin
  30. version: v1
  31. template:
  32. metadata:
  33. labels:
  34. app: httpbin
  35. version: v1
  36. spec:
  37. serviceAccountName: httpbin
  38. containers:
  39. - image: docker.io/kennethreitz/httpbin
  40. imagePullPolicy: IfNotPresent
  41. name: httpbin
  42. ports:
  43. - containerPort: 80
  1. kubectl -n bookinfo apply -f httpbin.yaml

配置 Gateway

然后创建一个 Gateway ,指定监听哪些入口流量。

httpbin_gw.yaml

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: Gateway
  3. metadata:
  4. name: httpbin-gateway
  5. spec:
  6. selector:
  7. istio: ingressgateway # use Istio default gateway implementation
  8. servers:
  9. - port:
  10. number: 80
  11. name: http
  12. protocol: HTTP
  13. hosts:
  14. - "httpbin.s1.whuanle.cn"
  15. - "*"

这一步为了大家能够通过域名更加直观地了解 Gateway,大家可以修改 httpbin.s1.whuanle.cn 替换为自己的域名。

然后在自己的电脑中打开 C:\Windows\System32\drivers\etc\hosts 增加一条记录 ,将 IP 指向自己的服务器。

  1. kubectl -n bookinfo apply -f httpbin_gw.yaml

现在,我们已经让 istio-ingressgateway 帮我们关注 httpbin.s1.whuanle.cn 这个地址,如果有人访问了 httpbin.s1.whuanle.cn,那么这个流量将会流入到 httpbin-gateway。

接下来我们将要为 Gateway 配置服务地址,并配置外部允许访问的地址后缀。

配置 VistualService:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: httpbin
  5. spec:
  6. hosts:
  7. - "*"
  8. gateways:
  9. - httpbin-gateway
  10. http:
  11. - match:
  12. - uri:
  13. prefix: /status
  14. - uri:
  15. prefix: /delay
  16. route:
  17. - destination:
  18. port:
  19. number: 8000
  20. host: httpbin

当 Gateway 和 VirtualService 端口只有一个时,不需要配置端口绑定。

  1. kubectl -n bookinfo apply -f httpbin_vs.yaml

找到 istio-ingressgateway 对外暴露的端口。

  1. kubectl get svc istio-ingressgateway -n istio-system

httpbin 是一个 http 测试程序,我们可以通过使用 /status/{状态码} 获取对应的 http 请求状态。

例如:

如果我们不希望这个服务被外界访问到,我们可以先把 /status 删除。

  1. kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. name: httpbin
  6. spec:
  7. hosts:
  8. - "*"
  9. gateways:
  10. - httpbin-gateway
  11. http:
  12. - match:
  13. - uri:
  14. prefix: /delay
  15. route:
  16. - destination:
  17. port:
  18. number: 8000
  19. host: httpbin
  20. EOF

此时你将无法访问 status 路径。但是我们还可以访问 /delay 路径。

httpbin 的 /delay 路径用于测试延迟 http 请求响应使用,/delay/{秒数} 可以指定服务器在多久之后才会返回响应。

例如 http://192.168.3.150:32309/delay/5 将在 5 秒后响应。

httpbin 还有很多路由接口,我们可以通过 VirtualService 配置放通哪些路径。

如果需要全部放通,可以使用:

  1. kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. name: httpbin
  6. spec:
  7. hosts:
  8. - "*"
  9. gateways:
  10. - httpbin-gateway
  11. http:
  12. - match:
  13. - uri:
  14. prefix: /
  15. route:
  16. - destination:
  17. port:
  18. number: 8000
  19. host: httpbin
  20. subset: v1
  21. EOF

子版本

第四章中进行版本路由实验时使用到,可以将流量导入到不同的版本之中。

  1. kubectl -n bookinfo apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: DestinationRule
  4. metadata:
  5. name: httpbin
  6. spec:
  7. host: httpbin
  8. subsets:
  9. - name: v1
  10. labels:
  11. version: v1
  12. EOF

首先是使用 DestinationRule 指向一个 Service:

  1. host: httpbin

当然,我们也可以写成

  1. host: httpbin.bookinfo.svc.cluster.local

通过 host 可以识别到对应的 Kubernetes Service,然后从 Service 对应的 Endpoints 中获得所有 Pod 列表。

通过 Endpoints 获得所有 Pod 之后,查看每个 Pod 的描述信息。当有一个请求到达时,根据 DestinationRule 中的标签选择器,选择合适的 Pod 进行访问。

  1. - name: v1
  2. labels:
  3. version: v1

istio-egressgateway

istio-egressgateway 也是 Istio 中的一种组件,需要自行安装。安装 istio-egressgateway 命令:

  1. helm install istio-egressgateway istio/gateway -n istio-system

在集群中,如果 A 应用访问的地址属于集群中的应用,那么 Istio 可以给这些请求注入各种行为,实现负载均衡和熔断等。

可是,如果集群内部要访问外部的一个服务时,需要配置访问地址,如 aaa.com,我们应该如何实现负载均衡和熔断这些功能呢?

Istio ServiceEntry 是一种资源,允许将外部服务(即不在 Istio 服务网格中的服务)纳入Istio服务网格。通过将外部服务添加到网格,可以使用 Istio 的流量管理和策略功能来控制与这些外部服务的交互。

以下是一个ServiceEntry示例,将外部HTTP服务 www.google.com添加到Istio服务网格:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: ServiceEntry
  3. metadata:
  4. name: google
  5. spec:
  6. hosts:
  7. - www.google.com
  8. addresses:
  9. - 192.168.1.1
  10. ports:
  11. - number: 80
  12. name: http
  13. protocol: HTTP
  14. location: MESH_EXTERNAL
  15. resolution: DNS
  16. endpoints:
  17. - address: "www.google.com"
  18. ports:
  19. http: 80
  20. locality: "us-west1/zone1"
  21. exportTo:
  22. - "*"

在此示例中,我们创建了一个名为httpbin-ext的ServiceEntry资源。指定的主机为httpbin.org,端口号为80,协议为HTTP。此外,我们将resolution设置为DNS,将location设置为MESH_EXTERNAL,表示该服务位于网格之外。

要将此ServiceEntry应用到集群,请将其保存到一个YAML文件(例如:httpbin-ext.yaml),然后运行以下命令:

  1. kubectl apply -f httpbin-ext.yaml

现在,Istio 服务网格中的服务访问 www.google.com 时仍受Istio策略的控制。例如,可以为此 ServiceEntry 创建 VirtualService 以应用流量管理规则,或者为其创建 DestinationRule 以配置负载均衡和连接池设置。

spec: 包含ServiceEntry的具体配置的对象。

  • hosts: 一个包含要导入的外部服务的主机名(FQDN)的列表。例如:["httpbin.org"]
  • addresses: (可选)与外部服务关联的虚拟IP地址的列表。例如:["192.168.1.1"]
  • ports: 一个描述外部服务使用的端口的列表。每个端口都有以下属性:
    • number: 端口号,例如:80。
    • name: 端口的名称,例如:http
    • protocol: 使用的协议,例如:HTTPTCPHTTPS等。
  • location: 服务的位置。可以是MESH_EXTERNAL(表示服务在网格外部)或MESH_INTERNAL(表示服务在网格内部,但不属于任何已知服务)。
  • resolution: 用于确定服务实例地址的解析方法。可以是NONE(默认值,表示不解析地址),STATIC(表示使用addresses字段中的IP地址),DNS(表示使用DNS解析主机名)或MESH_EXTERNAL
  • endpoints: (可选)外部服务的端点列表。每个端点都有以下属性:
    • address: 端点的IP地址或主机名。
    • ports: 一个包含端口名称和端口号的映射,例如:{"http": 8080}
    • labels: (可选)应用于端点的标签。
    • locality: (可选)端点的地理位置,例如:us-west1/zone1
  • exportTo: (可选)一个包含命名空间名称的列表,指定可以访问此ServiceEntry的命名空间。可以使用星号(*)表示所有命名空间。默认值为*
  • subjectAltNames: (可选)用于验证服务器证书主题替代名(SANs)的列表。

读者可以从官方文档中了解更多:

https://istio.io/latest/zh/docs/tasks/traffic-management/egress/egress-control/

Istio 入门(七):出入口网关 - 负载均衡和熔断等一系列功能的更多相关文章

  1. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  2. Istio流量治理原理之负载均衡

    流量治理是一个非常宽泛的话题,例如: ● 动态修改服务间访问的负载均衡策略,比如根据某个请求特征做会话保持: ● 同一个服务有两个版本在线,将一部分流量切到某个版本上: ● 对服务进行保护,例如限制并 ...

  3. SpringCloud无废话入门02:Ribbon负载均衡

    1.白话负载均衡 在上一篇的介绍中,我们创建了两个一模一样的服务提供者:Provider1和Provider2,然后它们提供的服务也一模一样,都叫Hello-Service.为什么一样的服务我们要部署 ...

  4. 干货 | 京东云应用负载均衡(ALB)多功能实操

    应用负载均衡(Application Load Balancer,简称ALB)是京东云自主研发的一款七层负载均衡产品,主要面向HTTP和HTTPS流量的WEB应用程序,提供灵活的功能配置.应用负载均衡 ...

  5. 网关/负载均衡下的consul集群代理

    之前有做过使用单机版的consul实现Prometheus服务注册,以为使用集群版的consul只是将consul服务地址从节点IP变为了网关IP.但比较坑的就是,当使用consul注册一个servi ...

  6. istio入门(01)istio的优势在哪里?

    Istio能做什么?Istio 试图解决微服务实施后面临的问题.Istio 提供了一个完整的解决方案,对整个服务网格行为洞察和操作控制,以满足微服务应用程序的多样化需求. Istio在服务网络中提供了 ...

  7. Windows Azure支持七层负载均衡--Application Gateway

    一直以来Windows Azure的负载均衡(Loadbalancer)功能一直被客户诟病,无法其竞争对手(特别是国内的云厂商)匹敌. Windows Azure的负载均衡器是四层的,前期的版本不支持 ...

  8. linux负载均衡总结性说明(四层负载/七层负载)

    在常规运维工作中,经常会运用到负载均衡服务.负载均衡分为四层负载和七层负载,那么这两者之间有什么不同?废话不多说,详解如下: 一,什么是负载均衡1)负载均衡(Load Balance)建立在现有网络结 ...

  9. windows第七层负载均衡--基于IIS的ARR负载均衡

    载均衡有很多种方法,有硬件负载均衡,软件负载均衡,还可以从域名解析下手. 不过,今天只讲软件负载均衡 软件负载均衡一般分两种,从网络协议来讲(tcp/ip),主要集中在第四层和第七层进行负载均衡. 第 ...

  10. Web负载均衡学习笔记之四层和七层负载均衡的区别

    0x00 简介 简单理解四层和七层负载均衡: ① 所谓四层就是基于IP+端口的负载均衡:七层就是基于URL等应用层信息的负载均衡:同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡. ...

随机推荐

  1. Flex布局常用属性详解

    1. Flex布局与响应式布局 1.1 为什么需要响应式布局? 在电脑PC端,使用浮动,定位同时使用像素px单位就可以完成大部分布局,而且布局完之后不会有大问题,但是到了移动端,移动设备的屏幕尺寸多种 ...

  2. MyBatis实现动态SQL更新

    博主记得在一个周五快下班的下午,产品找到我(为什么总感觉周五快下班就来活 ),跟我说有几个业务列表查询需要加上时间条件过滤数据,这个条件可能会变,不保证以后不修改,这个改动涉及到多个列表查询,于是博主 ...

  3. Solon v2.4.0 发布,Java 生态的新星燃起

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...

  4. 2023-07-23:给你 n 个任务和 m 个工人 每个任务需要一定的力量值才能完成 需要的力量值保存在下标从 0 开始的整数数组 tasks 中 第 i 个任务需要 tasks[i] 的力量才能完

    2023-07-23:给你 n 个任务和 m 个工人 每个任务需要一定的力量值才能完成 需要的力量值保存在下标从 0 开始的整数数组 tasks 中 第 i 个任务需要 tasks[i] 的力量才能完 ...

  5. python连接数据库及查询包含中文错误解决方法

    使用MySQLdb库来连接数据库 import MySQLdb conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='', por ...

  6. Numpy,一篇足以

    numpy 用于数值计算 ndarray, 一个有效的多维数组,能提供以数组为导向的快速数值计算和灵活的广播功能(broadcasting) 便利的数学函数 用于读取/写入(reading/writi ...

  7. 超详细的mysql总结(基本概念、DDL、DML)

    开发中存在着各种数据,比如用户的个人信息.商品详情.购买记录,这些数据都要以一定的方式储存,如果以文本的形式储存,每一次获取都要读取文件,如果信息有修改则需要直接修改文本,大量的数据会需要保存大量的文 ...

  8. call与retn指令

    一. call指令 将call指令下一跳指令压入栈中 jmp跳转到call指令的地址 二. retn指令 pop指令将栈顶元素弹出存储 jmp跳转到该栈顶元素地址 retn n;表示再前两步操作的基础 ...

  9. AI绘画StableDiffusion:云端在线版免费使用笔记分享-Kaggle版

    玩AI绘画(SD),自己电脑配置不够?今天给大家介绍一下如何baipiao在线版AI绘画StableDiffusion. Kaggle 是世界上最大的数据科学社区,拥有强大的工具和资源,可帮助您实现数 ...

  10. 基于bert-base-chinese训练bert模型(最后附上整体代码)

    目录: 一.bert-base-chinese模型下载 二.数据集的介绍 三.完成类的代码 四.写训练方法 五.总源码及源码参考出处 一.bert-base-chinese模型下载 对于已经预训练好的 ...