基于Istio的高级流量管理二

在这里插入图片描述

流量控制(流量切分)

在这里插入图片描述

请求路由

  • 特定网格中服务的规范表示有 Pilot 维护。服务的 istio 模型和在底层平台(Kubernetes、Mesos以及 Cloud
    Foundry 等)中的表达无关。
  • 特定平台的适配器负责从各自平台中获取元数据的各种字段,然后对服务模型进行填充。
  • istio 引入了服务版本的概念,可以通过版本(v1、v2)或环境(staging、prod)对服务进一步的细分。这些版本不一定是不同的API版本,他们可能是部署在不同环境(staging、prod或者dev 等)中的同一服务的不同迭代(使用这种方式的常见场景包括A/B 测试或者金丝雀部署)。
  • istio 的流量路由规则可以根据服务版本来对服务之间流量进行附加控制。

服务之间的通讯

  • 服务的客户端不知道服务不同版本之间的差异。
  • 它们可以使用服务的主机名或者 IP 地址继续访问服务。
  • Envoy sidecar/ 代理拦截并转发客户端和服务器之间的所有请求和相应。
  • istio 还为同一服务版本的多个实例提供流量负载均衡。可以在服务发现和负载均衡中找到更多信息。
  • istio 不提供 DNS。应用程序可以尝试使用底层平台(kube-dns、mesos-dns 等)中存在的 DNS服务来解析 FQDN。

Ingress 和 Egress

  • istio 假定进入和离开服务网络的所有流量都会通过 Envoy 代理进行传输。
  • 通过将 Envoy 代理部署在服务之前,运维人员可以针对面向用户的服务进行 A/B 测试、部署金丝雀服务等。
  • 通过使用 Envoy 将流量路由到外部 Web 服务(例如,访问 Maps API 或视频服务 API)的方式,运维人员可以为这些服务添加超时控制、重试、断路器等功能,同时还能从服务连接中获取各种细节指标。
    在这里插入图片描述

服务发现和负载均衡

istio 负载均衡服务网格中实例之间的通信

  • istio 假定存在服务注册表,以跟踪应用程序中服务的 pod/VM。它还假设服务的新实例自动注册到服务注册表,并且不健康的实例将被自动删除。
  • Pilot 使用来自服务注册的信息,并提供与平台无关的服务发现接口。网格中的 Envoy 实例执行服务发现,并相应的动态更新其负载均衡池。
  • 网格中的服务使用其 DNS 名称访问彼此,服务的所有 HTTP 流量都会通过 Envoy 自动重新路由。

Envoy 在负载均衡池中的实例之间分发流量

  • istio 目前仅允许三种负载均衡模式:轮询、随机、和带权重的最少请求。
  • 除了负载均衡外,Envoy 还会定期检查池中每个实例的运行状况。Envoy遵循熔断器风格模式, 根据健康检查 API调用的失败率将实例分类为不健康和健康两种。当给定实例的健康检查失败次数超过预定阈值时,将会被从负载均衡池中弹出。类似地,当通过的健康检查数超过预定國值时, 该实例将被添加回负载均衡池。您可以在处理故障中了解更多有关 Envoy 的故障处理功能。
  • 服务可以通过使用 HTTP 503 响应健康检查来主动减轻负担。在这种情况下,服务实例将立即从调用者的负载均衡池中删除。

故障处理

在这里插入图片描述

解读istio 提供的两个对象,Gateway 和 VirtualService

对象 Gateway :

spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "bookinfo.bianmc.com"

解读:定义了 Gateway 规则对象,指定标签 istio=ingressgateway ,处理的域名为 bookinfo.bianmc.com ,定义了一个 80 端口,协议为HTTP。对应了 Envoy 内的 监听器 listener

对象 VirtualService :

spec:
  hosts:
  - "bookinfo.bianmc.com"
  gateways:
  - bookinfo-gateway                      // 指定gateways 转发规则,要与这个对象关联
  http:
  - match:
    - port: 80                            // 默认,可以不写
      uri:
        exact: /productpage
    route:
    - destination:
        host: productpage
        port:
          number: 9080

解读:访问域名 bookinfo.bianmc.com 如果 match 端口80,路径 /productpage ,就 destination 转发到目的地名为 productpage 的svc,svc的端口为9080,所以 VirtualService 对应的是路由 route 转发规则。

合起来解读:

Gateway 对象 在标签为 istio=ingressgateway 的 POD(Envoy )中插入一个规则,这个规则定义一个 listener ,这个 listener 监听 http 协议的80 端口用户处理域名 bookinfo.bianmc.com 的请求。
VirtualService 对象在listener 中加一个转发规则,如果match 端口80,路径 /productpage ,就 destination 转发到目的地名为 productpage 的svc,svc的端口为9080。

实践1:基于域名的方式访问Istio服务网格

用户请求bookinfo的项目,在浏览器中输入域名,由DNS解析到LB负载均衡器,LB负载均衡器会将请求转发到IngressGateway中,IngressGateway根据请求头中的域名,将请求转发到对应的Gateway中,然后在将请求转发到应用程序的 Service资源,最后由应用程序的Pod资源提供应用程序的服务。

1. 注入 sidecar
2. 创建deploy
[root@vms120 httpbin]# kubectl create ns simple
namespace/simple created
[root@vms120 kube]# kubectl apply  -f  bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

[root@vms120 kube]# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
details-v1-7f4669bdd9-qc8z8       2/2     Running   0          91m
productpage-v1-5586c4d4ff-npzkn   2/2     Running   0          91m
ratings-v1-6cf6bc7c85-95fnq       2/2     Running   0          91m
reviews-v1-7598cc9867-bhk25       2/2     Running   0          91m
reviews-v2-6bdd859457-gkspm       2/2     Running   0          91m
reviews-v3-6c98f9d7d7-6fpjt       2/2     Running   0          91m

