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

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

今天的文章由 Istio 團隊發布,展示如何在 Kubernetes 中為您的微服務取得可見性、彈性、安全性和控制。

服務是現代軟體架構的核心。部署一系列模組化、小型(微)服務,而不是大型單體式應用程式,使開發人員能夠靈活地跨系統使用不同的語言、技術和發布節奏;從而提高生產力和速度,尤其是對於較大的團隊而言。

然而,隨著微服務的採用,由於較大系統中存在大量服務,因此出現了新的問題。對於單體式應用程式只需解決一次的問題,例如安全性、負載平衡、監控和速率限制,現在需要為每個服務處理。

Kubernetes 和服務

Kubernetes 透過 Service 建構支援微服務架構。它允許開發人員抽象化一組 Pod 的功能,並透過明確定義的 API 將其公開給其他開發人員。它允許為此抽象層級新增名稱並執行基本的 L4 負載平衡。但它對更高層級的問題沒有幫助,例如 L7 指標、流量分割、速率限制、斷路等。

Istio 在上週的 GlueCon 2017 上宣布,透過服務網格框架從根本上解決了這些問題。透過 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

如果我們要執行該應用程式,我們需要部署的其他兩個服務是 detailsreviews-v1。我們目前不需要部署 ratings 服務,因為 v1 版本的 reviews 服務未使用它。其餘服務基本上遵循與 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 一起封裝,Envoy 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 和 v1 版本 bookinfo 應用程式的最終部署如下所示

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。