前言
Istio已经18年中推出1.0 正式版本,并表示已可用于生产环境。
目前我们对网络计费计量有需求,而服务网格能实现网络指标收集、限流、访问控制和端到端认证、故障恢复和监控以及通常更加复杂的运维需求。
对于开发来说,只需要进行http服务(支持tcp/udp)调用(与使用原来的服务发现模式一样),中间的连接、控制、限流、认证全部交由Istio完成。
服务的实现
简单来说,Istio会在我们部署的每一个服务(Service),以sidecar的方式都被注入1个Proxy, 所有流量经过这个高性能的proxy继续转发,以Control Plane (控制面)进行规则的定义、控制、遥测。
基本功能展示
流量控制(灰度发布)
路由转发
指标监控、负载均衡、故障注入、处理等等
Kubernetes Istio的部署
对于官方文档提供的多种部署方式,由于我们的集群已经部署了helm和titler服务端,所以部署相当的简单
下载
istio 1.2.2 已经验证对kubernetes1.12, 1.13, 1.14支持
wget https://github.com/istio/istio/releases/download/1.2.2/istio-1.2.2-linux.tar.gz
部署
解压使用helm安装
tar -xvf istio-1.2.2-linux.tar.gz
cd istio-1.2.2/
kubectl create namespace istio-system
helm install install/kubernetes/helm/istio-init --name istio-init --namespace istio-system
等待crd(自定义控制器)的配置完成
helm status istio-init
当所有pod 和job都complete之后,部署istio
helm install install/kubernetes/helm/istio --name istio --namespace istio-system
部署服务时引入Istio
以后部署服务的时候,我们只要在命名空间设置label , istio-injection=enabled:
kubectl label namespaces <namespace> istio-injection=enabled
或者手动注入
kubectl apply -f <(istioctl kube-inject -f xxx.yaml)
即可完成Istio 的引入,推荐第一种方式,第二种方式需要下载istio的ctl工具支持;
Demo应用
先得说Istio的4个控制概念
- 1. VirtualService,用于配置实现请求路由的功能 (路由)
- 2. DestinationRule ,实现服务发现和负载均衡、故障处理和故障注入的功能 (策略)
- 3. ServiceEntry ,让服务网格内的服务,可以看到外面的世界 (出口控制)
- 4. Gateway ,让服务网格的服务,可以被全世界看到 (入口控制)
因为官方demo提供了3个明显标识的应用(页面),可以让我们快速看到流量的变化,先使用官方的应用进行测试;
后续使用我们自己的应用进行部署;
bookinfo DEMO应用
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n istioinj
根据上述概念,我们部署一个gateway 对这个bookinfo集群进行访问
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
查询istio的gateway代理的地址是80 -> 31380, 443 -> 31390
# kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.43.4.72 <pending> 15020:31818/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31912/TCP,15030:30074/TCP,15031:30408/TCP,15032:30763/TCP,15443:31776/TCP
浏览器进行访问 http://192.168.108.3:31380/productpage
该集群有3个后端页面,多次访问url会因为轮询的规则,页面发生变化。通过
星的颜色和数量进行区分 ↓
访问策略
设置默认的DestinationRule 策略
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml -n istioinj
destination-ruel.yaml
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
然后我们就能够用VirtualService 对流量进行转发
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v1.yaml -n istioinj
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml -n istioinj
策略v1
实现了所有流量只访问1页面v1:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
v1实现了所有流量只访问1页面:
策略v2
使用jason用户登录,流量全部走2页面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
使用jason用户登录,全部走2页面
流量控制
可以看到流量的路由配置比较简单,Istio会对符合规则的流量进行转发。
同时,在此基础上添加百分百,即可对流量进行控制:
策略v3
分流50%流量到 v3页面
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml -n istioinj
virtual-service-reviews-50-v3.yaml
# cat samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
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
可视化与遥测
需要启用KIALI工具,创建secret
KIALI_USERNAME=$(echo -n 'admin' | base64)
KIALI_PASSPHRASE=$(echo -n 'mysecret' | base64)
NAMESPACE=istio-system
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: kiali
namespace: $NAMESPACE
labels:
app: kiali
type: Opaque
data:
username: $KIALI_USERNAME
passphrase: $KIALI_PASSPHRASE
EOF
启用,使用helm upgrade
helm upgrade \
--set grafana.enabled=true \
--set kiali.enabled=true \
--set tracing.enabled=true \
--set "kiali.dashboard.jaegerURL=http://$(kubectl get svc tracing --namespace istio-system -o jsonpath='{.spec.clusterIP}'):80" \
--set "kiali.dashboard.grafanaURL=http://$(kubectl get svc grafana --namespace istio-system -o jsonpath='{.spec.clusterIP}'):3000" \
istio install/kubernetes/helm/istio --namespace istio-system
在设置了kiali的nodeport访问后,
上述配置的帐号和密码(admin/mysecret)
实现我们的网络可视化:
Kiali
无virtualservices策略:
virtual-service-reviews-50-v3策略:
同时我们启动了grafana、jaeger trace插件
Jaeger
对于上面的请求流程,jaeger细化到每个请求全程跟踪,包括请求、param、延时等等,极其方便研发对性能及请求status的分析
Grafana
在grafana http://192.168.108.3:30578/ 中,
我们可以很熟悉的查看我们每一个页面:
workload:
或者是整个集群的一个监控状态,Istio Performance:
指标度量
指标采集逻辑:
- 1. 从 Istio 属性中生成 这里是指标值以及日志
- 2.创建 handler(配置 Mixer 适配器),用来处理生成的日志
3. 根据一系列的 rule,把 日志(instance)传递给 handler
# 指标 instance 的配置
apiVersion: "config.istio.io/v1alpha2"
kind: metric
metadata:
name: doublerequestcount
namespace: istio-system
spec:
value: "2" # 每个请求计数两次
dimensions:
reporter: conditional((context.reporter.kind | "inbound") == "outbound", "client", "server")
source: source.workload.name | "unknown"
destination: destination.workload.name | "unknown"
message: '"twice the fun!"'
monitored_resource_type: '"UNSPECIFIED"'
---
# prometheus handler 的配置
apiVersion: "config.istio.io/v1alpha2"
kind: prometheus
metadata:
name: doublehandler
namespace: istio-system
spec:
metrics:
- name: double_request_count # Prometheus 指标名称
instance_name: doublerequestcount.metric.istio-system # Mixer Instance 名称(全限定名称)
kind: COUNTER
label_names:
- reporter
- source
- destination
- message
---
# 将指标 Instance 发送给 prometheus handler 的 rule 对象
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
name: doubleprom
namespace: istio-system
spec:
actions:
- handler: doublehandler.prometheus
instances:
- doublerequestcount.metric
注意:若暂无法进行指标收集,由于目前 Istio 1.2.2版本官方文档与英文文档是冲突的,
该配置也是缺失CRDS的:
查找各类文档目前无法解决该crd缺失问题,建议Istio使用旧版 1.1.15。1.2.2指标度量收集目前无法进行;