1. 程式人生 > >Kubernetes上的服務網格 Istio

Kubernetes上的服務網格 Istio

image

微服務架構將複雜系統切分若干小服務,每個服務可以被獨立地開發、部署和伸縮;微服務架構和容器(Docker/Kubernetes)是天作之合,可以進一步簡化微服務交付,加強整體系統的彈性和健壯性。然而由大量的微服務構成的分散式應用架構也會增加運維、除錯、和安全管理的複雜性。為了解決上述挑戰,Spring Cloud和Dubbo/EDAS等微服務框架將服務治理能力內建在程式設計框架中。

2017年5月,Google、IBM和Lyft釋出了開源服務網格框架Istio,提供微服務的連線、管理、監控和安全保護。Istio提供了一個服務間通訊的基礎設施層,解耦了應用邏輯和服務訪問中版本管理、安全防護、故障轉移、監控遙測等切面的問題。

Istio為希臘語,意思是“啟航”,雖然是一個非常年輕的專案卻得到了極大的關注,其生態發展非常迅猛。我們今天先關注一下在其分散式服務追蹤(Distributed Tracing)相關的進展。

安裝 Istio

配置 Kubernetes 叢集

我們可以使用Minikube或者阿里雲容器服務Kubernetes叢集進行驗證。

由於我們將採用 Initializers 方式進行部署,需要執行如下命令開啟相應的 Initializers 准入控制外掛。

minikube start \
    --memory 4096 \
    --registry-mirror=https://registry.docker-cn.com \
--extra-config=apiserver.Admission.PluginNames="Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota"

阿里雲容器服務在1.8+版本以上的Kubernetes叢集已經內建開啟了 Initializers 外掛,無需額外的配置工作。

注:由於部署Istio之後會為每個Pod注入sidecar,來接管服務通訊,建議在獨立的測試環境中進行驗證。

需要根據叢集管理頁面資訊,配置相應的連線資訊

image

下載 Istio 發行版

在 Istio releases頁面 獲取最新的安裝包,解壓到本地,或者執行如下命令

curl -L https://git.io/getLatestIstio | sh -

執行如下命令

# 切換工作目錄到 Istio
cd istio-0.3.0
# 新增 istioctl client 到 PATH 環境變數
export PATH=$PWD/bin:$PATH

部署 Istio

# 部署 Istio 系統元件
kubectl apply -f install/kubernetes/istio.yaml
# 部署 Istio initializer 外掛
kubectl apply -f install/kubernetes/istio-initializer.yaml

部署完畢後,可以用如下命令來驗證 Istio 元件是否成功部署

$ kubectl get svc,pod  -n istio-system
NAME                TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)                                                            AGE
svc/istio-ingress   LoadBalancer   10.0.0.241   <pending>     80:31411/TCP,443:31972/TCP                                         22m
svc/istio-mixer     ClusterIP      10.0.0.146   <none>        9091/TCP,15004/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP   22m
svc/istio-pilot     ClusterIP      10.0.0.253   <none>        15003/TCP,443/TCP                                                  22m

NAME                                    READY     STATUS    RESTARTS   AGE
po/istio-ca-76dddbd695-jzgq4            1/1       Running   0          22m
po/istio-ingress-85fb769c4d-8jr4r       1/1       Running   0          22m
po/istio-initializer-7fcb8b7454-f68h8   1/1       Running   0          10s
po/istio-mixer-587fd4bbdb-wpbfr         3/3       Running   0          22m
po/istio-pilot-7db8db896c-wdmhp         2/2       Running   0          22m

等待所有的 Pod 進入執行狀態,Istio 就已經部署完成了。

分散式服務追蹤

部署測試應用BookInfo

參照 BookInfo指南,部署應用。該應用由若干個微服務組成,每個微服務都通過容器方式進行部署。

image

執行 如下命令

kubectl apply -f samples/bookinfo/kube/bookinfo.yaml

MiniKube 環境下執行如下命令獲取相應的訪問地址

