本教程已加入 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:

server {
listen 80;
server_name example.org www.example.org;
#...
}

Gateway:

  servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- example.org
- www.example.org

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

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

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

server {
listen 80;
server_name example.org www.example.org;
#...
} location /some/path/ {
proxy_pass http:/bookinfo:9080/;
}

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

spec:
hosts:
- "www.example.org"
gateways:
# 绑定 Gateway
- mygateway
http:
route:
- destination:
host: bookinfo
port:
number: 9080

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

部署服务

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

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

httpbin.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
kubectl -n bookinfo apply -f httpbin.yaml

配置 Gateway

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

httpbin_gw.yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.s1.whuanle.cn"
- "*"

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

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

kubectl -n bookinfo apply -f httpbin_gw.yaml

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

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

配置 VistualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin

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

kubectl -n bookinfo apply -f httpbin_vs.yaml

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

kubectl get svc istio-ingressgateway  -n istio-system

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

例如:

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
EOF

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

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

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

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

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

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 8000
host: httpbin
subset: v1
EOF

子版本

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

kubectl -n bookinfo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
EOF

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

  host: httpbin

当然,我们也可以写成

  host: httpbin.bookinfo.svc.cluster.local

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

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

  - name: v1
labels:
version: v1

istio-egressgateway

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

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

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

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

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

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

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: google
spec:
hosts:
- www.google.com
addresses:
- 192.168.1.1
ports:
- number: 80
name: http
protocol: HTTP
location: MESH_EXTERNAL
resolution: DNS
endpoints:
- address: "www.google.com"
ports:
http: 80
locality: "us-west1/zone1"
exportTo:
- "*"

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

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

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. “easyExcel”导入的代码实现

    使用easyExcel在导入数据事有很好的使用性,方便操作. 添加依赖: <dependency> <groupId>com.alibaba</groupId> & ...

  2. 【Mybatis】动态SQL

    目录 动态SQL if语句 动态SQL if+where语句 动态SQL if+set语句 动态SQL choose(when,otherwise)语句 动态SQL trim语句 动态SQL SQL片 ...

  3. ITIL4与Devops(一)

    目录 一.服务管理与ITIL 1.1 服务管理现状 1.2 服务管理原则 1.3 ITIL版本发展历程 ITIL2 服务支持 服务交付 服务战略 ITIL3 框架 职能 ITIL 2011 流程的基本 ...

  4. 2021-8-2 Mysql个人练习题

    创建学生表 CREATE TABLE student( id int, uname VARCHAR(20), chinese FLOAT, english FLOAT, math FLOAT ); I ...

  5. redis 中的 set

    set是String中的无序集合  底层是 是 value为null 的hash表  时间复杂化是o(1): sadd  k1 v1 v2 v3  set中添加数据 smembers k1 取出set ...

  6. loopback4:单元测试冻结时间

    解决方案 import {expect} from '@loopback/testlab'; import sinon from 'sinon'; describe('example test', ( ...

  7. Django: 获取头信息

    如何获取请求头信息 使用如下函数request.META.get("HTTP_请求头函数"),需要注意的是,请求头变量需要全部大写. 其他注意事项如下所示: 如果headerkey ...

  8. word中查找替换不能使用 解决方案

    打开查找,然后点更多,最下面点不限定格式

  9. 需求太多处理不过来?MoSCoW模型帮你

    一.MoSCoW模型是什么 MoSCoW模型是在项目管理.软件开发中使用的一种排序优先级的方法,以便开发人员.产品经理.客户对每个需求交付的重要性达成共识. MoSCoW是一个首字母缩略词,代表: M ...

  10. ACl与ACL实验

    ACl与ACL实验 ACL 1,ACL概述及 产生的背景 ACL: access list 访问控制列表 2,ACL应用 ACL两种应用: 应用在接口的ACL-----过滤数据包(原目ip地址,原目 ...