Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

Google,IBM 和 Lyft 自豪地宣佈 Istio 的第一個公開發布:一個開源項目,提供統一的鏈接,安全,管理和監控微服務的方。 咱們目前的版本針對  Kubernetes 環境; 咱們打算在將來幾個月內爲虛擬機和 Cloud Foundry 等其餘環境增長支持。 Istio 將流量管理添加到微服務中,併爲增值功能(如安全性,監控,路由,鏈接管理和策略)創造了基礎。 該軟件使用來自 Lyft 的通過測試的特使代理構建,並提供對流量的可見性和控制,而不須要對應用程序代碼進行任何更改。 Istio 爲 CIO 提供了強大的工具,能夠在整個企業中實施安全性,政策和合規性要求。html

Istio 和 Service Mesh

Istio 是 Google、IBM 和 Lyft 聯合開源的微服務 框架,旨在解決大量微服務的發現、鏈接、管理、監控以及安全等問題。Istio 對應用是透明的,不須要改動任何服務代碼就能夠實現透明的服務治理。node

Istio 的主要特性包括:nginx

  • HTTP、gRPC 和 TCP 網絡流量的自動負載均衡git

  • 豐富的路由規則,細粒度的網絡流量行爲控制github

  • 流量加密、服務間認證,以及強身份聲明json

  • 全範圍( Fleet-wide )策略執行後端

  • 深度遙測和報告

Service Mesh

Service Mesh(服務網格)是一個用於保證服務間安全、快速、可靠通訊的網絡代理組件,是隨着微服務和雲原生應用興起而誕生的基礎設施層。它一般以輕量級網絡代理的方式同應用部署在一塊兒(好比 sidecar 方式,以下圖所示)。Serivce Mesh 能夠看做是一個位於 TCP/IP 之上的網絡模型,抽象了服務間可靠通訊的機制。但與 TCP 不一樣,它是面向應用的,爲應用提供了統一的可視化和控制。api

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

爲了保證服務間通訊的可靠性,Service Mesh 須要支持熔斷機制、延遲感知的負載均衡、服務發現、重試等一些列的特性。安全

好比 Linkerd 處理一個請求的流程包括 markdown

  • 查找動態路由肯定請求的服務

  • 查找該服務的實例

  • Linkerd 跟響應延遲等因素選擇最優的實例

  • 將請求轉發給最優實例,記錄延遲和響應狀況

  • 若是請求失敗或實例實效,則轉發給其餘實例重試(須要是冪等請求)

  • 若是請求超時,則直接失敗,避免給後端增長更多的負載

  • 記錄請求的度量和分佈式跟蹤狀況

    爲何 Service Mesh 是必要的

  • 將服務治理與實際服務解耦,避免微服務化過程當中對應用的侵入

  • 加速傳統應用轉型微服務或雲原生應用

Service Mesh 並不是一個全新的功能,而是將已存在於衆多應用之中的相關功能分離出來,放到統一的組件來管理。特別是在微服務應用中,服務數量龐大,而且多是基於不一樣的框架和語言構建,分離出來的 Service Mesh 組件更容易管理和協調它們。

Istio 原 理

Istio 從邏輯上能夠分爲數據平面和控制平面:

  • 數據平面主要由一系列的智能代理(Envoy)組成,管理微服務之間的網絡通訊

  • 控制平面負責管理和配置這些智能代理,並動態執行策略

    Istio 架構能夠以下圖所示

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

主要由如下組件構成

  • Envoy :Lyft 開源的高性能代理總線,支持動態服務發現、負載均衡、TLS 終止、HTTP/2 和 gPRC 代理、健康檢查、性能測量等功能。Envoy 以 sidecar 的方式部署在相關的服務的 Pod 中。

  • Mixer:負責訪問控制、執行策略並從 Envoy 代理中收集遙測數據。Mixer 支持靈活的插件模型,方便擴展(支持 GCP、AWS、Prometheus、Heapster 等多種後端)

  • Istio-Auth:提供服務間和終端用戶的認證機制

  • Pilot:動態管理 Envoy 示例的生命週期,提供服務發現、流量管理、智能路由以及超時、熔斷等彈性控制的功能。其與 Envoy 的關係以下圖所示

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

