当前位置:   article > 正文

istio学习记录——VirtualService详解

istio学习记录——VirtualService详解


上一篇使用VirtualService进行了简单的流量控制,并通过Gateway将流量导入到了集群内。这一篇将更加深入的介绍 VirtualService。

k8s中有service,service能够对流量进行负载均衡,那为什么istio又引入了VirtualService呢,因为service的负载均衡只有简单的轮询和会话亲和,istio需要更为细致的流量控制,所以有了VirtualService。

VirtualService特性

流量路由规则:通过 VirtualService,你可以定义一组规则,用于决定如何将请求路由到后端服务。这可以基于多种条件,包括请求的主机名、路径、请求头等

版本控制:VirtualService 允许你指定请求应该路由到哪个后端服务的哪个版本。这对于实现流量的分阶段发布(canary deployment)或蓝绿部署(blue-green deployment)等非常有用。

超时和重试策略:你可以在 VirtualService 中定义超时和重试策略,以控制在请求失败时的行为。这有助于增加服务的可靠性和弹性。

故障注入:Istio 允许你通过 VirtualService 在服务之间注入故障,以测试系统在异常情况下的表现。这对于测试容错性和恢复能力非常有用。

重定向和重写:通过 VirtualService,你可以配置请求的重定向或重写规则。这使得可以对请求进行转发、修改路径或重定向到不同的 URL。

下面将一一演示这些特性的配置,路由规则和版本控制,在前面的文章中有介绍,这里不再重新演示

环境准备

注:test-istio 已经设置了istio的sidecar注入

所有的演示均在test-istio 命名空间进行,因为只有都注入了istio的sidecar,客户端才可以接收到来自 Pilot server 端有关 virtual service 的配置

nginx的deployment

镜像使用: nginx:1.24-alpine版本,标准版没有vi命令,后续操作需要vi修改配置

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx
  5. namespace: test-istio
  6. spec:
  7. selector:
  8. matchLabels:
  9. server: web
  10. app: nginx
  11. replicas: 1
  12. template:
  13. metadata:
  14. labels:
  15. server: web
  16. app: nginx
  17. spec:
  18. containers:
  19. - name: nginx
  20. image: nginx:1.24-alpine
  21. ports:
  22. - containerPort: 80

nginx应用service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: web-svc
  5. namespace: test-istio
  6. spec:
  7. ports:
  8. - name: port
  9. port: 80
  10. protocol: TCP
  11. targetPort: 80
  12. selector:
  13. server: web
  14. app: nginx

httpd的deployment

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: httpd
  6. name: httpd
  7. namespace: test-istio
  8. spec:
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. app: httpd
  13. strategy:
  14. rollingUpdate:
  15. maxSurge: 25%
  16. maxUnavailable: 25%
  17. type: RollingUpdate
  18. template:
  19. metadata:
  20. labels:
  21. app: httpd
  22. server: web
  23. spec:
  24. containers:
  25. - image: httpd:latest
  26. name: httpd

httpd应用的service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: web-httpd
  5. namespace: test-istio
  6. spec:
  7. ports:
  8. - name: port
  9. port: 80
  10. protocol: TCP
  11. targetPort: 80
  12. selector:
  13. server: web
  14. app: httpd

一个curl的client端,用于请求使用

也可以直接用上面的nginx pod

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: curl-client
  5. namespace: test-istio
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: curl-client
  10. replicas: 1
  11. template:
  12. metadata:
  13. labels:
  14. app: curl-client
  15. spec:
  16. containers:
  17. - name: test
  18. image: curlimages/curl:latest
  19. command:
  20. - sleep
  21. - "36000"

故障注入

这里先介绍故障注入【因为后续的超时和重试需要借助故障注入进行演示】

VirtualService支持的故障注入:有延时注入,和中止注入

CRD代码

  1. type HTTPFaultInjection struct {
  2. state protoimpl.MessageState
  3. sizeCache protoimpl.SizeCache
  4. unknownFields protoimpl.UnknownFields
  5. // Delay requests before forwarding, emulating various failures such as
  6. // network issues, overloaded upstream service, etc.
  7. Delay *HTTPFaultInjection_Delay `protobuf:"bytes,1,opt,name=delay,proto3" json:"delay,omitempty"`
  8. // Abort Http request attempts and return error codes back to downstream
  9. // service, giving the impression that the upstream service is faulty.
  10. Abort *HTTPFaultInjection_Abort `protobuf:"bytes,2,opt,name=abort,proto3" json:"abort,omitempty"`
  11. }

