istio bookinfo配置演示(11)

bookinfo

其中包包中有一个 bookinfo的示例,这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

Bookinfo 应用分为四个单独的微服务:

  • productpage. 这个微服务会调用 detailsreviews 两个微服务,用来生成页面。
  • details. 这个微服务中包含了书籍的信息。
  • reviews. 这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
  • ratings. 这个微服务中包含了由书籍评价组成的评级信息。

reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。

拓扑结构如下:

image-20220713173219338.png

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成(接口API统一),并且 reviews 服务具有多个版本

安装

解压istio后,在samples/bookinfo目录下是相关bookinfo目录,参考官网中的getting-startrd

[root@linuxea_48 /usr/local/istio-1.14.1]# ls samples/bookinfo/ -ll
total 20
-rwxr-xr-x 1 root root 3869 Jun  8 10:11 build_push_update_images.sh
drwxr-xr-x 2 root root 4096 Jun  8 10:11 networking
drwxr-xr-x 3 root root   18 Jun  8 10:11 platform
drwxr-xr-x 2 root root   46 Jun  8 10:11 policy
-rw-r--r-- 1 root root 3539 Jun  8 10:11 README.md
drwxr-xr-x 8 root root  123 Jun  8 10:11 src
-rw-r--r-- 1 root root 6329 Jun  8 10:11 swagger.yaml

而后安装 platform/kube/bookinfo.yaml文件

[root@linuxea_48 /usr/local/istio-1.14.1]# kubectl -n java-demo apply -f samples/bookinfo/platform/kube/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

错误处理

Unhandled exception
Type=Bus error vmState=0x00000000
J9Generic_Signal_Number=00000028 Signal_Number=00000007 Error_Value=00000000 Signal_Code=00000002
Handler1=00007F368FD0AD30 Handler2=00007F368F5F72F0 InaccessibleAddress=00002AAAAAC00000
RDI=00007F369017F7D0 RSI=0000000000000008 RAX=00007F369018CBB0 RBX=00007F369017F7D0
RCX=00007F369003A9D0 RDX=0000000000000000 R8=0000000000000000 R9=0000000000000000
R10=00007F36900008D0 R11=0000000000000000 R12=00007F369017F7D0 R13=00007F3679C00000
R14=0000000000000001 R15=0000000000000080
RIP=00007F368DA7395B GS=0000 FS=0000 RSP=00007F3694D1E4A0
EFlags=0000000000010202 CS=0033 RBP=00002AAAAAC00000 ERR=0000000000000006
TRAPNO=000000000000000E OLDMASK=0000000000000000 CR2=00002AAAAAC00000
xmm0 0000003000000020 (f: 32.000000, d: 1.018558e-312)
xmm1 0000000000000000 (f: 0.000000, d: 0.000000e+00)
xmm2 ffffffff00000002 (f: 2.000000, d: -nan)
xmm3 40a9000000000000 (f: 0.000000, d: 3.200000e+03)
xmm4 dddddddd000a313d (f: 667965.000000, d: -1.456815e+144)
xmm5 0000000000000994 (f: 2452.000000, d: 1.211449e-320)
xmm6 00007f369451ac40 (f: 2488380416.000000, d: 6.910614e-310)
xmm7 0000000000000000 (f: 0.000000, d: 0.000000e+00)
xmm8 dd006b6f6f68396a (f: 1869101440.000000, d: -9.776703e+139)
xmm9 0000000000000000 (f: 0.000000, d: 0.000000e+00)
xmm10 0000000000000000 (f: 0.000000, d: 0.000000e+00)
xmm11 0000000049d70a38 (f: 1238829568.000000, d: 6.120632e-315)
xmm12 000000004689a022 (f: 1183424512.000000, d: 5.846894e-315)
xmm13 0000000047ac082f (f: 1202456576.000000, d: 5.940925e-315)
xmm14 0000000048650dc0 (f: 1214582272.000000, d: 6.000833e-315)
xmm15 0000000046b73e38 (f: 1186414080.000000, d: 5.861665e-315)
Module=/opt/ibm/java/jre/lib/amd64/compressedrefs/libj9jit29.so
Module_base_address=00007F368D812000
Target=2_90_20200901_454898 (Linux 3.10.0-693.el7.x86_64)
CPU=amd64 (32 logical CPUs) (0x1f703dd000 RAM)
----------- Stack Backtrace -----------
(0x00007F368DA7395B [libj9jit29.so+0x26195b])
(0x00007F368DA7429B [libj9jit29.so+0x26229b])
(0x00007F368D967C57 [libj9jit29.so+0x155c57])
J9VMDllMain+0xb44 (0x00007F368D955C34 [libj9jit29.so+0x143c34])
(0x00007F368FD1D041 [libj9vm29.so+0xa7041])
(0x00007F368FDB4070 [libj9vm29.so+0x13e070])
(0x00007F368FC87E94 [libj9vm29.so+0x11e94])
(0x00007F368FD2581F [libj9vm29.so+0xaf81f])
(0x00007F368F5F8053 [libj9prt29.so+0x1d053])
(0x00007F368FD1F9ED [libj9vm29.so+0xa99ed])
J9_CreateJavaVM+0x75 (0x00007F368FD15B75 [libj9vm29.so+0x9fb75])
(0x00007F36942F4305 [libjvm.so+0x12305])
JNI_CreateJavaVM+0xa82 (0x00007F36950C9B02 [libjvm.so+0xab02])
(0x00007F3695ADDA94 [libjli.so+0xfa94])
(0x00007F3695CF76DB [libpthread.so.0+0x76db])
clone+0x3f (0x00007F36955FAA3F [libc.so.6+0x121a3f])
---------------------------------------
JVMDUMP039I Processing dump event "gpf", detail "" at 2022/07/20 08:59:38 - please wait.
JVMDUMP032I JVM requested System dump using '/opt/ibm/wlp/output/defaultServer/core.20220720.085938.1.0001.dmp' in response to an event
JVMDUMP010I System dump written to /opt/ibm/wlp/output/defaultServer/core.20220720.085938.1.0001.dmp
JVMDUMP032I JVM requested Java dump using '/opt/ibm/wlp/output/defaultServer/javacore.20220720.085938.1.0002.txt' in response to an event
JVMDUMP012E Error in Java dump: /opt/ibm/wlp/output/defaultServer/javacore.20220720.085938.1.0002.txt
JVMDUMP032I JVM requested Snap dump using '/opt/ibm/wlp/output/defaultServer/Snap.20220720.085938.1.0003.trc' in response to an event
JVMDUMP010I Snap dump written to /opt/ibm/wlp/output/defaultServer/Snap.20220720.085938.1.0003.trc
JVMDUMP032I JVM requested JIT dump using '/opt/ibm/wlp/output/defaultServer/jitdump.20220720.085938.1.0004.dmp' in response to an event
JVMDUMP013I Processed dump event "gpf", detail "".

