情感分析應用的架構
我們將會繼續使用Kubernetes入門文章中的樣例,它較爲複雜,足以通過實踐展示Istio的特性。
這個應用由四個微服務組成:
- SA-Frontend服務:前端的Reactjs應用;
- SA-WebApp服務:處理情感分析的請求;
- SA-Logic服務:執行情感分析;
- SA-Feedback服務:接收用戶關於分析精確性的反饋。
在圖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所示。
但是,要訪問服務,我們需要允許傳入的流量進入集羣,也就是所謂的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-frontend、sa-web-app和sa-feedback服務(如圖8所示)。
現在,我們拆分一下應該路由至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
這裏的重點在於:
- VirtualService將會應用於通過http-gateway的請求;
- 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所示。
現在,我們可以通過http://{{EXTERNAL-IP}}/
訪問情感分析應用了。如果你遇到Not Found狀態的話,請不要擔心,有時候配置生效並更新envoy緩存會耗費一點時間。
在轉入下一部分之前,你需要使用該應用生成一些流量。
系列回顧