k8s系列之十七 Istio中的服务治理

删除前面配置的目的地规则

[root@k8s-master ~]# kubectl delete destinationrule details
destinationrule.networking.istio.io "details" deleted
[root@k8s-master ~]# kubectl delete destinationrule productpage
destinationrule.networking.istio.io "productpage" deleted
[root@k8s-master ~]# kubectl delete destinationrule ratings
destinationrule.networking.istio.io "ratings" deleted
[root@k8s-master ~]# kubectl delete destinationrule reviews
destinationrule.networking.istio.io "reviews" deleted

删除前面配置的VirtualService

[root@k8s-master rules]# kubectl get VirtualService
NAME       GATEWAYS             HOSTS   AGE
bookinfo   [bookinfo-gateway]   [*]     60m
[root@k8s-master rules]# kubectl delete VirtualService bookinfo
virtualservice.networking.istio.io "bookinfo" deleted

删除前面配置的gateway

[root@k8s-master rules]# kubectl delete gateway bookinfo-gateway
gateway.networking.istio.io "bookinfo-gateway" deleted

流量路由管理

在 Istio 中,流量路由管理是通过 DestinationRule 和 VirtualService 这两个资源来实现的。DestinationRule 用于定义服务的目标规则,例如负载均衡策略、连接池设置等。而 VirtualService 则用于定义服务的路由规则,包括如何将流量路由到不同的版本或实例。

  1. 创建Istio Ingress Gateway,并与应用程序关联
    2bookinfo-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:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  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


创建Istio Ingress Gateway,并与应用程序关联

[root@k8s-master rules]# kubectl apply -f 2bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo unchanged
  1. 为所有服务创建DestinationRule(目的地规则)
    为bookinfo所有的服务创建DestinationRule,该CRD定义了服务所有的版本子集。
    3destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  host: productpage
  subsets:
  - name: v1
    labels:
      version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  host: ratings
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v2-mysql
    labels:
      version: v2-mysql
  - name: v2-mysql-vm
    labels:
      version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details
spec:
  host: details
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
---

创建目标规则

[root@k8s-master rules]# kubectl apply -f 3destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
  1. 创建VirtualService
    通过创建VirtualService并设置路由规则可以配置流量的流向。

这里配置一个将所有流量路由到所有服务的v1 版本。
4virtual-service-all-v1.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        host: details
        subset: v1
---


应用服务

[root@k8s-master rules]# kubectl apply -f 4virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created

访问http://192.168.200.129:31743/productpage
在这里插入图片描述

此时无论如何刷新页面,只可以看见没有星星图案版本的Reviews服务,也就是v1版本的Reviews服务。

基于流量比例的路由

通过Istio我们可以设定流向每个版本流量的比例。在下面的规则中reviews配置了80%v1,20%v2。
5virtual-service-reviews-80-20.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 80
    - destination:
        host: reviews
        subset: v2
      weight: 20


应用服务

[root@k8s-master rules]# kubectl apply -f 5virtual-service-reviews-80-20.yaml
virtualservice.networking.istio.io/reviews configured

配置了20%流量流向v2版本,80%的流量流向v1版本。

刷新页面可以看见黑色星标服务与没有星标的服务交替出现,并且出现的比例大致在1:4左右。
我们可以修改权重,配置可以实时生效,达到灰度发布的目的。

基于身份的路由配置

接下来,将更改路由配置,以将来自特定用户的所有流量路由到特定服务版本。在这种情况下,来自名为 Jason 的用户的所有流量都将路由到该服务reviews:v2。

此示例是由于该productpage服务会为所有出站 HTTP 请求添加自定义标头。
6virtual-service-reviews-test-v2.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1


应用服务

[root@k8s-master rules]# kubectl apply -f 6virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews configured

当我们未登录时将无法看见带有星星标记的服务

在这里插入图片描述
当我们以jason用户登录时,将会看见带有星星标记的服务

在这里插入图片描述

故障注入

故障注入是一种测试技术,用于模拟系统中的故障情况,以验证系统在异常情况下的行为。在 Istio 中,可以使用 Fault Injection 来模拟各种不同类型的故障,例如延迟、错误码、中断等。这有助于评估系统在异常情况下的可靠性和容错性。

延时注入

上文reviews:v2中已经对用户jason进行了基于身份的路由配置

这里在用户 jason 下的reviews:v2和ratings微服务的服务调用之间注入 7 秒延迟。此测试将发现一个有意引入 Bookinfo 应用程序的错误。

请注意,该reviews:v2服务有一个 10 秒的硬编码连接超时。

7virtual-service-ratings-test-delay.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1


