概述
这个应用模仿在线书店的一个分类,显示一本书的信息。 是Istio官方推荐的第一个Demo案例。
页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务:
- productpage. 这个微服务会调用 details 和 reviews 两个微服务,用来生成页面。
- details. 这个微服务中包含了书籍的信息。
- reviews. 这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
- ratings. 这个微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
- v1 版本不会调用 ratings 服务。
- v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
- v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。
下图展示了这个应用的端到端架构。
Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。
Istio 部署
Kubernetes集群
实验中选用三台CentOS 7.6的虚机作为集群Node,Istio 1.10 测试过的 Kubernetes 发行版包括:1.18, 1.19, 1.20, 1.21.
Name | Role | demo |
---|---|---|
master01 | control-plane,master | 192.168.110.70 |
worker01 | worker | 192.168.110.71 |
worker02 | worker | 192.168.110.72 |
docker-ce | runtime | 20.10.8 |
kubernetes | plane | 1.21.3 |
Antrea | CNI | 1.2.1 |
Istio安装
Istio可以选用多种安装形式,参考安装指南 本实验选用:使用 Helm 安装
下载Istio
- 手动在Istio Release页面选择版本,本次选择1.10.3,或使用2.中的自动方法
- 自动下载Istio和工具
curl -L https://istio.io/downloadIstio | sh -
- 转到 Istio 包目录。本次的包是 istio-1.10.3
total 28
drwxr-x---. 2 root root 22 Jul 15 01:32 `bin`
-rw-r--r--. 1 root root 11348 Jul 15 01:32 LICENSE
drwxr-xr-x. 5 root root 52 Jul 15 01:32 manifests
-rw-r-----. 1 root root 854 Jul 15 01:32 manifest.yaml
-rw-r--r--. 1 root root 5866 Jul 15 01:32 README.md
drwxr-xr-x. 20 root root 4096 Jul 15 01:32 `samples`
drwxr-xr-x. 3 root root 57 Jul 15 01:32 tools
安装目录包含:
samples/ 目录下的示例应用程序
bin/ 目录下的 istioctl 客户端二进制文件 .
- 将 istioctl 客户端加入搜索路径或拷贝到/usr/local/bin
export PATH=$PWD/bin:$PATH
Helm安装Istio
- 为 Istio 组件,创建命名空间 istio-system :
$ kubectl create namespace istio-system
- 安装 Istio base chart,它包含了 Istio 控制平面用到的集群范围的资源:
$ helm install istio-base manifests/charts/base -n istio-system
- 安装 Istio discovery chart,它用于部署 istiod 服务:
$ helm install istiod manifests/charts/istio-control/istio-discovery
–set global.hub=“docker.io/istio”
–set global.tag=“1.10.3”
-n istio-system
- (可选项) 安装 Istio 的入站网关 chart,它包含入站网关组件:
$ helm install istio-ingress manifests/charts/gateways/istio-ingress
–set global.hub=“docker.io/istio”
–set global.tag=“1.10.3”
-n istio-system
- (可选项) 安装 Istio 的出站网关 chart,它包含了出站网关组件:
$ helm install istio-egress manifests/charts/gateways/istio-egress
–set global.hub=“docker.io/istio”
–set global.tag=“1.10.3”
-n istio-system
- 确认命名空间 istio-system 中所有 Kubernetes pods 均已部署,且返回值中 STATUS 的值为 Running:
NAME READY STATUS RESTARTS AGE
istio-egressgateway-57c94c475f-sxfwc 1/1 Running 1 20h
istio-ingressgateway-67c99c69bd-4nnj8 1/1 Running 1 20h
istiod-84d4b8cfbd-fmlx6 1/1 Running 0 20h
部署应用
在 Istio 中运行这一应用,无需对应用自身做出任何改变。 只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。 最终的部署结果将如下图所示:
启动应用服务
进入 Istio 安装目录。
Istio 默认自动注入 Sidecar. 请为 default 命名空间打上标签 istio-injection=enabled:
$ kubectl label namespace default istio-injection=enabled
- 使用 kubectl 部署应用:
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# Copyright Istio Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##################################################################################################
# This file defines the services, service accounts, and deployments for the Bookinfo sample.
#
# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
#
# Alternatively, you can deploy any resource separately:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
##################################################################################################
##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
---
Service | Image | port | container_port |
---|---|---|---|
Details | examples-bookinfo-ratings-v1:1.16.2 | 9080 | 9080 |
Ratings | examples-bookinfo-ratings-v1:1.16.2 | 9080 | 9080 |
Reviews | examples-bookinfo-reviews-v1:1.16.2 | 9080 | 9080 |
Productpage | examples-bookinfo-productpage-v1:1.16.2 | 9080 | 9080 |
- 验证服务建立情况
[root@master01 istio-1.10.3]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.102.118.154 <none> 9080/TCP 19h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h
productpage ClusterIP 10.105.83.88 <none> 9080/TCP 19h
ratings ClusterIP 10.106.171.86 <none> 9080/TCP 19h
reviews ClusterIP 10.100.42.119 <none> 9080/TCP 19h
Pod的情况
[root@master01 istio-1.10.3]# kubectl get po
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-h8fn8 2/2 Running 0 19h
productpage-v1-6b746f74dc-w6rsh 2/2 Running 0 19h
ratings-v1-b6994bb9-xl5dg 2/2 Running 0 19h
reviews-v1-545db77b95-4vk5g 2/2 Running 0 19h
reviews-v2-7bf8c9648f-k7mg2 2/2 Running 0 19h
reviews-v3-84779c7bbc-d6wsc 2/2 Running 0 19h
可以看到上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。
- 要确认 Bookinfo 应用是否正在运行,请在某个 Pod 中用 curl 命令对应用发送请求,例如 ratings:
[root@master01 istio-1.10.3]# kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
确定外部访问Ingress
现在 Bookinfo 服务启动并运行中,需要使应用程序可以从外部访问 Kubernetes 集群,例如使用浏览器。可以用 Istio Gateway 来实现这个目标。
- 为应用程序定义 Ingress 网关:
$ kubectl apply -f samples/bookinfo/networking/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:
- "*"
---
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
- 使用 hosts 字段列举虚拟服务的主机——即用户指定的目标或是路由规则设定的目标,本例中是所有;
- 在 http 字段包含了虚拟服务的路由规则,用来描述匹配条件和路由行为,它们把 HTTP/1.1、HTTP2 和 gRPC 等流量发送到 hosts 字段指定的目标;
- route 部分的 destination 字段指定了符合此条件的流量的实际目标地址,本例中指向productpage:9080
- 路由规则按从上到下的顺序选择,虚拟服务中定义的第一条规则有最高优先级
- 确认网关创建完成:
[root@master01 istio-1.10.3]# kubectl get gateways.networking.istio.io
NAME AGE
bookinfo-gateway 17h
- 查看IngressGateway
[root@master01 istio-1.10.3]# kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egressgateway ClusterIP 10.98.141.98 <none> 80/TCP,443/TCP 22h
istio-ingressgateway LoadBalancer 10.98.243.160 <pending> 15021:30499/TCP,80:30047/TCP,443:31601/TCP 22h
可以看到外面再上一步配置的Gateway80端口对应的nodePort
是300047,由于没有配置对外LBer,所以外可以通过http://host:port访问,即http://192.168.110.70:300047
刷新
页面会轮询v1/v2/v3
安装Kiali
Kiali 最初是由 Red Hat 开源的,用于解决 Service Mesh 中可观察性即微服务的可视性问题。目前已获得 Istio 社区的官方支持。 Kiali 提供以下功能:
- 服务拓扑图
- 分布式跟踪
- 指标度量收集和图标
- 配置校验
- 健康检查和显示
- 服务发现
本例中已经给了安装yaml
[root@master01 ~]# kubectl apply -f istio-1.10.3/samples/addons/kiali.yaml
customresourcedefinition.apiextensions.k8s.io/monitoringdashboards.monitoring.kiali.io created
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
monitoringdashboard.monitoring.kiali.io/envoy created
monitoringdashboard.monitoring.kiali.io/go created
monitoringdashboard.monitoring.kiali.io/kiali created
monitoringdashboard.monitoring.kiali.io/micrometer-1.0.6-jvm-pool created
monitoringdashboard.monitoring.kiali.io/micrometer-1.0.6-jvm created
monitoringdashboard.monitoring.kiali.io/micrometer-1.1-jvm created
monitoringdashboard.monitoring.kiali.io/microprofile-1.1 created
monitoringdashboard.monitoring.kiali.io/microprofile-x.y created
monitoringdashboard.monitoring.kiali.io/nodejs created
monitoringdashboard.monitoring.kiali.io/quarkus created
monitoringdashboard.monitoring.kiali.io/springboot-jvm-pool created
monitoringdashboard.monitoring.kiali.io/springboot-jvm created
monitoringdashboard.monitoring.kiali.io/springboot-tomcat created
monitoringdashboard.monitoring.kiali.io/thorntail created
monitoringdashboard.monitoring.kiali.io/tomcat created
monitoringdashboard.monitoring.kiali.io/vertx-client created
monitoringdashboard.monitoring.kiali.io/vertx-eventbus created
monitoringdashboard.monitoring.kiali.io/vertx-jvm created
monitoringdashboard.monitoring.kiali.io/vertx-pool created
monitoringdashboard.monitoring.kiali.io/vertx-server created
查看:
[root@master01 addons]# kubectl get po -n istio-system
NAME READY STATUS RESTARTS AGE
......
kiali-7bdf78768c-9gsvl 1/1 Running 0 17h
配置访问kiali
[root@master01 ~]# kubectl port-forward –address 0.0.0.0 kiali-7bdf78768c-9gsvl 20001 -n istio-system