本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用 Istio 服務網格管理微服務

今天的文章由 Istio 團隊撰寫,展示瞭如何在 Kubernetes 中為微服務提供可見性、彈性、安全性和控制。

服務是現代軟體架構的核心。部署一系列模組化、小型(微型)服務而不是大型單體服務,讓開發人員可以靈活地在整個系統中使用不同的語言、技術和釋出節奏;從而提高生產力和速度,尤其適用於大型團隊。

然而,隨著微服務的採用,由於大型系統中存在的服務數量龐大,新的問題也隨之出現。對於單體應用只需解決一次的問題,如安全性、負載均衡、監控和速率限制,現在需要為每個服務單獨處理。

Kubernetes 和服務

Kubernetes 透過 服務 構造支援微服務架構。它允許開發人員抽象出一組 Pod 的功能,並透過定義明確的 API 將其暴露給其他開發人員。它允許為這一抽象層新增名稱並執行基本的 L4 負載均衡。但它無助於解決更高級別的問題,例如 L7 指標、流量拆分、速率限制、熔斷等。

上週在 GlueCon 2017 大會上釋出的 Istio 透過服務網格框架從根本上解決了這些問題。有了 Istio,開發人員可以實現微服務的核心邏輯,然後讓框架負責其餘部分——流量管理、發現、服務身份和安全性以及策略實施。更棒的是,這也可以應用於現有微服務,而無需重寫或重新編譯其任何部分。Istio 使用 Envoy 作為其執行時代理元件,並提供了一個 可擴充套件的中間層,允許全域性跨領域策略實施和遙測資料收集。

Istio 的當前版本面向 Kubernetes 使用者,並且以一種方式打包,您只需幾行程式碼即可安裝,併為 Kubernetes 中的微服務提供開箱即用的可見性、彈性、安全性和控制。

在一系列部落格文章中,我們將研究一個由 4 個獨立微服務組成的簡單應用程式。我們將首先介紹如何使用純 Kubernetes 部署應用程式。然後,我們將在啟用 Istio 的叢集中部署完全相同的服務,而無需更改任何應用程式程式碼——並檢視如何觀察指標。

在後續文章中,我們將重點介紹更高階的功能,例如 HTTP 請求路由、策略、身份和安全管理。

示例應用程式:BookInfo

我們將使用一個名為 BookInfo 的簡單應用程式,它顯示商店中書籍的資訊、評論和評分。該應用程式由四種不同語言編寫的微服務組成

BookInfo-all (2).png由於這些微服務的容器映象都可以在 Docker Hub 中找到,因此我們只需要 Kubernetes 的 yaml 配置即可部署此應用程式。

值得注意的是,這些服務對 Kubernetes 和 Istio 沒有依賴關係,但卻是一個有趣的案例研究。特別是,評論服務的服務、語言和版本眾多,使其成為一個有趣的服務網格示例。有關此示例的更多資訊可以在此處找到。

在 Kubernetes 中執行 Bookinfo 應用程式

在這篇文章中,我們將重點關注應用程式的 v1 版本

BookInfo-v1 (3).png

使用 Kubernetes 部署它很簡單,與其他任何服務的部署方式沒有區別。 productpage 微服務的 Service 和 Deployment 資源如下所示

apiVersion: v1

kind: Service

metadata:

name: productpage

labels:

  app: productpage

spec:

type: NodePort

ports:

- port: 9080

  name: http

selector:

  app: productpage

---

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

name: productpage-v1

spec:

replicas: 1

template:

  metadata:

    labels:

      app: productpage

      track: stable

  spec:

    containers:

    - name: productpage

      image: istio/examples-bookinfo-productpage-v1

      imagePullPolicy: IfNotPresent

      ports:

      - containerPort: 9080

如果我們想執行該應用程式,還需要部署另外兩個服務:**details** 和 **reviews-v1**。此時我們不需要部署 **ratings** 服務,因為 reviews 服務的 v1 版本不使用它。其餘服務基本上遵循與 **productpage** 相同的模式。所有服務的 yaml 檔案都可以在 此處 找到。

將服務作為普通的 Kubernetes 應用程式執行

kubectl apply -f bookinfo-v1.yaml

要從叢集外部訪問應用程式,我們需要 **productpage** 服務的 NodePort 地址

export BOOKINFO\_URL=$(kubectl get po -l app=productpage -o jsonpath={.items[0].status.hostIP}):$(kubectl get svc productpage -o jsonpath={.spec.ports[0].nodePort})

我們現在可以將瀏覽器指向 http://$BOOKINFO_URL/productpage,並看到

使用 Istio 執行 Bookinfo 應用程式

現在我們已經看到了應用程式,我們將稍微調整部署以使其與 Istio 一起工作。我們首先需要在叢集中安裝 Istio。為了看到所有指標和跟蹤功能,我們還安裝了可選的 Prometheus、Grafana 和 Zipkin 外掛。我們現在可以刪除之前的應用程式並使用完全相同的 yaml 檔案再次啟動 Bookinfo 應用程式,這次是使用 Istio

