Kubernetes 是容器的编排工具,可以非常方便的进行大规模的容器调度。通过这种模式,将传统的软件模式改造成微服务模式。这种微服务的架构模式,将复杂系统切分为数十乃至上百个小服务,每个服务负责实现一个独立的业务逻辑。这些小服务易于被小型的软件工程师团队负责,这带来了语言和框架选择灵活性,并可以缩短应用开发上线时间,可根据不同的工作负载和资源要求对服务进行独立缩扩容等优势。但另一方面,当应用被拆分为多个微服务进程后,进程内的方法调用变成了了进程间的远程调用。这就引入了对大量服务的连接、管理和监控的复杂性。
在微服务模式中,如何实现各个进程间的通信,是微服务中一个重要的部分。
Istio 是 CNCF 提出的由 Google、IBM、Lyft 等共同开源的 Service Mesh 框架。是连接 Kubernetes 和 Serverless 架构的重要基础设施层。
一 Istio 简介
1 Istio
Isito 主要实现以下三个功能:
1.监控
2.安全
3.流量管理
其架构图如下:
其中,Citadel 是服务间认证加密的组件,Pilot 是服务间通信策略的控制层面,Galley 负责检查用户的策略配置。
其中 Pilot 是数据层面的控制组件,Proxy 是数据层面的执行组件。
2 流量管理
根据前面的描述,我们知道,在 Istio 中,流量管理通过 Pilot 和 Envoy 实现。Pilot 对 Envoy 通过下面几个组件进行流量策略的控制:
1.Gateway - 是 Istio 的 IngressGateway,流量通过这个 Gateway 进入 VirtualService。
2.VirtualService - 通过
a.HTTP header
b.URIs
c.Ports
d.sourceLables
对流量进行分类,分发到不同的 Service 上。
3.DestinationRule -定义了流量如何分发到 Pod 上,比如负载均衡策略、Session Affinity 等。同时还可以通过 Label 对同一组服务进行更细致的分组,比如 ServiceA-v1、ServiceA-v2。用于流量的 splitting。
本文将介绍在 GKE 上如何实现通过 Isito 实现 service 间流量的控制。
二 环境准备
1 GKE
在 Google Cloud 上创建 GKE Cluster,enable Istio,具体命令行如下:
gcloud beta container clusters create "istiodemo" --zone "us-central1-c" --num-nodes "4" --enable-stackdriver-kubernetes --enable-ip-alias --addons HttpLoadBalancing,Istio
复制代码
通过 Console 界面查看创建的 GKE Cluster:
查看 Istio 相关的 workload:
2 本地安装 Istioctl 工具
本文采用 Istio1.4.3:
export ISTIO_VERSION=1.4.3curl -L https://git.io/getLatestIstio | ISTIO_VERSION=$ISTIO_VERSION sh -
复制代码
检查 Istio 版本
./istioctl version --short
client version: 1.4.3control plane version: 04871014b586f671f2ce14646e5061945f75c9c5data plane version: (1 proxies)
复制代码
查看 istio 状态:
这里采用 Istio 的 Demo profile,可以用下面的命令:
istioctl manifest apply --set profile=demo
复制代码
可以看到各种监控的工具都安装完成:
3 安装 bookinfo
Bookinfo 跟随 Istio 的安装包一起下载到本地目录。Bookinfo 的软件架构如下:
安装过程如下:
kubectl label namespace default istio-injection=enabledkubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
复制代码
查看 pod、service 信息:
红框表示出来的,都是 bookinfo 相关的 deployment。
红框表示出来的,都是 bookinfo 相关的 service。
查看应用的状态:
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>"
复制代码
Simple Bookstore App
三 通过 Istio 进行流量管理
1 配置 Gateway 和 VirtualService 使外部可以访问
配置 Istio Ingress Gateway,使外部可以访问 bookinfo:
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
复制代码
配置文件如下:
apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: bookinfo-gatewayspec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: bookinfospec: 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
复制代码
查看 GW 的公网地址:
kubectl get svc -n istio-systemNAME TYPE CLUSTER-IP EXTERNAL-IP istio-citadel ClusterIP 10.0.12.62 <none> istio-galley ClusterIP 10.0.5.255 <none> istio-ingressgateway LoadBalancer 10.0.13.240 35.202.166.31 istio-pilot ClusterIP 10.0.6.138 <none> istio-policy ClusterIP 10.0.2.42 <none> istio-sidecar-injector ClusterIP 10.0.0.149 <none> istio-telemetry ClusterIP 10.0.15.195 <none> promsd ClusterIP 10.0.5.191 <none>
复制代码
可以看到 istio-ingressgateway 的公网地址是 35.202.166.31。通过这个 IP 地址访问 bookinfo:
curl -s http://$Gateway_URL/productpage | grep -o "<title>.*</title>"
复制代码
Simple Bookstore App
通过 Kiali 界面 istioctl dashboard kiali: admin/admin 可以看到 Micro Service 间拓扑关系:
2 部署 DestinationRule
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
复制代码
配置文件内容:
apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: productpagespec: host: productpage subsets: - name: v1 labels: version: v1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: reviewsspec: host: reviews subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: ratingsspec: 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/v1alpha3kind: DestinationRulemetadata: name: detailsspec: host: details subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2---
复制代码
这个 Destination Rule 中包含每个子应用的不同版本。此时在刷新网页时,可以看到 3 个版本的 Review。
通过脚本持续的访问页面:
for i in {1..100}; do curl -o /dev/null -s -w %{http_code} \ http://35.188.64.161/productpage; sleep 1; done
复制代码
此时流量是基本均担的:
3 配置 VirtualService 流量导向 v1
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
复制代码
配置文件内容:
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: productpagespec: hosts: - productpage http: - route: - destination: host: productpage subset: v1---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - route: - destination: host: reviews subset: v1---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: ratingsspec: hosts: - ratings http: - route: - destination: host: ratings subset: v1---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: detailsspec: hosts: - details http: - route: - destination: host: details subset: v1---
复制代码
可以看到,所有的流量都导向 v1 的 subset。包括 productpage、reviews、ratings、details。此时再刷新页面,都只有相同的内容。
4 配置 VirtualService 通过识别 http header 内容进行控制流量
VirtualService 可以通过 http header 中的内容对流量进行控制。这里采用用户名来进行控制:
kubectl apply \ -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
复制代码
配置文件内容:
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v1
复制代码
可以看到,如果用户是 jason,流量将导向 v2,否则导向 v1.
使用 jason 登录,可以看到 review 的页面是下面黑色的星星。是 v2 的 subset。
退出登录,或用随意的名字登录,都是没有星星的 v1 版本:
5 配置 VirtualService 流量导向 v1 和 v3 各一半
清除上面实验的配置:
kubectl delete \ -f samples/bookinfo/networking/virtual-service-all-v1.yaml
复制代码
此时流量会在 3 个版本间轮训。
下面的配置会只导向 v1:
kubectl apply \ -f samples/bookinfo/networking/virtual-service-all-v1.yaml
复制代码
采用下面的配置,把流量在 v1 和 v3 间各 50%分流:
kubectl apply \ -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
复制代码
配置的具体内容:
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50
复制代码
此时可以看到流量在 v1 和 v3 间轮询:
6 配置 VirtualService 流量导向 v3
应用如下配置:
kubectl apply \ -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
复制代码
配置的具体内容如下:
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - route: - destination: host: reviews subset: v3
复制代码
这样流量都导向 v3:
7 配置 VirtualService 流量导向 v1 和 v2,比例 9:1
应用如下配置:
kubectl apply \ -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
复制代码
配置的具体内容如下:
apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 90 - destination: host: reviews subset: v2 weight: 10
复制代码
此时 90%流量导向 v1,10%的流量导向 v2。可以通过多刷页面看到 v2 的黑色星星页面。
四 总结
通过在 GKE 上的 Istio 的 Gateway/VirtualService/DestinationRule 可以非常方便的控制各个微服务间的流量调度。
评论