部署 Service Mesh 簡化微服務通信(下)

來自專欄 KubernetesMeetup 社區

在下面的教程中,我們將使用 Istio Service Mesh 來演示一個最強大的功能:「請求路由」。Istio Service Mesh 允許將選定 HTTP 標記的特定請求路由到特定目標上,這個功能只有第 7 層代理可以做到。第 4 層負載均衡器或代理是不可以實現該功能的。

在本教程中,我們假設你正在運行 Kubernetes 集羣(提示:遵循這些說明,你可以在幾分鐘內啟動新集羣,或使用「 Kublr-in-a-box 」來設置本地集羣)。對於本教程,具有 1 個主節點和 2 個工作節點的小型集羣足已。

安裝 Istio 控制平面

一種選擇是遵循官方教程,在 Kubernetes 集羣中安裝控制平面。安裝步驟取決於你的本地機器類型(Mac,Linux,Windows),因此我們不會在此提供本地 istioctl 應用程序和 kubectl 的安裝說明,這兩個 CLI 工具將用於管理 Kubernetes 和 Istio。

對於那些缺乏耐心但懂行的人來說,這有分不太詳細的指導(如果不奏效,可以逐步使用官方指導):

  • 安裝 Kubernetes 集羣(使用上面列出的任何方法,或使用現有的測試開發集羣)。
  • 在本地安裝 kubectl(用它來管理 Kubernetes 集羣)。
  • 從 GitHub 發布頁面安裝 istioctl(將 Envoy 代理注入 Pod 並設置路由規則和策略),安裝很簡單:
  • 適用於 Mac 或 Linux 運行curl -L https://git.io/getLatestIstio | sh -
  • 在 Windows 上解壓縮 zip,並將二進位文件複製到 PATH(可以簡單地複製到c:windowssystem32)或 istioctl.exe 從 /bin/ 目錄運行所有命令。

從 /bin/ 目錄運行所有命令。

  • 到包含解壓縮文件的文件夾,然後通過執行kubectl apply -f install/kubernetes/istio-demo.yaml

進行安裝。

另一種選擇是使用 Kublr 創建你的 Kubernetes 集羣:在 AWS 或 Azure 上啟動集羣的簡便方法(閱讀我們的快速入門即可[1])。

在儀錶板中找到以下鏈接並將配置文件下載到你的

~/.kube/config

(%USERPROFILE%/.kube/config 在Windows中),然後導航到 Kubernetes 儀錶板:

%USERPROFILE%/.kube/config

在 Windows 中,然後導入到 Kubernetes 儀錶板:

使用配置文件中的憑據(找到 「username:admin」 並使用此用戶及其列出的密碼登錄儀錶板)。你能看到儀錶板,並單擊側欄中的默認 「NAMESPACE」, 將顯示以下 3 個默認 Namespace:

Istio 組件將安裝到它們自己的 Namespace 中。找到你下載的 Istio 壓縮包、解壓,然後在文件夾下運行:

kubectl apply -f install/kubernetes/istio-demo.yaml

你將看到正在創建的許多組件,每個組件都在官方文檔中有描述,或者你可以打開 yaml 文件查看注釋,每個資源都記錄在該文件中。然後我們可以瀏覽 Namespace 並檢查是否所有內容都已成功創建:

單擊 istio-system 並確保在組件創建期間沒有錯誤或問題。它看起來應該類似於:

圖中大約有 50 個事件,你可以滾動查看「成功」狀態,並看到某處是否有錯誤。如果出現錯誤,你可以在 Istio GitHub 問題頁面上發布錯誤報告。

我們需要找到 istio-ingress 服務的入口點,以此瞭解流量發送到的位置。導航到側欄中的 「istio-system」Namespace。如果它創建後在其他 Namespace 中不可見,只需刷新瀏覽器頁面,選擇該 Namespace,單擊 「Service」 並找到外部端點,如下圖所示:

這是 AWS 彈性負載均衡器,但你可能會看到 IP 地址,具體取決於集羣設置。我們將使用此端點地址訪問我們演示的 Web 服務。

使用 Envoy Proxy Sidecar 部署演示 Web 服務

現在來到本教程最有趣的部分。我們來檢查這個 Sevice Mesh 的路由功能。首先,我們將部署兩個演示 Web 服務,「藍色」和「綠色」。將以下內容複製到名為 my-websites.yaml 的 yaml 文件中。

apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v1 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-1 spec: containers: - name: website-version-1 image: aquamarine/kublr-tutorial-images:v1 resources: requests: cpu: 0.1 memory: 200---apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v2 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-2 spec: containers: - name: website-version-2 image: aquamarine/kublr-tutorial-images:v2 resources: requests: cpu: 0.1 memory: 200---apiVersion: apps/v1beta1kind: Deploymentmetadata: name: web-v3 namespace: defaultspec: replicas: 1 template: metadata: labels: app: website version: website-version-3 spec: containers: - name: website-version-3 image: aquamarine/kublr-tutorial-images:v3 resources: requests: cpu: 0.1 memory: 200---apiVersion: v1kind: Servicemetadata: name: websitespec: ports: - port: 80 targetPort: 80 protocol: TCP name: http selector: app: website

