bookinfo
其中包包中有一个 bookinfo的示例,这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务:
productpage
. 这个微服务会调用details
和reviews
两个微服务,用来生成页面。details
. 这个微服务中包含了书籍的信息。reviews
. 这个微服务中包含了书籍相关的评论。它还会调用ratings
微服务。ratings
. 这个微服务中包含了由书籍评价组成的评级信息。
reviews
微服务有 3 个版本:
- v1 版本不会调用
ratings
服务。 - v2 版本会调用
ratings
服务,并使用 1 到 5 个黑色星形图标来显示评分信息。 - v3 版本会调用
ratings
服务,并使用 1 到 5 个红色星形图标来显示评分信息。
拓扑结构如下:
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-v1
reviews-v3
reviews-v2
此时在kiali中能看到一个简单的拓扑:
请求从ingress-gateway进入后,到达productpage的v1版本,而后调度到details的v1, 其中reviews流量等比例的被切割到v1,v2,v3,并且v2,v3比v1还多了一个ratings服务,如下图
网格测试
安装完成,我们进行一些测试,比如:请求路由,故障注入等
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
这取决于定义了三个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
在/productpage
Bookinfo 应用程序上,以 user 身份登录jason
。
登录后
kiali变化如下
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
-
使用上述配置,请求流程如下:
productpage
→reviews:v2
→ratings
(仅限用户jason
)productpage
→reviews:v1
(对于其他所有人)
注入延迟故障
要测试 Bookinfo 应用程序微服务的弹性,在userreviews:v2
和微服务之间注入 7s 延迟。此测试将发现一个有意引入 Bookinfo 应用程序的错误。ratings
`jason`
如果是jason,在100%的流量上,注入7秒延迟,路由到v1版本,其他的也路由到v1版本,唯一不同是jason访问是有 延迟的,其他人正常,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
apply
> kubectl.exe -n java-demo apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
virtualservice.networking.istio.io/ratings configured
我们打开浏览器测试
并且可以看到Sorry, product reviews are currently unavailable for this book.
中断故障注入
测试微服务弹性的另一种方法是引入 HTTP 中止故障。ratings
在此任务中,将为测试用户的微服务引入 HTTP 中止jason
。
在这种情况下,希望页面立即加载并显示Ratings service is currently unavailable
消息。
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
apply
> kubectl.exe -n java-demo apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
virtualservice.networking.istio.io/ratings configured
kiali如下
4.流量迁移
如何将流量从一个微服务版本转移到另一个版本。
一个常见的用例是将流量从旧版本的微服务逐渐迁移到新版本。在 Istio 中,可以通过配置一系列路由规则来实现这一目标,这些规则将一定比例的流量从一个目的地重定向到另一个目的地。
在此任务中,将使用将 50% 的流量发送到reviews:v1
和 50% 到reviews:v3
。然后,将通过将 100% 的流量发送到 来完成迁移reviews:v3
。
首先,运行此命令将所有流量路由到v1
每个微服务的版本。
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
---
apply
> kubectl.exe -n java-demo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage unchanged
virtualservice.networking.istio.io/reviews configured
virtualservice.networking.istio.io/ratings configured
virtualservice.networking.istio.io/details unchanged
现在无论刷新多少次,页面的评论部分都不会显示评分星。这是因为将 Istio 配置为将 reviews 服务的所有流量路由到该版本reviews:v1
,并且该版本的服务不访问星级评分服务。
reviews:v1
使用reviews:v3
以下清单传输 50% 的流量
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 50
- destination:
host: reviews
subset: v3
weight: 50
apply
> kubectl.exe -n java-demo apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
virtualservice.networking.istio.io/reviews configured
如下
kiali
5.请求超时
使用路由规则的timeout字段指定 HTTP 请求的超时。默认情况下,请求超时被禁用,但在此任务中,将服务超时覆盖为 1 秒。但是,为了查看其效果,还可以在调用服务时人为地引入 2 秒延迟。reviews
`ratings`
在开始之前,将所有的请求指派到v1
kubectl -n java-demo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
而后将reviews调度到v2
kubectl -n java-demo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
EOF
在ratings的v1上注入一个2秒钟的延迟
reviews会访问到ratings
kubectl -n java-demo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
delay:
percent: 100
fixedDelay: 2s
route:
- destination:
host: ratings
subset: v1
EOF
访问如下图,当应用程序调到ratings的时候,会超时2秒
一旦应用程序的上游响应缓慢,势必影响到服务体验,于是,我们将调整,如果上游服务响应超过0.5s就不去请求
kubectl -n java-demo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
timeout: 0.5s
EOF
此时刷新提示Sorry, product reviews are currently unavailable for this book.
因为服务响应超过0.5秒,不去请求了
如果此时,我们认为3秒是可以接受的,就改成3,服务就可以访问到ratings了