通過 Istio 重新實現微服務 (三):使用Istio代理運行應用

情感分析應用的架構

我們將會繼續使用Kubernetes入門文章中的樣例,它較爲複雜,足以通過實踐展示Istio的特性。

這個應用由四個微服務組成:

  • SA-Frontend服務:前端的Reactjs應用;
  • SA-WebApp服務:處理情感分析的請求;
  • SA-Logic服務:執行情感分析;
  • SA-Feedback服務:接收用戶關於分析精確性的反饋。

圖6 情感分析的微服務

在圖6中,除了服務之外,我們還看到了Ingress Controller,在Kubernetes中,它會將傳入的請求路由至對應的服務,Istio採用了類似的概念,名爲Ingress Gateway,在本文後續的內容中,我們將會對其進行介紹。

使用Istio代理運行應用

如果要要跟着本文一起練習的話,讀者可以clone該GitHub倉庫 istio-mastery,其中包含了適用於Kubernetes和Istio的應用程序與manifest。

Sidecar注入

注入可以自動手動完成。如果要啓用自動化的Sidecar注入,我們需要使用istio-injection=enabled來標記命名空間,這可以通過執行如下的命令來實現:

$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

現在,默認命名空間中部署的所有pod都將會被注入sidecar。切換至[istio-mastery]倉庫的根目錄,並執行如下的命令:

$ kubectl apply -f resource-manifests/kube
persistentvolumeclaim/sqlite-pvc created 
deployment.extensions/sa-feedback created 
service/sa-feedback created 
deployment.extensions/sa-frontend created
service/sa-frontend created 
deployment.extensions/sa-logic created 
service/sa-logic created 
deployment.extensions/sa-web-app created 
service/sa-web-app created

執行如下的命令並檢查Ready列,我們會看到“2/2”,這表明第二個容器已經注入進來了。

$ kubectl get pods
NAME                         READY STATUS   RESTARTS   AGE 
sa-feedback-55f5dc4d9c-c9wfv 2/2    Running  0         12m 
sa-frontend-558f8986-hhkj9   2/2    Running  0         12m
sa-logic-568498cb4d-s9ngt   2/2     Running  0         12m 
sa-web-app-599cf47c7c-s7cvd 2/2     Running  0         12m

服務已經啓動並運行了,每個容器都包含了sidecar代理,如圖7所示。

圖7 某個Pod中的Envoy代理

但是,要訪問服務,我們需要允許傳入的流量進入集羣,也就是所謂的Ingress流量。

Ingress網關

允許流量進入集羣的一個最佳實踐就是使用Istio的Ingress網關,它處於集羣的邊緣並且靠近傳入的流量,它能夠實現Istio的多項特性,比如路由、安全和監控。

在Istio安裝的時候,Ingress網關組件以及將其暴露給外部的服務已經安裝到了集羣中,我們可以通過如下的命令獲取它的外部IP:

$ kubectl get svc -n istio-system -l istio=ingressgateway
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)
istio-ingressgateway   LoadBalancer   10.0.132.127   13.93.30.120   80:31380/TCP,443[...]

在本文後續的內容中,我們將會通過該IP(將其稱爲EXTERNAL-IP)訪問應用程序,爲了便利起見,我們通過下面的命令將其保存到變量中:

$ EXTERNAL_IP=$(kubectl get svc -n istio-system \
			-l app=istio-ingressgateway \
			-o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

如果你在瀏覽器中訪問該IP的話,將會看到服務不可用的錯誤,默認情況下,在我們定義網關之前,Istio會阻止所有傳入的流量。

網關資源

網關是一種Kubernetes自定義資源定義(Kubernetes Custom Resource Definition),它是我們在集羣中安裝Istio時所定義的,藉助它,我們能夠指定允許傳入流量的端口、協議和主機。

在我們的場景中,我們想要爲所有主機開放80端口。我們可以通過如下的定義來進行配置:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: http-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
	hosts: 
	- "*"

除了istio: ingressgateway選擇器之外,所有配置項的含義均不言自明。通過使用這個選擇器,我們可以指定哪個Ingress網關使用該配置,在我們的場景中,也就是在Istio安裝時的默認Ingress網關控制器。

通過執行如下的命令,應用該配置:

$ kubectl apply -f resource-manifests/istio/http-gateway.yaml
gateway.networking.istio.io "http-gateway" created

網關允許我們訪問80端口,但是它還不知道要將請求路由至何處,而這一功能是通過Virtual Service來實現的。

VirtualService資源

VirtualService能夠指導Ingress網關如何路由允許進入集羣的請求。

對於我們的應用來說,通過http-gateway的請求必須要路由至sa-frontendsa-web-appsa-feedback服務(如圖8所示)。

圖8 通過VirtualService配置路由

現在,我們拆分一下應該路由至SA-Frontend的請求:

  • 精確的路徑“/”應該路由至SA-Frontend以便於獲取Index.html;
  • 帶有“/static/*”前綴的路徑應該路由至SA-Frontend,以便於獲取前端所需的靜態文件,比如級聯樣式表和JavaScript文件;
  • 匹配正則表達式“^.*\.(ico|png|jpg)$”的路徑應該路由至SA-Frontend,因爲它代表的是頁面展現所需的圖片。

這樣,我們就會得到如下的配置:

kind: VirtualService 
metadata:
	name: sa-external-services 
spec:
  hosts:
  - "*"
  gateways:
  - http-gateway      # 1
  http:
  - match:
    - uri:
        exact: /
    - uri:
        exact: /callback
    - uri:
        prefix: /static
    - uri:
		regex: '^.*\.(ico|png|jpg)$' 
	route:
	- destination:
  		host: sa-frontend    # 2
    	port:
			number: 80

這裏的重點在於:

  1. VirtualService將會應用於通過http-gateway的請求;
  2. destination定義了請求要路由至哪個服務。

注意:上面的配置在sa-virtualservice-external.yaml文件中,它還包含了路由至SA-WebApp和SA-Feedback的配置,但是簡潔期間,我們將其省略了。

通過執行如下的命令,應用VirtualService:

$ kubectl apply -f resource-manifests/istio/sa-virtualservice-external.yaml
virtualservice.networking.istio.io "sa-external-services" created

注意:當我們應用該資源時(其實所有的Istio資源均如此),Kubernetes API Server會創建一個新的事件,該事件會被Istio的控制平面接收到,然後會將新的配置應用到每個pod的envoy代理上。Ingress Gateway控制器是Control Plane配置的另外一個Envoy,如圖9所示。

圖9 配置Istio-IngressGateway來路由請求

現在,我們可以通過http://{{EXTERNAL-IP}}/訪問情感分析應用了。如果你遇到Not Found狀態的話,請不要擔心,有時候配置生效並更新envoy緩存會耗費一點時間。

在轉入下一部分之前,你需要使用該應用生成一些流量。


系列回顧

通過 Istio 重新實現微服務 (一):認識 Istio

通過 Istio 重新實現微服務 (二):Istio 實踐

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章