在數據平面上,除了 Envoy,還能夠選擇使用 nginxmesh 和 linkerd 做爲網絡代理。好比,使用 nginxmesh 時,Istio的控制平面(Pilot、Mixer、Auth)保持不變,但用 Nginx Sidecar 取代 Envoy:
Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

安 裝

Istio 目前僅支持 Kubernetes,在部署 Istio 以前須要先部署好 Kubernetes 集羣並配置好 kubectl 客戶端。

下 載 Istio

curl -L https://git.io/getLatestIstio | sh -
cd istio-0.2.12/
cp bin/istioctl /usr/local/bin

部 署 Istio 服 務

兩種方式(選擇其一執行)

  • 禁止 Auth:kubectl apply -f install/kubernetes/istio.yaml

  • 啓用 Auth:kubectl apply -f install/kubernetes/istio-auth.yaml

部署完成後,能夠檢查 isotio-system namespace 中的服務是否正常運行:

$ kubectl -n istio-system get pod
NAME                             READY     STATUS    RESTARTS   AGE
istio-ca-5cd46b967c-q5th6        1/1       Running   0          3m
istio-egress-56c4d999bc-82js4    1/1       Running   0          3m
istio-ingress-5747bb855f-tv98x   1/1       Running   0          3m
istio-mixer-77487797f6-cwtqt     2/2       Running   0          3m
istio-pilot-86ddcb7ff5-t2zpk     1/1       Running   0          3m

部 署 Prometheus、Grafana 和 Zipkin 插 件

kubectl apply -f install/kubernetes/addons/grafana.yaml
kubectl apply -f install/kubernetes/addons/servicegraph.yaml
kubectl apply -f install/kubernetes/addons/zipkin.yaml
kubectl apply -f install/kubernetes/addons/prometheus.yaml
# kubectl apply -f install/kubernetes/addons/zipkin-to-stackdriver.yaml

等一會全部 Pod 啓動後,能夠經過 NodePort 或負載均衡服務的外網 IP 來訪問這些服務。好比經過 NodePort 方式,先查詢服務的 NodePort

$ kubectl -n istio-system get svc grafana -o jsonpath='{.spec.ports[0].nodePort}'
32070
$ kubectl -n istio-system get svc servicegraph -o jsonpath='{.spec.ports[0].nodePort}'
31072
$ kubectl -n istio-system get svc zipkin -o jsonpath='{.spec.ports[0].nodePort}'
30032
$ kubectl -n istio-system get svc prometheus -o jsonpath='{.spec.ports[0].nodePort}'
30890

經過 http://<kubernetes-ip>:32070/dashboard/db/istio-dashboard 訪問  Grafana 服務

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

經過 http://<kubernetes-ip>:31072/dotviz 訪問 ServiceGraph 服務,展現服務之間調用關係圖

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

經過 http://<kubernetes-ip>:30032 訪問 Zipkin 跟蹤頁面

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

經過 http://<kubernetes-ip>:30890 訪問 Prometheus 頁面

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

部署 示 例 應 用

在部署應用時,須要經過 istioctl kube-inject 給 Pod 自動插入 Envoy 容器,即

wget https://raw.githubusercontent.com/istio/istio/master/blog/bookinfo-v1.yaml
# inject with istioctl
kubectl apply -f <(istioctl kube-inject -f bookinfo-v1.yaml)

# create ingress
cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: bookinfo
 annotations:
   kubernetes.io/ingress.class: "istio"
spec:
 rules:
 - http:
     paths:
     - path: /productpage
       backend:
         serviceName: productpage
         servicePort: 9080
     - path: /login
       backend:
         serviceName: productpage
         servicePort: 9080
     - path: /logout
       backend:
         serviceName: productpage
         servicePort: 9080
EOF

原始應用以下圖所示

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

istioctl kube-inject 在原始應用的每一個 Pod 中插入了一個 Envoy 容器

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

服務啓動後,能夠經過 Ingress 地址

http://<ingress-address>/productpage

來訪問 BookInfo 應用

