istio入門

1、背景

​隨着單片應用程序向分佈式微服務架構過渡 ,特別是服務之間呈現拓撲狀的複雜關係,service mesh的提出就是爲了簡化管理微服務之間的通訊問題。爲了實現微服務 Service Mesh 模式和諸多理念,Google , IBM 和 Lyft 這三家公司協同研發,並於 2017 年 6 月 8 日( 根據 Github 最後一次提交的時間 )發佈了 Istio 的第一個發行版——Istio 0.1 版本。git

2、istio架構

​istio分爲控制面和數據面,架構以下圖所示。github

​![](/tmp/5de067fab481934666d3bb44090fadad/istioistio架構json

  • 數據面:由一組sidecar組成,對應具體的組件爲envoy;經過給每一個應用啓動一個輕量級的網絡代理,來執行對網絡通訊的控制和調整,Sidecar和外圍代理,實現客戶端和服務器之間的安全通訊;
  • 控制面:負責管理和配置代理流量。具體經過mixer組件下發策略給envoy,執行策略並對各個sidecar收集數據。 Citadel用於密鑰和證書管理;pilot將身份驗證策略和安全命名信息分發到代理;mixer用於管理受權和審覈。

3、核心功能

流量管理:api

下圖顯示了pilot的服務發現過程。

​ istio根據Kubernetes的適配器發現並註冊service後,流量規則會由pilot解析成envoy理解的格式傳送給Sidecar,進而控制服務間的流量和 API 調用。Istio 簡化了斷路器、超時和重試等服務級別屬性的配置,而且能夠輕鬆設置 A/B 測試、金絲雀部署和基於百分比的流量分割的分階段部署等重要任務。安全

安全:服務器

​Istio提供底層安全通訊通道,使開發人員能夠專一於應用程序級別的安全,並提供大規模管理服務通訊的身份驗證、受權和加密。使用Istio,服務通訊在默認狀況下是安全的,能夠跨不一樣的協議和運行時一致地實施策略,全部這些都只需不多或根本不須要更改應用程序。網絡

​安全涉及的幾個組件及架構以下圖所示:

​Citadel:用於密鑰和證書管理。架構

​Sidecar和外圍代理:實現客戶端和服務器之間的安全通訊。app

​pilot:將身份驗證策略和安全命名信息分發到代理。運維

​mixer:用於管理受權和審覈。

策略定製: 爲應用程序配置自定義策略,以在運行時強制執行規則,如動態限制服務的通訊量,經過名單限制對服務的訪問,也能夠建立本身的策略適配器,添加自定義受權行爲。

可觀察性: Istio強大的跟蹤、監控和日誌記錄功能可以讓人深刻了解服務網格的部署。經過Istio的監控功能,能夠真正瞭解服務性能對上下游的影響,同時其定製的儀表盤可查看全部服務的性能,並瞭解該性能對其餘流程有何影響。

4、基本功能驗證

本環境基於Kubernets1.14和istio1.13版本進行驗證。其中下面的例子都在官方連接的samples目錄中,官方連接[1]istio官方例子

一、流量管理:

​爲了填充本身的服務註冊表,Istio鏈接到服務發現系統,而在Kubernetes集羣上安裝了Istio,Istio會自動檢測該集羣中的服務和端點,使用此服務註冊表,代理就能夠將流量定向到相關服務。默認狀況下同一工做負載多個實例,流量會平均分發,而做爲A/B測試的一部分,也能夠將特定百分比的流量定向到服務的新版本,或者對特定服務實例子集的流量應用不一樣的負載平衡策略。還能夠對進出Mesh的流量應用特殊規則,或者將Mesh的外部依賴項添加到服務註冊表。

以官方的bookinfo爲例,使用對同一程序多版本的流量管理,具體配置以下:

自注入使能

kubectl label namespace default istio-injection=enabled

部署bookinfo到default namespaces,bookinfo服務之間默認的調用關係以下圖:

可建立virtualService所有流量導向reviews-v1,yaml文件中host指向的是reviews service,只指定了v1版本,所以流量全導向reviews v1。

virtualService yaml以下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1

結果以下圖,能夠看到圖中綠色部分就是當前流量的走向,所有走向previews v1:

二、安全,主要提供服務網格之間安全訪問,這裏以enable TLS爲例。

建立meshPolicy全局enable tls

kubectl apply -f - <<EOF
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
  name: "default"
spec:
  peers:
  - mtls: {}
EOF

由於使能了TLS,因此不帶證書訪問會報錯,直接http訪問結果以下:

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: 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看到對應跟蹤信息,以下圖:

相關文章
相關標籤/搜索