注入延时

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - test.com
  9. http:
  10. - fault:
  11. delay:
  12. percentage:
  13. value: 100
  14. fixedDelay: 5s
  15. route:
  16. - destination:
  17. host: web-svc
  18. port:
  19. number: 80

示例表示:100%的请求都将进行延时,延时时间5s

验证延时

  1. kubectl -n test-istio exec -it client-curl sh
  2. # 执行命令
  3. curl -w '\nTotal time: %{time_total}\n' -s test.com

注入中止

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - test.com
  9. http:
  10. - fault:
  11. abort:
  12. percentage:
  13. value: 100
  14. httpStatus: 500
  15. route:
  16. - destination:
  17. host: web-svc
  18. port:
  19. number: 80

所有的请求都将请求失败,返回状态码 500

在将返回状态码修改为503试试

如果有兴趣,可以再尝试修改注入故障的百分比试试

超时和重试策略

超时

超时的示例将通过为nginx服务设置超时时间,然后为httpd注入超时时间,通过nginx转发请求到httpd来达到超时的效果【nginx服务需要在设置的超时时间内返回】

  1. # httpd 的VirtualService
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. name: web-httpd
  6. namespace: test-istio
  7. spec:
  8. hosts:
  9. - example123.com
  10. http:
  11. - fault:
  12. delay:
  13. percentage:
  14. value: 100
  15. fixedDelay: 5s
  16. route:
  17. - destination:
  18. host: web-httpd
  19. port:
  20. number: 80
  21. # nginx 的 VirtualService
  22. apiVersion: networking.istio.io/v1alpha3
  23. kind: VirtualService
  24. metadata:
  25. name: web-vs
  26. namespace: test-istio
  27. spec:
  28. hosts:
  29. - test.com
  30. http:
  31. - timeout: 3s
  32. route:
  33. - destination:
  34. host: web-svc
  35. port:
  36. number: 80

nginx超时时间 3是,httpd的延时注入 5s

配置之前client请求一下,正常返回

下面进入nginx,修改配置,以达成转发到httpd的需求

  1. vi /etc/nginx/conf.d/default.conf
  2. # 替换为自己的pod
  3. kubectl -n test-istio exec -it nginx-v2-5d65f8f449-kqh5v sh
  4. # 修改 web-httpd 是httpd的service
  5. location / {
  6. # root /usr/share/nginx/html;
  7. # index index.html index.htm;
  8. proxy_pass http://example123.com;
  9. }
  10. # 查看配置是否正确
  11. nginx -t
  12. # 重载配置
  13. nginx -s relaod

请求httpd

请求nginx

把超时时间修改为6是,再次尝试 ,请求可以正常返回了

注意:如果你在验证过程中,出现无法解析域名,或者解析域名但是访问test.com 时,返回一些莫名的数据,那么请尝试更换 example123.com 为其他值,在学习时我尝试了很多域名,由于设置了延时导致,代理到了网络中真实的域名,返回了各种网站,

这里也可以直接用service的名称来代替,这样可以不用响应莫名的网站

重试

重试:分为两种情况,1、请求超时,2、服务端响应错误

  1. - retries:
  2. attempts: 3 # 配置重试次数
  3. perTryTimeout: 1s # 超时重试时间, 超过1s则重试
  4. retryOn: 5xx # 重试策略

可配置策略:  x-envoy-retry-on

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - test.com
  9. http:
  10. - retries:
  11. attempts: 3
  12. perTryTimeout: 1s
  13. retryOn: 5xx
  14. route:
  15. - destination:
  16. host: web-svc
  17. port:
  18. number: 80

示例配置重试三次,重试重试时间1s,重试策略所有5xx响应码

4s,本身1s+重试三次 3s

这里还是接着上面的配置进行的,就是nginx转发到httpd,httpd配置了5s延时,下面配置httpd的vs为故障注入——中止50% 

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-httpd
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - example123.com
  9. http:
  10. - fault:
  11. abort:
  12. percentage:
  13. value: 50
  14. httpStatus: 503
  15. route:
  16. - destination:
  17. host: web-httpd
  18. port:
  19. number: 80