3. 创建 Gateway 和 VirtualService
[root@vms120 networking]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "bookinfo.bianmc.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "bookinfo.bianmc.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
  
[root@vms120 kube]# kubectl get svc -n istio-system
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
istio-ingressgateway   LoadBalancer   10.101.89.49    <pending>     15021:31342/TCP,80:31857/TCP,443:31702/TCP   2d21h
istiod                 ClusterIP      10.100.70.217   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        2d21h

访问测试

curl -H 指定域名, CLUSTER-IP/地址 
[root@vms120 ~]# curl -H "host:bookinfo.bianmc.com" 10.101.89.49/productpage  -v
* About to connect() to 10.101.89.49 port 80 (#0)
*   Trying 10.101.89.49...
* Connected to 10.101.89.49 (10.101.89.49) port 80 (#0)
> GET /productpage HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host:bookinfo.bianmc.com
>
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 4294
< server: istio-envoy
< date: Mon, 05 Sep 2022 08:46:27 GMT
< x-envoy-upstream-service-time: 23
<
<!DOCTYPE html>
<html>
  <head>
    <title>Simple Bookstore App</title>

LB负载均衡我们采用Nginx来实现,由Nginx去反向代理IngressGateway的NodePort端口来实现基于域名去访问lstio中的程序.

1.安装Nginx
[root@lb~]# yum -y install nginx

2.配置Nginx反向代理Istio的IngressGateway
[root@lb~]# vim /etc/nginx/conf.d/istio-ingressgateway.conf
server {
        listen 80;
        server_name _;

        location / {
                proxy_http_version 1.1;			#开启http的1.1版本协议,istio是1.1版本,nginx默认1.0版本
                proxy_set_header Host $host;			#代理转发时携带请求的主机头
                proxy_pass http://192.168.26.120:31857;		#代理到istio的IngressGateway
        }
}

3.启动Nginx
[root@lb~]# systemctl restart nginx

在这里插入图片描述

实践2:基于Istio服务网格进行重定向

[root@vms120 networking]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "bookinfo.bianmc.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "bookinfo.bianmc.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage/hello
    rewrite:
      uri: /productpage
    route:
    - destination:
        host: productpage
        port:
          number: 9080

只要修改 VirtualService 对象在listener 中的转发规则,让访问 /productpage/hello 的流量 rewrite 重定向到 /productpage

[root@vms120 ~]# curl -H "host:bookinfo.bianmc.com" 10.101.89.49/productpage  -v
* About to connect() to 10.101.89.49 port 80 (#0)
*   Trying 10.101.89.49...
* Connected to 10.101.89.49 (10.101.89.49) port 80 (#0)
> GET /productpage HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host:bookinfo.bianmc.com
>
< HTTP/1.1 404 Not Found

还是访问 /productpage 显示 404

[root@vms120 ~]# curl -H "host:bookinfo.bianmc.com" 10.101.89.49/productpage/hello  -v
* About to connect() to 10.101.89.49 port 80 (#0)
*   Trying 10.101.89.49...
* Connected to 10.101.89.49 (10.101.89.49) port 80 (#0)
> GET /productpage/hello HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host:bookinfo.bianmc.com
>
< HTTP/1.1 200 OK

访问 /productpage/hello 被转发到正确的地址

实践3:基于Istio服务网格部署 HTTPS 证书

1. 生成 https 证书
[root@vms120 ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=bianmc Inc./CN=*.bianmc.io' -keyout bianmc.io.key -out bianmc.io.crt
Generating a 2048 bit RSA private key
..................................+++
...........................................................................+++
writing new private key to 'bianmc.io.key'
-----
2. 创建存放证书的 secret ,也可以在 VirtualService 中直接调用证书文件
[root@vms120 ~]# kubectl create secret tls bianmc-credential --key=bianmc.io.key --cert=bianmc.io.crt -n istio-system
secret/bianmc-credential created
3. 创建 Gateway 和 VirtualService
[root@vms120 networking]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 443                               // https 端口
      name: https                        
      protocol: HTTPS                           // 协议HTTPS
    tls:                                        // 指定 存放证书的 secret
      mode: SIMPLE
      credentialName: bianmc-credential       
      // 也可以在 VirtualService 中直接调用证书文件   
      //       serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      //       privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - "bookinfo.bianmc.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "bookinfo.bianmc.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:                           
        exact: /productpage
      port: 443                     // 监听端口修改
    route:
    - destination:
        host: productpage
        port:
          number: 9080


[root@vms120 ~]# curl  --resolve bookinfo.bianmc.com:443:10.101.89.49      https://bookinfo.bianmc.com/productpage  -v -k
* Added bookinfo.bianmc.com:443:10.101.89.49 to DNS cache
* About to connect() to bookinfo.bianmc.com port 443 (#0)
*   Trying 10.101.89.49...
* Connected to bookinfo.bianmc.com (10.101.89.49) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=*.bianmc.io,O=bianmc Inc.
* 	start date: 905 09:09:50 2022 GMT
* 	expire date: 905 09:09:50 2023 GMT
* 	common name: *.bianmc.io
* 	issuer: CN=*.bianmc.io,O=bianmc Inc.
> GET /productpage HTTP/1.1
> User-Agent: curl/7.29.0
> Host: bookinfo.bianmc.com
> Accept: */*
>
< HTTP/1.1 200 OK

注意 :必须在 istio-system 的 namespace 中创建证书的 secret !!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值