$ kubectl describe ingress
Name:            gateway
Namespace:        default
Address:        192.168.0.77
Default backend:    default-http-backend:80 (10.8.0.4:8080)
Rules:
  Host    Path    Backends
  ----    ----    --------
  *
        /productpage     productpage:9080 (<none>)
        /login         productpage:9080 (<none>)
        /logout     productpage:9080 (<none>)
Annotations:
Events:    <none>

Google、IBM 和 Lyft 聯合開源的微服務 Service Mesh 框架 Istio

##金 絲 雀 部 署

首先部署 v2 版本的應用,並配置默認路由到 v1 版本:

wget https://raw.githubusercontent.com/istio/istio/master/blog/bookinfo-ratings.yaml
kubectl apply -f <(istioctl kube-inject -f bookinfo-ratings.yaml)

wget https://raw.githubusercontent.com/istio/istio/master/blog/bookinfo-reviews-v2.yaml
kubectl apply -f <(istioctl kube-inject -f bookinfo-reviews-v2.yaml)

# create default route
cat <<EOF | istioctl create -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  route:
  - labels:
      version: v1
    weight: 100
EOF

示例一:將 10% 請求發送到 v2 版本而其他 90% 發送到 v1 版本

cat <<EOF | istioctl create -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  route:
  - labels:
      version: v2
    weight: 10
  - labels:
      version: v1
    weight: 90
EOF

示例二:將特定用戶的請求所有發到 v2 版本

cat <<EOF | istioctl create -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
 name: reviews-test-v2
spec:
 destination:
   name: reviews
 precedence: 2
 match:
   request:
     headers:
       cookie:
         regex: "^(.*?;)?(user=jason)(;.*)?$"
 route:
 - labels:
     version: v2
   weight: 100
EOF

示例三:所有切換到 v2 版本

cat <<EOF | istioctl replace -f -
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  name: reviews-default
spec:
  destination:
    name: reviews
  route:
  - labels:
      version: v2
    weight: 100
EOF

示例四:限制併發訪問

# configure a memquota handler with rate limits
cat <<EOF | istioctl create -f -
apiVersion: "config.istio.io/v1alpha2"
kind: memquota
metadata:
 name: handler
 namespace: default
spec:
 quotas:
 - name: requestcount.quota.default
   maxAmount: 5000
   validDuration: 1s
   overrides:
   - dimensions:
       destination: ratings
     maxAmount: 1
     validDuration: 1s
EOF

# create quota instance that maps incoming attributes to quota dimensions, and createrule that uses it with the memquota handler
cat <<EOF | istioctl create -f -
apiVersion: "config.istio.io/v1alpha2"
kind: quota
metadata:
 name: requestcount
 namespace: default
spec:
 dimensions:
   source: source.labels["app"] | source.service | "unknown"
   sourceVersion: source.labels["version"] | "unknown"
   destination: destination.labels["app"] | destination.service | "unknown"
   destinationVersion: destination.labels["version"] | "unknown"
---
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
 name: quota
 namespace: default
spec:
 actions:
 - handler: handler.memquota
   instances:
   - requestcount.quota
EOF

爲了查看訪問次數限制的效果,能夠使用 wrk 給應用加一些壓力:

export BOOKINFO_URL=$(kubectl get po -n istio-system -l istio=ingress -o jsonpath={.items[0].status.hostIP}):$(kubectl get svc -n istio-system istio-ingress -o jsonpath={.spec.ports[0].nodePort})
wrk -t1 -c1 -d20s http://$BOOKINFO_URL/productpage

參考文檔:

明晚九點|基於 Ansible API 的任務管理平臺

主講師:panda

前 douban 運維工程師,目前就任於創業公司。引入 douban 的運維平臺思想,完成公司的自動化運維平臺開發和建設。對運維工程師轉運維研發的困惑和痛點深有感觸,樂於分享本身轉型中的五味雜陳。

主要內容:

1:中小公司對於 puppet/salt/ansible 選擇之我見

2:Ansible 在生產環境中的經常使用場景

3:Playbook API實現任務管理平臺思路、難點及實現

分享模式:網絡直播

分享時間:12月14日(週四)

相關文章
相關標籤/搜索