参考Istio 入门(三):体验 Istio、微服务部署、可观测性 - 痴者工良 - 博客园 (cnblogs.com)
在本章中,我们将会学习到如何部署一套微服务、如何使用 Istio 暴露服务到集群外,并且如何使用可观测性组件监测流量和系统指标。
本章教程示例使用的是 Istio 官方的一套微服务,这套微服务是一个在线书店,打开页面之后会看到一个分类、书的信息以及书的评论,页面的内容由不同的子服务提供。
书店微服务分为四个单独的微服务,在上图中已经使用红色方框画出来了。这四个微服务分别是:
productpage
: 汇集所有服务的数据,生成浏览页面。details
:存储了书籍的信息,如描述、作者、出版社等。reviews
:存储了书籍相关的评论,但是不包含评分打星。ratings
:存储评论中的评分打星。Productpage 服务对外提供 Web 访问页面,而且其它的三个服务只能在集群内部访问。四个服务分别采用了不同的语言开发,Productpage 聚合其它三个服务的信息生成一个页面。
给这些示例服务创建一个命名空间。
kubectl create namespace bookinfo
给命名空间添加 Istio 的标签,指示 Istio 在部署应用(只对 Pod 起效)的时候,自动注入 Envoy Sidecar Proxy 容器:
kubectl label namespace bookinfo istio-injection=enabled
进入 Istio 安装目录。
使用 kubectl
部署应用到bookinfo :
kubectl -n bookinfo apply -f samples/bookinfo/platform/kube/bookinfo.yaml
上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。
检查
执行命令完成后,查看 bookinfo 命名空间下的 Pod。
kubectl get pods -n bookinfo
可以看到,每个 Pod 的 READY 属性都是 2/2
,这表示该 Pod 中有两个容器,并且当前有两个容器已经就绪。
如果我们查看其中一个 Pod 的组成结构,会发现有 Pod 被塞进了一个 istio-proxy 容器。
kubectl -n bookinfo describe pod productpage-v1-564d4686f-cn5bb
接着使用 kubectl -n bookinfo get svc
查看 Service,四个微服务都已经被注册了 Service。
curl 10.105.180.245:9080
默认 Istio 不会开启零信任双向认证模式,因此在集群内可以自己访问应用。如果开启了 mTLS 双向认证模式,则只能在 Pod 中访问应用。
创建 productpage_tmpsvc.yaml 文件
touch productpage_tmpsvc.yaml
vim productpage_tmpsvc.yaml
apiVersion: v1
kind: Service
metadata:
name: productpagetmp
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
type: NodePort
kubectl -n bookinfo apply -f productpage_tmpsvc.yaml
kubectl -n bookinfo get svc
然后在页面中访问 31527 端口(大家的端口不一样,按自己的来)。
http://192.168.1.247:31527/productpage?u=normal 多次刷新
到体验 Istio 的时刻了,在本小节中,我们将会为 productpage 创建 Istio Gateway,对外提供网页访问。
我们已经部署了 istio-ingressgateway,这个组件起到了类似 nginx、apisix 的效果,对外提供端口访问,然后将流量转发到内部服务中。详见 istio学习笔记-安装-CSDN博客
但是 istio-ingressgateway 并不能直接转发流量到 Pod,它还需要进行一些配置。我们要为 productpage 创建一个站点,绑定对应的域名,这样外部访问 istio-ingressgateway 的端口时,istio-ingressgateway 才知道该将流量转发给谁。在 Istio 中,定义这种绑定关系的资源叫 Gateway。
Gateway 类似 Nginx 需要创建一个反向代理时需要绑定的域名配置。
kubectl -n bookinfo apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
cat samples/bookinfo/networking/bookinfo-gateway.yaml
hosts
表示对外开放的访问路径,你可以绑定域名、IP 等。这里使用 *
,表示所有访问都可以进入此网关。
当我们创建 Istio Gateway 之后,istio-ingressgateway 会为我们监控流量,检测不同的域名或端口属于哪个 Istio Gateway 。
虽然创建了 Istio Gateway,但是我们还不能直接通过网关访问到前面部署的微服务,我们还需要创建 Istio VirtualService 将 Istio Gateway 跟对应的 Kubernetes Service 绑定起来,然后流量才能正式流向 Pod。
请一定要注意这里,流量实际并不会经过 Service 中,但是 VirtualService 需要通过 Service 来发现 Pod。
这里类似 nginx 配置反向代理,配置监听之后,还需要指向将请求映射到哪个地址。
VirtualService 的主要目标是为服务提供稳定的入口地址,并通过配置一系列的路由规则来控制流量在网格内的行为。
就以最简单的路由区配来说,Kubernetes Service 是不支持路由规则的,而 Istio 可以通过指定路由后缀中;Service 不支持流量分析,负载均衡只有轮询。而 Istio 利用 Service 来发现 Pod,然后直接将流量转发到 Pod 中,可以实现各种功能。
VirtualService 可以用于实现以下功能:
请求路由:将请求路由到特定的服务或版本,例如将请求分发到不同版本的服务,以实现灰度发布或金丝雀发布。
请求重试:为失败的请求配置重试策略,以提高服务的可用性。
请求超时:设置请求的超时时间,以便在特定时间内没有得到响应时中断请求。
请求镜像:将请求的副本发送到另一个服务,用于测试新版本的服务,而不影响实际的生产流量。
流量分割:将流量按照特定的比例分发到不同的服务或版本,以实现流量控制。
执行
kubectl -n bookinfo apply -f samples/bookinfo/networking/bookinfo-gateway.yaml 时 已创建 VirtualService
这里的 YAML 分为两大部分,第一部分是 http.match
,表示暴露了哪些 API 地址,外部访问时只能访问到这些地址。
可以通过 http.match
限制集群外部访问此地址时所能使用的 URL。
然后通过 http.route
绑定 Kubernetes Service ,通过 Service 中的服务发现,将流量转发到对应的 Pod 中。
host 这里,由于 VirtualService 跟 Service/Pod 在同一个命名空间中,所以只需要配置 Service 的名称即可,如果要跨命名空间访问,则需要加上完整的命名空间名称。
DestinationRule是定义在路由发生后应用于服务的流量的策略。这些规则指定负载均衡的配置、sidecar的连接池大小以及离群值检测设置,以检测并从负载平衡池中清除不正常的主机。以上信息仅供参考,如有需要,建议您咨询专业技术人员。
Istio VistualService 中可以限制外部能够访问的路由地址,而 DestinationRule 则可以配置访问的 Pod 策略。可以为 Istio VistualService 绑定一个 Istio DestinationRule,通过 DestinationRule 我们还可以定义版本子集等,通过更加丰富的策略转发流量。
echo 'export ISTIO_HOME=/opt/istio-1.19.4' >> /etc/profile
echo 'export PATH=$PATH:$ISTIO_HOME/bin' >> /etc/profile
source /etc/profile
istioctl version
为了确保网关没问题,我们需要执行 Istio 命令查看日志:
istioctl analyze -n bookinfo
然后我们查看为 productpage 创建的网关。
kubectl get gw -A
然后查看 VistualService。
kubectl get vs -A
我们通过 Helm 部署了 istio-ingressgateway,其访问端口如下:
kubectl get svc -n istio-system
在本节部署 bookinfo-gateway 的时候,我们使用了端口 80,因此不需要另外配置 ,直接通过 istio-ingressgateway 的 32299 端口访问即可。
之前配置的是 8080 需要改为80
kubectl -n bookinfo delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
vim samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl -n bookinfo apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl get svc -n istio-system