kubectl delete -f bookinfo-v1.yaml

kubectl apply -f \<(istioctl kube-inject -f bookinfo-v1.yaml)

請注意,這次我們使用 `istioctl kube-inject` 命令修改 `bookinfo-v1.yaml`,然後再建立部署。它將 Envoy Sidecar 注入到 Kubernetes Pod 中,具體請參閱此處。因此,所有微服務都與 Envoy Sidecar 一起打包,該 Sidecar 管理服務的傳入和傳出流量。

在 Istio 服務網格中,我們不希望像在純 Kubernetes 中那樣直接訪問應用程式 **productpage**。相反,我們希望請求路徑中有一個 Envoy sidecar,這樣我們就可以使用 Istio 的管理功能(版本路由、熔斷器、策略等)來控制對 **productpage** 的外部呼叫,就像我們可以控制內部請求一樣。Istio 的 Ingress 控制器用於此目的。

要使用 Istio Ingress 控制器,我們需要為應用程式建立一個 Kubernetes Ingress 資源,並使用 `kubernetes.io/ingress.class: "istio"` 進行標註,如下所示

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

使用 Istio 和 bookinfo 應用的 v1 版本進行部署,結果如下

BookInfo-v1-Istio (5).png

這次我們將使用 Istio Ingress 控制器的 NodePort 地址訪問應用程式

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

我們現在可以在 http://$BOOKINFO_URL/productpage 載入頁面,並再次看到正在執行的應用程式——對於使用者來說,應該與之前沒有 Istio 的部署沒有任何區別。

然而,現在應用程式正在 Istio 服務網格中執行,我們可以立即開始看到一些好處。

指標收集

我們從 Istio 開箱即用獲得的第一件事是 Prometheus 中的指標收集。這些指標由 Envoy 中的 Istio 過濾器生成,根據預設規則(可以自定義)收集,然後傳送到 Prometheus。指標可以在 Grafana 的 Istio 儀表板中視覺化。請注意,雖然 Prometheus 是開箱即用的預設指標後端,但 Istio 允許您插入其他後端,我們將在未來的部落格文章中演示。

為了演示,我們首先執行以下命令來為應用程式生成一些負載

wrk -t1 -c1 -d20s http://$BOOKINFO\_URL/productpage

我們獲取 Grafana 的 NodePort URL

export GRAFANA\_URL=$(kubectl get po -l app=grafana -o jsonpath={.items[0].status.hostIP}):$(kubectl get svc grafana -o jsonpath={.spec.ports[0].nodePort})

我們現在可以在瀏覽器中開啟 http://$GRAFANA_URL/dashboard/db/istio-dashboard,並檢查每個 Bookinfo 服務的各種效能指標

istio-dashboard-k8s-blog.png

分散式追蹤 接下來,我們從 Istio 獲得的是使用 Zipkin 進行呼叫追蹤。我們獲取其 NodePort URL

export ZIPKIN\_URL=$(kubectl get po -l app=zipkin -o jsonpath={.items[0].status.hostIP}):$(kubectl get svc zipkin -o jsonpath={.spec.ports[0].nodePort})

我們現在可以將瀏覽器指向 http://$ZIPKIN_URL/,以檢視透過 Bookinfo 服務的請求跟蹤跨度。

儘管 Envoy 代理開箱即用地將跟蹤跨度傳送到 Zipkin,但要充分發揮其潛力,應用程式需要感知 Zipkin 並轉發一些標頭以將各個跨度關聯起來。有關詳細資訊,請參閱 zipkin-tracing

整個機群的整體檢視 Istio 提供的指標不僅僅是方便。透過在整個服務網格中生成統一指標,它們提供了服務網格的一致檢視。我們不必擔心協調各種執行時代理發出的不同型別的指標,也不必新增任意代理來為未檢測的遺留應用程式收集指標。我們也不再需要依賴開發過程來正確檢測應用程式以生成指標。服務網格能夠看到所有流量,甚至包括進出遺留“黑盒”服務的流量,併為所有這些流量生成指標。 總結 上述演示展示瞭如何通過幾個步驟啟動 Istio 支援的服務並觀察其上的 L7 指標。在接下來的幾周,我們將繼續演示 Istio 的更多功能,例如策略管理和 HTTP 請求路由。Google、IBM 和 Lyft 聯手建立了 Istio,這是基於我們在為內部和企業客戶構建和運營大型複雜微服務部署方面的共同經驗。Istio 是一項行業範圍的社群工作。我們很高興看到行業合作伙伴的熱情以及他們帶來的見解。當我們邁出下一步並將 Istio 釋出到野外時,我們迫不及待地想看到更廣泛的貢獻者社群將為它帶來什麼。如果您正在使用或考慮在 Kubernetes 上使用微服務架構,我們鼓勵您嘗試 Istio,在 istio.io 上了解更多資訊,告訴我們您的想法,或者更好的是,加入開發人員社群,幫助塑造它的未來!

——代表 Istio 團隊。IBM 軟體工程師 Frank Budinsky,Google 軟體工程師 Andra Cismaru 和產品經理 Israel Shalom。