export GATEWAY_URL=$(kubectl get po -l istio=ingress -n istio-system -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -n istio-system -o 'jsonpath={.spec.ports[0].nodePort}')

阿里雲Kubernetes叢集已經為每個叢集配置了SLB和Ingress

$ kubectl get ingress -o wide
NAME      HOSTS     ADDRESS          PORTS     AGE
gateway   *         112.74.xxx.xxx   80        2m

我們可以通過如下的方法來獲得相應的地址

export GATEWAY_URL=$(kubectl get ingress -o wide -o jsonpath={.items[0].status.loadBalancer.ingress[0].ip})

當如下命令

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage

返回 200 時,就表示應用已經成功部署,可以通過瀏覽器開啟 http://${GATEWAY_URL}/productpage 來訪問應用了

image

部署分散式服務追蹤

分散式追蹤系統可以幫助觀察服務間呼叫鏈,是診斷效能問題、分析系統故障的利器。

Istio 生態實現了對不同的分散式追蹤系統的支援,包括ZipkinJaeger

Istio v0.3 提供了對Jaeger良好支援,測試方法如下

kubectl apply -n istio-system -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml

部署完成之後,我們可以通過埠對映來訪問Jaeger 控制面板:

kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686 &

多訪問幾次測試應用,我們可以清楚的看到服務的呼叫鏈,

image

image

image

Istio分散式追蹤實現

Istio服務網格的核心是Envoy,是一個高效能的開源L7代理和通訊匯流排。在Istio中,每個微服務都被注入了Envoy Sidecar,該例項負責處理所有傳入和傳出的網路流量。因此,每個Envoy Sidecar都可以監控所有的服務間API呼叫,並記錄每次服務呼叫所需的時間以及是否成功完成。

每當微服務發起外部呼叫時,客戶端Envoy會建立一個新的span。一個span代表一組微服務之間的完整互動過程,從請求者(客戶端)發出請求開始到接收到服務方的響應為止。

在服務互動過程中,客戶端會記錄請求的發起時間和響應的接收時間,伺服器端Envoy會記錄請求的接收時間和響應的返回時間。

每個Envoy都會將自己的span檢視資訊釋出到分散式追蹤系統。當一個微服務處理請求時,可能需要呼叫其他微服務,從而導致因果關聯的span的建立,形成完整的trace。這就需要由應用來從請求訊息中收集和轉發下列 Header

  • x-request-id
  • x-b3-traceid
  • x-b3-spanid
  • x-b3-parentspanid
  • x-b3-sampled
  • x-b3-flags
  • x-ot-span-context

在通訊鏈路中的Envoy,可以擷取、處理、轉發相應的Header。

    Client Tracer                                              Server Tracer
┌──────────────────┐                                       ┌──────────────────┐
│                  │                                       │                  │
│   TraceContext   │           Http Request Headers        │   TraceContext   │
│ ┌──────────────┐ │          ┌───────────────────┐        │ ┌──────────────┐ │
│ │ TraceId      │ │          │ X─B3─TraceId      │        │ │ TraceId      │ │
│ │              │ │          │                   │        │ │              │ │
│ │ ParentSpanId │ │ Extract  │ X─B3─ParentSpanId │ Inject │ │ ParentSpanId │ │
│ │              ├─┼─────────>│                   ├────────┼>│              │ │
│ │ SpanId       │ │          │ X─B3─SpanId       │        │ │ SpanId       │ │
│ │              │ │          │                   │        │ │              │ │
│ │ Sampled      │ │          │ X─B3─Sampled      │        │ │ Sampled      │ │
│ └──────────────┘ │          └───────────────────┘        │ └──────────────┘ │
│                  │                                       │                  │
└──────────────────┘                                       └──────────────────┘

總結

Istio 藉助良好的擴充套件機制和強大的生態正在加速 Service Mesh的應用和普及。除上文之外還有 Weave Scope, Istio Dashboard 和 Istio-Analytics 專案提供豐富的呼叫鏈路視覺化和分析能力。

本文作者:易立