文章目录
Bookinfo 应用介绍
Bookinfo 应用分为四个单独的微服务:
- productpage:这个微服务会调用 details 和 reviews 两个微服务,用来生成页面。
- details:这个微服务中包含了书籍的信息。
- reviews:这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
- ratings:这个微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
- v1 版本不会调用 ratings 服务。
- v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
- v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。
下图展示了这个应用的端到端架构:
Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子: 它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。
服务依赖图如下所示:
部署Bookinfo
Bookinfo项目地址:https://github.com/whuanle/istio_book/tree/main
Istio前置配置参考《29.云原生KubeSphere服务网格实战之Istio安装配置》
- 创建bookinfo空间,并配置自动注入istio
kubectl create namespace bookinfo
kubectl label namespace bookinfo istio-injection=enabled
kubectl label namespace bookinfo istio.io/rev=1-11-2
- 部署bookinfo
资源文件:https://github.com/whuanle/istio_book/tree/main/3
kubectl -n bookinfo apply -f details_deploy.yaml
kubectl -n bookinfo apply -f details_svc.yaml
kubectl -n bookinfo apply -f details_sa.yaml
kubectl -n bookinfo apply -f ratings_deploy.yaml
kubectl -n bookinfo apply -f ratings_svc.yaml
kubectl -n bookinfo apply -f ratings_sa.yaml
kubectl -n bookinfo apply -f reviews_v1_deploy.yaml
kubectl -n bookinfo apply -f reviews_v2_deploy.yaml
kubectl -n bookinfo apply -f reviews_v3_deploy.yaml
kubectl -n bookinfo apply -f reviews_svc.yaml
kubectl -n bookinfo apply -f reviews_sa.yaml
kubectl -n bookinfo apply -f productpage_deploy.yaml
kubectl -n bookinfo apply -f productpage_svc.yaml
kubectl -n bookinfo apply -f productpage_sa.yaml
_sa.yaml是ServiceAccount:
Istio 为服务之间的通信提供基于双向 TLS 的认证,这是是通过给每个 ServiceAccount 创建一个证书实现的,可以使用 ServiceAccount 验证对方的身份,不同的应用可以共享同一个 ServiceAccount,但是为每个 Deployment 使用单独的 ServiceAccount 可以更好地组织和管理安全配置。
- 查看部署情况
- 访问测试
创建一个 Service 暴露 productpage 的页面
点击Normal user
因为当前使用 Service 绑定 Pod,因此会使用轮询实现负载均衡,你可以多次刷新,会查到右侧的评分星星有所变化
刷新页面出现:
再次刷新页面:
部署入口网关
什么是 Gateway
istio-ingressgateway 并不能直接转发流量到 Pod,它还需要进行一些配置。我们要为 productpage 创建一个站点,绑定对应的域名,这样外部访问 istio-ingressgateway 的端口时,istio-ingressgateway 才知道该将流量转发给谁。在 Istio 中,定义这种绑定关系的资源叫 Gateway。
部署Gateway
参考:https://github.com/whuanle/istio_book/blob/main/5.gateway.md
- 编写ingress_gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
类似nginx监听配置。hosts 表示对外开放的访问路径,你可以绑定域名、IP 等。这里使用 * ,表示所有访问都可以进入此网关。
- 部署
kubectl -n bookinfo apply -f ingress_gateway.yaml
当我们创建 Istio Gateway 之后,istio-ingressgateway 会为我们监控流量,检测不同的域名或端口属于哪个 Istio Gateway
部署 VirtualService
什么是 VirtualService
虽然创建了 Istio Gateway,但是我们还不能直接通过网关访问到前面部署的微服务,我们还需要创建 Istio VirtualService 将 Istio Gateway 跟对应的 Kubernetes Service 绑定起来,然后流量才能正式流向 Pod。
请一定要注意这里,流量实际并不会经过 Service 中,但是 VirtualService 需要通过 Service 来发现 Pod。
这里类似 nginx 配置反向代理,配置监听之后,还需要指向将请求映射到哪个地址。
server {
listen 80;
server_name example.org www.example.org;
#...
}
location /some/path/ {
proxy_pass http://A:9080;
}
VirtualService 的主要目标是为服务提供稳定的入口地址,并通过配置一系列的路由规则来控制流量在网格内的行为。
就以最简单的路由区配来说,Kubernetes Service 是不支持路由规则的,而 Istio 可以通过指定路由后缀中;Service 不支持流量分析,负载均衡只有轮询。而 Istio 利用 Service 来发现 Pod,然后直接将流量转发到 Pod 中,可以实现各种功能。
VirtualService 可以用于实现以下功能:
- 请求路由:将请求路由到特定的服务或版本,例如将请求分发到不同版本的服务,以实现灰度发布或金丝雀发布。
- 请求重试:为失败的请求配置重试策略,以提高服务的可用性。
- 请求超时:设置请求的超时时间,以便在特定时间内没有得到响应时中断请求。
- 请求镜像:将请求的副本发送到另一个服务,用于测试新版本的服务,而不影响实际的生产流量。
- 流量分割:将流量按照特定的比例分发到不同的服务或版本,以实现流量控制。
部署 VirtualService
- 编写productpage_vs.yaml
编写vs跟编写springcloud Gateway路由规则类似,需要指定匹配的路径
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match: # 可以通过 http.match 限制集群外部访问此地址时所能使用的 URL。
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route: # 绑定 Kubernetes Service ,通过 Service 中的服务发现,将流量转发到对应的 Pod 中。
- destination:
# k8s内部服务域名,跨命名空间使用完整名称
host: productpage
port:
number: 9080
这里的 YAML 分为两大部分,第一部分是 http.match,表示暴露了哪些 API 地址,外部访问时只能访问到这些地址。
- 部署vs
kubectl -n bookinfo apply -f productpage_vs.yaml
访问验证一下
访问测试
- 为了确保网关没问题,我们需要执行 Istio 命令查看日志:
# istioctl analyze
Info [IST0102] (Namespace default) The namespace is not enabled for Istio injection. Run 'kubectl label namespace default istio-injection=enabled' to enable it, or 'kubectl label namespace default istio-injection=disabled' to explicitly mark it as not needing injection.
- 查看为 productpage 创建的网关
[root@ksmaster21 3]# kubectl get gw -A
NAMESPACE NAME AGE
bookinfo bookinfo-gateway 18m
Kubernetes 本身也有一个 Gateway,因此不能使用 kubectl get gateway 来获取 Istio 的 Gateway,而是使用简写 gw。
- 查看 VistualService
# kubectl get vs -A
NAMESPACE NAME GATEWAYS HOSTS AGE
bookinfo bookinfo ["bookinfo-gateway"] ["*"] 6m54s
- 查看istio-ingressgateway
istio-ingressgateway默认以LoadBalancer方式暴露,我们没有配置,修改为nodeport暴露
- 访问测试
访问时一定需要带 /productpage ,因为我们并没有放通 /
修改 Gateway 端口
如果需要更换端口,可以修改 istio-ingressgateway 的 Service,增加新的端口映射。
kubectl edit svc istio-ingressgateway -n istio-system
#添加下述内容
- name: http666
protocol: TCP
port: 666
targetPort: 8080
nodePort: 32666
或可视化编辑
修改后
然后修改前面的 ingress_gateway.yaml,将端口从 80 改成 666 。
即可通过 32666 端口访问到此微服务。