[root@k8s-master rules]# kubectl apply -f 7virtual-service-ratings-test-delay.yaml
virtualservice.networking.istio.io/ratings configured

当我们以未登录的状态访问bookinfo应用时,我们不会看见星星标记的服务。

当我们用jason登录时,页面会有一个7秒左右的延迟,并且最后由于超时的原因页面会有错误提示。
在这里插入图片描述

Http故障注入

也可以为服务注入一个Http的故障,如500等。
8virtual-service-ratings-test-abort.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 100.0
        httpStatus: 500
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1


[root@k8s-master rules]# kubectl apply -f 8virtual-service-ratings-test-abort.yaml
virtualservice.networking.istio.io/ratings configured

当我们以未登录的状态访问bookinfo应用时,服务可以正常访问。

当我们用jason登录时,用户登录时会发现ratings服务不可用。
在这里插入图片描述

设置超时时间

我们将前一步的延时缩短一点,缩短为2s,让服务不会因为延时而超时,当我们登录时会有2s左右的延时,但是页面可以正常访问,reviews服务正常提供服务。

我们可以通过配置VirtualService设定服务的超时时间。
9virtual-service-rewiews-test-v2-timeout.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
    timeout: 0.5s

[root@k8s-master rules]# kubectl apply -f 9virtual-service-rewiews-test-v2-timeout.yaml
virtualservice.networking.istio.io/reviews configured

我们设置服务超时的时间为0.5s。

当我们再已jason用户登录时,2s的延迟后服务将会超时报错。

配置熔断

开启自动注入:kubectl label namespace default istio-injection=enabled

1.启动httpbin实例

httpbin.yaml在/usr/local/istio-1.10.4/samples/httpbin下。

[root@k8s-master httpbin]# kubectl apply -f /usr/local/istio-1.10.4/samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created

2.配置熔断器
10dr-httpbin.yaml

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 3m
      maxEjectionPercent: 100

[root@k8s-master rules]# kubectl apply -f 10dr-httpbin.yaml
destinationrule.networking.istio.io/httpbin created

配置文件设置了httpbin服务的tcp流量的最大连接数和http流量的最大请求数为1。

4.启动客户端,连接httpbin服务

root@k8s-master sample-client]# kubectl apply -f /usr/local/istio-1.10.4/samples/httpbin/sample-client/fortio-deploy.yaml
service/fortio created
deployment.apps/fortio-deploy created

foritio作为客户端对httpbin服务发起请求。

查询foritio 服务pod的名称,进入foritio服务容器,对httpbin服务发起请求。

[root@k8s-master sample-client]# kubectl get po
NAME                                   READY   STATUS    RESTARTS   AGE
busybox-7c84546778-9jzpx               1/1     Running   28         68d
busybox-7c84546778-rs5d9               1/1     Running   29         68d
details-v1-6486db986c-8w4m9            2/2     Running   2          5d2h
fortio-deploy-6dc9b4d7d9-m2hpl         1/1     Running   0          36s
httpbin-66cdbdb6c5-c4fqq               1/1     Running   0          4m33s
kindly-robin-mychart-fb68878c8-dlzw8   1/1     Running   1          5d3h
productpage-v1-76ddd6867b-l2sll        2/2     Running   2          5d2h
ratings-v1-54bf9bb699-7sssb            2/2     Running   2          5d2h
reviews-v1-76d5495769-xs4gx            2/2     Running   2          5d2h
reviews-v2-5ff5f7dd8b-jw6wm            2/2     Running   2          5d2h
reviews-v3-7f8467c6ff-wnt6d            2/2     Running   2          5d2h
[root@k8s-master sample-client]# kubectl exec fortio-deploy-6dc9b4d7d9-m2hpl -c fortio -- /usr/bin/fortio curl -quiet http://httpbin:8000/get
HTTP/1.1 200 OK
Server: gunicorn/19.9.0
Date: Tue, 26 Mar 2024 10:09:38 GMT
Connection: keep-alive
Content-Type: application/json
Content-Length: 177
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "args": {},
  "headers": {
    "Host": "httpbin:8000",
    "User-Agent": "fortio.org/fortio-1.17.1"
  },
  "origin": "10.244.2.69",
  "url": "http://httpbin:8000/get"
}

可以看见服务请求成功,那么我们就可以开始提高并发数,测试熔断。

使用两个并发连接 ( -c 2)调用服务并发送 20 个请求 ( -n 20):