监听nginx的日志

 kubectl -n test-istio logs -f nginx-5d65f8f449-kqh5v -c istio-proxy

换个窗口访问一下

重定向和重写

重定向

Redirect 指的是将请求到原目标服务的流量重定向到给另外一个目标服务,客户端请求时不用更改任何方式从而访问到重定向后的目标服务。

  1. type HTTPRedirect struct {
  2. state protoimpl.MessageState
  3. sizeCache protoimpl.SizeCache
  4. unknownFields protoimpl.UnknownFields
  5. // On a redirect, overwrite the Path portion of the URL with this
  6. // value. Note that the entire path will be replaced, irrespective of the
  7. // request URI being matched as an exact path or prefix.
  8. Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"`
  9. // On a redirect, overwrite the Authority/Host portion of the URL with
  10. // this value.
  11. Authority string `protobuf:"bytes,2,opt,name=authority,proto3" json:"authority,omitempty"`
  12. // Types that are assignable to RedirectPort:
  13. //
  14. // *HTTPRedirect_Port
  15. // *HTTPRedirect_DerivePort
  16. RedirectPort isHTTPRedirect_RedirectPort `protobuf_oneof:"redirect_port"`
  17. // On a redirect, overwrite the scheme portion of the URL with this value.
  18. // For example, `http` or `https`.
  19. // If unset, the original scheme will be used.
  20. // If `derivePort` is set to `FROM_PROTOCOL_DEFAULT`, this will impact the port used as well
  21. Scheme string `protobuf:"bytes,6,opt,name=scheme,proto3" json:"scheme,omitempty"`
  22. // On a redirect, Specifies the HTTP status code to use in the redirect
  23. // response. The default response code is MOVED_PERMANENTLY (301).
  24. RedirectCode uint32 `protobuf:"varint,3,opt,name=redirect_code,json=redirectCode,proto3" json:"redirect_code,omitempty"`
  25. }

重定向的CRD定义,可以看出,支持配置

  • uri : 重定向路径

  • authority:重定向后的host

  • Scheme: 重定向的协议

  • RedirectCode:重定向的响应码

  • RedirectPort:重定向端口

这里将发送到nginx的请求重定向到httpd

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - web-svc
  9. http:
  10. - match:
  11. - uri:
  12. prefix: /
  13. redirect:
  14. uri: /
  15. authority: web-httpd

将向ningx的service 的请求重定向到httpd的service的请求,【这里使用的是前缀匹配,所有物理是访问 web-svc,还是web-svc/123, web-svc/456 都会重定向到 web-httpd】

curl -i参数是打印 响应体, -L参数是跟随 重定向

重写

将请求转发给目标服务前修改HTTP请求中指定部分的内容,目标服务也可以是服务本身【既是只对请求路径进行调整】

重写服务自身的接口路径

进入nginx修改nginx的配置

vi /etc/nginx/conf.d/default.conf

  1. location /home/ {
  2. root /usr/share/nginx/html;
  3. index index.html index.htm;
  4. }
  5. location / {
  6. proxy_pass http://web-httpd;
  7. proxy_http_version 1.1;
  8. }

重载nginx配置 nginx -s reload

配置请求路径为 /home/ 前缀时跳转到 / 【根路径代理到了httpd服务】

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - web-svc
  9. http:
  10. - match:
  11. - uri:
  12. prefix: /home/
  13. rewrite:
  14. uri: /
  15. route:
  16. - destination:
  17. host: web-svc
  18. port:
  19. number: 80

进入client请求一下

重写到其他服务

将httpd服务重写到nginx

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: web-vs
  5. namespace: test-istio
  6. spec:
  7. hosts:
  8. - web-httpd
  9. http:
  10. - match:
  11. - uri:
  12. prefix: /
  13. rewrite:
  14. uri: /
  15. route:
  16. - destination:
  17. host: web-svc
  18. port:
  19. number: 80

请求一下

到这里VirtualService的主要功能就演示完成了,后续回继续介绍istio其他相关资源,例如DestinationRule

参考:

Istio / Virtual Service

原文

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/181722
推荐阅读
相关标签
  

闽ICP备14008679号