如下

echo 0 > /proc/sys/vm/nr_hugepages

见34510,13389

配置完成,pod准备结束

(base) [root@k8s-01 bookinfo]#  kubectl -n java-demo get pod
NAME                             READY   STATUS    RESTARTS   AGE
details-v1-6d89cf9847-46c4z      2/2     Running   0          27m
productpage-v1-f44fc594c-fmrf4   2/2     Running   0          27m
ratings-v1-6c77b94555-twmls      2/2     Running   0          27m
reviews-v1-765697d479-tbprw      2/2     Running   0          6m30s
reviews-v2-86855c588b-sm6w2      2/2     Running   0          6m2s
reviews-v3-6ff967c97f-g6x8b      2/2     Running   0          5m55s
sleep-557747455f-46jf5           2/2     Running   0          5d

1.gateway配置

hosts为*,也就是默认的配置,匹配所有。也就意味着,可以使用ip地址访问

在VirtualService中的访问入口如下

  http:
  - match:
    - uri:
        exact: /productpage

只要pod正常启动,南北流量的访问就能够被引入到网格内部,并且可以通过ip/productpage进行访问

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

apply

(base) [root@k8s-01 bookinfo]# kubectl -n java-demo apply -f networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

而后便可以通过浏览器打开

同时。这里的版本是随着刷新一直在变化

reviews-v1image-20220720175106154.png

reviews-v3image-20220720175015939.png

reviews-v2image-20220720175046687.png

此时在kiali中能看到一个简单的拓扑:

请求从ingress-gateway进入后,到达productpage的v1版本,而后调度到details的v1, 其中reviews流量等比例的被切割到v1,v2,v3,并且v2,v3比v1还多了一个ratings服务,如下图

image-20220721095431030.png

网格测试

安装完成,我们进行一些测试,比如:请求路由,故障注入等

1.请求路由

要开始,需要将destination rules中配置的子集规则,如下

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
---

apply

kubectl -n java-demo apply -f samples/bookinfo/networking/destination-rule-all.yaml
> kubectl -n java-demo apply -f samples/bookinfo/networking/destination-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

而后,对于非登录用户,将流量全发送到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
---

使用如下命令创建即可

kubectl -n java-demo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
> kubectl -n java-demo apply -f samples/bookinfo/networking/virtual-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
PS E:opsk8s-1.23.1-latestistio-企鹅通istio-1.14

此时在去访问,流量都会到v1

image-20220721100513724.png

这取决于定义了三个reviews的子集,如下

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

随后指明了reviews调度到v1

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

如果没有VirtualService这reviews的配置,就会在三个版本中不断切换

2.用户标识调度

此时我们希望某个用户登录就让他转发到某个版本

如果end-user等于json就转发到v2

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

/productpageBookinfo 应用程序上,以 user 身份登录jason

image-20220721111350671.png

登录后

image-20220721111435197.png

kiali变化如下

image-20220721111533493.png

3.故障注入

要了解故障注入,需要了解混沌工程。在云原生上,在某些时候希望能够抵御某种程度局部故障。比如希望允许客户端重试,超时来解决局部问题

istio原生支持两种故障注入来模拟混动工程的效果,注入超时,或者重试故障

基于此前上的两个之上

$ kubectl -n java-demo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
$ kubectl -n java-demo apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  • 使用上述配置,请求流程如下:

    • productpagereviews:v2ratings(仅限用户jason
    • productpagereviews:v1(对于其他所有人)