$ kubectl exec fortio-deploy-6dc9b4d7d9-m2hpl -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
02:35:44 I logger.go:127> Log level is now 3 Warning (was 2 Info)
Fortio 1.17.1 running at 0 queries per second, 8->8 procs, for 20 calls: http://httpbin:8000/get
Starting at max qps with 2 thread(s) [gomax 8] for exactly 20 calls (10 per thread + 0)
Ended after 45.6804ms : 20 calls. qps=437.82
Aggregated Function Time : count 20 avg 0.00447278 +/- 0.002527 min 0.0030049 max 0.0126282 sum 0.0894556
# range, mid point, percentile, count
>= 0.0030049 <= 0.004 , 0.00350245 , 70.00, 14
> 0.004 <= 0.005 , 0.0045 , 90.00, 4
> 0.011 <= 0.012 , 0.0115 , 95.00, 1
> 0.012 <= 0.0126282 , 0.0123141 , 100.00, 1
# target 50% 0.00369382
# target 75% 0.00425
# target 90% 0.005
# target 99% 0.0125026
# target 99.9% 0.0126156
Sockets used: 2 (for perfect keepalive, would be 2)
Jitter: false
Code 200 : 20 (100.0 %)
Response Header Sizes : count 20 avg 230 +/- 0 min 230 max 230 sum 4600
Response Body/Total Sizes : count 20 avg 854 +/- 0 min 854 max 854 sum 17080
All done 20 calls (plus 0 warmup) 4.473 ms avg, 437.8 qps

可以看到有20%的服务被熔断了。

Istio中的安全策略

Istio中可以直接配置服务间访问时的安全策略,并实时生效

1.Http流量的授权策略
为Http服务设置授权策略可以设定该服务接受哪些服务的调用,这里我们演示的思路是设定一个全局的访问拒绝策略,通过修改配置,一步一步开放每个服务,使其出现在浏览器上。
创建一个全局的访问拒绝策略。
11authorizationPolicy.yaml

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}

[root@k8s-master rules]# kubectl apply -f 11authorizationPolicy.yaml
authorizationpolicy.security.istio.io/allow-nothing created

该策略将会拒绝所有对default命名空间下工作负载的访问,我们访问页面,会发现访问被拒绝了。
在这里插入图片描述
2 开放ProductPage服务

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "productpage-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]

运行该配置文件,会为productpage服务设置授权策略,该策略为设置from字段,则运行所有用户对productpage工作负载进行访问,并且只开放了GET方法的访问。

等待几秒钟,Istiod将规则下发,刷新页面我们会看到productpage页面可以正常访问,但是details服务和reviews服务任然无法正常访问。
在这里插入图片描述

3.开放Details服务

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]

同样配置授权策略为Details服务开放访问,此时配置了from字段,并且绑定了productpage服务的serviceAccount,说明Details服务只接受来自与bookinfo-productpage这个serviceAccount绑定的工作负载的Get请求访问。

运行该配置,等待几秒钟后刷新页面将会看到Details服务可以正常显示了,而reviews服务任然处于拒绝访问状态。
在这里插入图片描述
5.开放Reviews服务

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]

同样我们可以看到reviews服务可以正常访问
在这里插入图片描述
6.开放ratings服务

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ratings-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: ratings
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
    to:
    - operation:
        methods: ["GET"]


可以看到ratings服务已经恢复正常。

文章参考

相关推荐

  1. 为什么K8s需要服务网格Istio

    2024-03-27 06:50:09       12 阅读
  2. k8s服务发现

    2024-03-27 06:50:09       39 阅读
  3. k8s 对外服务 Ingress

    2024-03-27 06:50:09       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-27 06:50:09       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-27 06:50:09       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-27 06:50:09       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-27 06:50:09       20 阅读

热门阅读

  1. k8s 的资源清单

    2024-03-27 06:50:09       17 阅读
  2. 图论相关代码(matlab)

    2024-03-27 06:50:09       19 阅读
  3. Mac OS中Git版本更新(亲测有效)

    2024-03-27 06:50:09       17 阅读
  4. Odoo自动化动作

    2024-03-27 06:50:09       16 阅读
  5. spring boot3 解决跨域几种方式

    2024-03-27 06:50:09       18 阅读
  6. caffe | undefined reference to google protobuf

    2024-03-27 06:50:09       18 阅读
  7. Flink SQL填坑记3:两个kafka数据关联查询

    2024-03-27 06:50:09       18 阅读
  8. react native hooks 如何避免重复请求

    2024-03-27 06:50:09       16 阅读
  9. AI绘画自动生成器平台有哪些

    2024-03-27 06:50:09       17 阅读
  10. python数据解析xpath

    2024-03-27 06:50:09       18 阅读
  11. 微信小程序 第四节课

    2024-03-27 06:50:09       18 阅读
  12. pytorch中的torch.hub.load()

    2024-03-27 06:50:09       21 阅读