請注意,當你想要使用帶有 Pod 的 Envoy sidecar 時,應該存在標籤「app」中(它用於請求跟蹤功能使用),並且服務定義中的 「spec.ports.name」 必須正確命名(http、http2、grpc、redis、mongo)否則 Envoy 將對該服務流量採取行動,把它當成普通的 TCP 一樣,這樣你將無法使用路由的第 7 層功能!此外,Pod 在集羣中只提供一個「Service」。如你所見,定義文件有三個簡單的部署,每個部署使用不同版本的 Web 服務(v1 / v2 / v3),以及三個簡單的服務,每個服務都指向相應的部署。

現在,我們將使用 「istioctl kube-inject」 命令將所需的 Envoy 代理配置添加到此文件中的 Pod 來定義。它將生成一個新的 yaml 文件,其中包含可供 kubectl 部署的 Envoy sidecar 其他組件,運行:

istioctl kube-inject -f my-websites.yaml -o my-websites-with-proxy.yaml

如果它按預期進行工作,你將看到此輸出:

deployment "web-v1" createddeployment "web-v2" createddeployment "web-v3" createdservice "website" createdLet』s inspect the pods to see that the Envoy

我們可以看到每個 Pod 有兩個容器,一個是網站容器,另一個是代理 sidecar:

此外,我們可以通過運行以下命令檢查 Envoy 代理日誌:

kubectl logs <your pod name> istio-proxy

你將看到很多輸出,最後一行與此類似:

add/update cluster outbound|80|version-1|website.default.svc.cluster.local starting warmingadd/update cluster outbound|80|version-2|website.default.svc.cluster.local starting warmingadd/update cluster outbound|80|version-3|website.default.svc.cluster.local starting warmingwarming cluster outbound|80|version-3|website.default.svc.cluster.local completewarming cluster outbound|80|version-2|website.default.svc.cluster.local completewarming cluster outbound|80|version-1|website.default.svc.cluster.local complete

這意味著代理 sidecar 狀態良好並在該 Pod 中運行。

現在我們需要部署最小的 Istio 配置資源,將流量路由到我們的服務和 Pod 上,將以下清單保存到名為「website-routing.yaml」的文件中:

---apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: website-gatewayspec: selector: # Which pods we want to expose as Istio router # This label points to the default one installed from file istio-demo.yaml istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP # Here we specify which Kubernetes service names # we want to serve through this Gateway hosts: - "*"---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: website-virtual-servicespec: hosts: - "*" gateways: - website-gateway http: - route: - destination: host: website subset: version-1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: websitespec: host: website subsets: - name: version-1 labels: version: website-version-1 - name: version-2 labels: version: website-version-2 - name: version-3 labels: version: website-version-3

Gateway,VirtualService 和 DestinationRule 是自定義的 Istio 資源,用於管理和配置

istio-ingressgateway pod

的入口行為。我們將在下一個教程中更深入地描述它們,這些教程寫明 Istio 配置的技術細節。現在,部署這些資源以便能夠訪問示例的網站:

kubectl create -f website-routing.yam

下一步是訪問我們的演示網站。我們部署了三個「版本」,每個版本顯示不同的頁面文本和顏色,但目前我們只能通過 Istio ingress 訪問 v1。而我們訪問我們的終端只是為了確保 Web 服務被部署。

通過運行以下命令查找外部端點:

kubectl get services istio-ingressgateway -n istio-system

或者通過瀏覽 istio-ingressgateway 服務找到它,如下所示(我們也在本教程的開頭看到它):

通過點擊它訪問外部端點。你可能會看到多個鏈接,因為一個鏈接指向 HTTPS,另一個鏈接指向負載均衡器的 HTTP 埠。如果是這樣,請僅使用 HTTP 鏈接,因為我們沒有為本教程設置 TLS,你應該看到演示網站的 v1 頁面:

我們示例網站中的 Kubernetes 服務僅指向單一部署,而確切配置是我們為網站創建的 Istio VirtualService。它告訴 Envoy 代理將「Web」服務的請求僅路由到標籤為「version:website-version-1」的 Pod(服務網站的清單只選擇了一個標籤「app:website」是來自我們的 Pod ,但是沒有說明要選擇的「版本」標籤 —— 因此,如果沒有Envoy 路由策略,Kubernetes 服務本身將在所有具有「app:website」標籤的 Pod 中進行循環,包括 v1、2 和 3。你可以通過更改 VirtualService 清單的以下部分並重新部署它來更改我們看到的網站版本:

http: - route: - destination: host: website subset: version-1

通常,當需要使用少量流量測試新版本的應用程序時(金絲雀部署),vanilla Kubernetes 方法將創建第二個部署,該部署使用新的 Docker 鏡像但使用相同的 Pod標籤,這樣就可以使「Service」將流量發送到此 Pod 標籤中,同時在第二次部署中將新插入的 Pod 與之前的 Pod 進行平衡。它不像 Istio 解決方案那樣靈活。你無法輕鬆將 10% 的流量指向新部署(為了達到精確的 10%,你需要根據所需的百分比保持兩個部署之間的 Pod 副本比例,例如 9 個「v1 pods」和 1 個「v2 pod 「,或 18 個」v1 pods「和 2 個」v2 pods「),並且不能使用 HTTP 標頭將請求路由到特定版本上。

參考文獻:

[1]docs.kublr.com/quicksta

[2]kublr.com/blog/implemen


推薦閱讀:
相關文章