随着单片应用程序向分布式微服务架构过渡 ,特别是服务之间呈现拓扑状的复杂关系,service mesh的提出就是为了简化管理微服务之间的通讯问题。为了实现微服务 Service Mesh 模式和诸多理念,Google , IBM 和 Lyft 这三家公司协同研发,并于 2017 年 6 月 8 日( 根据 Github 最后一次提交的时间 )发布了 Istio 的第一个发行版——Istio 0.1 版本。git
istio分为控制面和数据面,架构以下图所示。github
 -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 503 sleep.foo to httpbin.bar: 503 sleep.bar to httpbin.foo: 503 sleep.bar to httpbin.bar: 503
建立 destination rules使能TLS,目标是全部的集群内部的服务,而后服务之间就能够正常的访问了,使能TLS的操做以下:
kubectl apply -f - <<EOF apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "default" namespace: "istio-system" spec: host: "*.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
根据destination rules,访问全部集群内部服务都会带上TLS证书进行访问,使能TLS的访问结果:
for from in "foo" "bar"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 200 sleep.foo to httpbin.bar: 200 sleep.bar to httpbin.foo: 200 sleep.bar to httpbin.bar: 200
除了全局指定tls,也能够单独指定namespace使能TLS,操做以下:
kubectl apply -f - <<EOF apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "default" namespace: "foo" spec: peers: - mtls: {} EOF kubectl apply -f - <<EOF apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "default" namespace: "foo" spec: host: "*.foo.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
指定特定service tls,操做以下:
cat <<EOF | kubectl apply -n bar -f - apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "httpbin" spec: targets: - name: httpbin peers: - mtls: {} EOF cat <<EOF | kubectl apply -n bar -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "httpbin" spec: host: "httpbin.bar.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
三、策略
这里仍是以官方的bookinfo为例,指定应用拒绝访问。
首先修改istio configmap修改disablePolicyChecks为false,使能policy;而后制定策略拒绝v3版本的访问版本,匹配源为reviews v3和目的ratings制定rule对应handler为拒绝访问,yaml以下:
apiVersion: "config.istio.io/v1alpha2" kind: handler metadata: name: denyreviewsv3handler spec: compiledAdapter: denier params: status: code: 7 message: Not allowed --- apiVersion: "config.istio.io/v1alpha2" kind: instance metadata: name: denyreviewsv3request spec: compiledTemplate: checknothing --- apiVersion: "config.istio.io/v1alpha2" kind: rule metadata: name: denyreviewsv3 spec: match: destination.labels["app"] == "ratings" && source.labels["app"]=="reviews" && source.labels["version"] == "v3" actions: - handler: denyreviewsv3handler instances: [ denyreviewsv3request ]
四、可观察性
Istio为网格内的全部服务通讯生成详细的telemetry信息。此telemetry提供服务行为的可观察性,使运维人员可以对应用程序进行故障排除、维护和优化, 具体经过三个方面表现,第一个是metrics即指标,Istio根据监控的四个维度(延迟、流量、错误和饱和度)生成一组服务指标,暴露给proetheus。第二个是访问日志,当流量流入网格内的服务时,Istio能够生成每一个请求的完整记录,包括源和目标元数据。此信息使操做员可以审核服务行为,直至各个工做负载实例级别。 第三个是分布式跟踪, Istio提供了一种经过监视流经网格的各个请求来监视和了解行为的方法,了解服务网状网内的服务依赖关系和延迟来源。
以bookinfo为例,配置istio自动收集服务指标,每次调用网格内的服务,都会有相应的指标生成。
配置收集metrics的yaml文件以下:
# Configuration for metric instances apiVersion: config.istio.io/v1alpha2 kind: instance metadata: name: doublerequestcount namespace: istio-system spec: compiledTemplate: metric params: value: "2" # count each request twice 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"' --- # Configuration for a Prometheus handler apiVersion: config.istio.io/v1alpha2 kind: handler metadata: name: doublehandler namespace: istio-system spec: compiledAdapter: prometheus params: metrics: - name: double_request_count # Prometheus metric name instance_name: doublerequestcount.instance.istio-system # Mixer instance name (fully-qualified) kind: COUNTER label_names: - reporter - source - destination - message --- # Rule to send metric instances to a Prometheus handler apiVersion: config.istio.io/v1alpha2 kind: rule metadata: name: doubleprom namespace: istio-system spec: actions: - handler: doublehandler instances: [ doublerequestcount ]
在prometheus graph界面搜索istio_double_request_count,结果以下:
日志功能,使用资源instance,handler,rule建立,具体内容以下:
# Configuration for logentry instances apiVersion: config.istio.io/v1alpha2 kind: instance metadata: name: newlog namespace: istio-system spec: compiledTemplate: logentry params: severity: '"warning"' timestamp: request.time variables: source: source.labels["app"] | source.workload.name | "unknown" user: source.user | "unknown" destination: destination.labels["app"] | destination.workload.name | "unknown" responseCode: response.code | 0 responseSize: response.size | 0 latency: response.duration | "0ms" monitored_resource_type: '"UNSPECIFIED"' --- # Configuration for a stdio handler apiVersion: config.istio.io/v1alpha2 kind: handler metadata: name: newloghandler namespace: istio-system spec: compiledAdapter: stdio params: severity_levels: warning: 1 # Params.Level.WARNING outputAsJson: true --- # Rule to send logentry instances to a stdio handler apiVersion: config.istio.io/v1alpha2 kind: rule metadata: name: newlogstdio namespace: istio-system spec: match: "true" # match for all requests actions: - handler: newloghandler instances: - newlog
访问productpage,能够看到有对应的日志生成,操做以下:
kubectl logs -n istio-system -l istio-mixer-type=telemetry -c mixer | grep "newlog" | grep -v '"destination":"telemetry"' | grep -v '"destination":"pilot"' | grep -v '"destination":"policy"' | grep -v '"destination":"unknown"' {"level":"warn","time":"2019-12-16T16:45:53.950607Z","instance":"newlog.instance.istio-system","destination":"ratings","latency":"1.494269ms","responseCode":200,"responseSize":48,"source":"reviews","user":"unknown"}
分布式跟踪,使用jaeger进行trace, 默认采样率为1%。至少须要发送100个请求,才能看到一个跟踪,访问productpage操做:
for i in `seq 1 100`; do curl -s -o /dev/null http://$GATEWAY_URL/productpage; done
能够在jaeger dashboard看到对应跟踪信息,以下图: