官網文檔:
https://istio.io/docs/reference/config/networking/#VirtualService
在學習像Istio這樣的新技術時,看一下示例應用程序總是一個好主意。 Istio repo有一些示例應用程序,但它們似乎有各種不足。 文檔中的BookInfo是一個很好的示例。 但是,對於我而言,它太冗長,服務太多,而且文檔似乎專注於管理BookInfo應用程序,而不是從頭開始構建。 有一個較小的helloworld例子,但它更多的是關於自動伸縮而不是其他。 在這篇文章中,我想介紹一下基礎知識,並展示如何從頭開始構建支持Istio的“HelloWorld”應用程序。 要記住的一點是,Istio只管理你應用的流量。 在這種情況下,應用程序生命周期由底層平台Kubernetes管理。 因此,你需要了解容器和Kubernetes基礎知識,並且需要了解Istio Routing原語,例如Gateway,VirtualService,DestinationRule。 我假設大多數人都知道容器和Kubernetes基礎知識。 我將在本文中專注於Istio Routing。 # 基礎步驟 以下這些大致就是你需要遵循的,以獲得Istio的“HelloWorld”應用程序的步驟:
創建一個Kubernetes集群並安裝帶有sidecare自動注入的Istio。
使用你選擇的語言創建Hello World應用程序,創建Docker鏡像並將其推送到公共鏡像倉庫。
為你的容器創建Kubernetes Deployment和Service。
創建Gateway以啟用到群集的HTTP(S)流量。
創建VirtualService,通過Gateway公開Kubernetes服務。
(可選)如果要創建多個版本應用程序,請創建DestinationRule以定義可從VirtualService引用的subsets。
(可選)如果要在服務網格外部調用其他外部服務,請創建ServiceEntry。
我不會在本文中介紹步驟1和2,因為它們不是特定於Istio的。 如果您需要有關這些步驟的幫助,可以查看我在本文末尾提到的文章。 第3步也不是Istio特定的,但它是其他一切的先決條件,所以讓我們從那開始。 # Deployment和Service 正如我所提到的,應用程序生命周期由Kubernetes管理。 因此,您需要從創建Kubernetes Deployment和Service開始。 我的情況如下,我有一個容器化的ASP.NET核心應用程序,其鏡像我已經推送到谷歌鏡像倉庫。 讓我們從創建一個aspnetcore.yaml
文件開始:
apiVersion: v1
kind: Service
metadata:
name: aspnetcore-service
labels:
app: aspnetcore
spec:
ports:
- port: 8080
name: http
selector:
app: aspnetcore
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: aspnetcore-v1
spec:
replicas: 1
template:
metadata:
labels:
app: aspnetcore
version: v1
spec:
containers:
- name: aspnetcore
image: gcr.io/istio-project-212517/hello-dotnet:v1
imagePullPolicy: Always #IfNotPresent
ports:
- containerPort: 8080
創建Deployment和Service:
$ kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created
deployment.extensions "aspnetcore-v1" created
到目前為止沒有任何特定的針對Istio的內容。 # Gateway 我們現在可以開始研究Istio Routing。 首先,我們需要為服務網格啟用HTTP/HTTPS流量。 為此,我們需要創建一個網關。 Gateway描述了在邊緣運行的負載均衡,用於接收傳入或傳出的HTTP/TCP連接。 讓我們創建一個aspnetcore-gateway.yaml
文件:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: aspnetcore-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:- "*"
創建Gateway:
$ kubectl apply -f aspnetcore-gateway.yaml
gateway.networking.istio.io "aspnetcore-gateway" created
此時,我們為集群啟用了HTTP流量。 我們需要將之前創建的Kubernetes服務映射到Gateway。 我們將使用VirtualService執行此操作。 # VirtualService VirtualService實際上將Kubernetes服務連接到Istio網關。 它還可以執行更多操作,例如定義一組流量路由規則,以便在主機被尋址時應用,但我們不會深入了解這些細節。 讓我們創建一個aspnetcore-virtualservice.yaml
文件:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: aspnetcore-virtualservice
spec:
hosts:
- "*"
- "*"
gateways: - aspnetcore-gateway
http: - route:
- destination:
host: aspnetcore-service
請注意,VirtualService與特定網關綁定,並定義引用Kubernetes服務的主機。 創建VirtualService:
$ kubectl apply -f aspnetcore-virtualservice.yaml
virtualservice.networking.istio.io "aspnetcore-virtualservice" created
- destination:
測試V1版本APP 我們准備測試我們的應用程序了。 我們需要獲取Istio Ingress Gateway的IP地址:
$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP
istio-ingressgateway LoadBalancer 10.31.247.41 35.240.XX.XXX
當我們在瀏覽器中打開EXTERNAL-IP
時,我們應該看到HelloWorld ASP.NET Core應用程序:
1.png
DestinationRule 在某些時候,你希望將應用更新為新版本。 也許你想分割兩個版本之間的流量。你需要創建一個DestinationRule來定義是哪些版本,在Istio中稱為subset。 首先,更新aspnetcore.yaml文件以使用v2版本的容器定義v2的deployment:
apiVersion: v1
kind: Service
metadata:
name: aspnetcore-service
labels:
app: aspnetcore
spec:
ports:
- port: 8080
name: http
selector:
app: aspnetcore
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: aspnetcore-v1
spec:
replicas: 1
template:
metadata:
labels:
app: aspnetcore
version: v1
spec:
containers:
- name: aspnetcore
image: gcr.io/istio-project-212517/hello-dotnet:v1
imagePullPolicy: Always #IfNotPresent
ports:
- containerPort: 8080
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: aspnetcore-v2
spec:
replicas: 1
template:
metadata:
labels:
app: aspnetcore
version: v2
spec:
containers:
- name: aspnetcore
image: gcr.io/istio-project-212517/hello-dotnet:v2
imagePullPolicy: Always #IfNotPresent
ports:
- containerPort: 8080
創建新的Deployment:
$ kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created
如果使用EXTERNAL-IP刷新瀏覽器,您將看到應用程序的v1和v2版本交替出現:
2.png
3.png
這是符合預期的,因為兩個版本都暴露在相同的Kubernetes服務之后:aspnetcore-service。 如果您想將服務僅指向v2,該怎么辦? 這可以通過在VirtualService中指定subset來完成,但我們需要首先在DestinationRules中定義這些subset。 DestinationRule本質上是將標簽映射到Istio的subset。 創建一個aspnetcore-destinationrule.yaml
文件:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: aspnetcore-destinationrule
spec:
host: aspnetcore-service
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1 - name: v2
labels:
version: v2
創建DestinationRule:
$ kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destinationrule" created
現在你可以從VirtualService來引用v2 subset:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: aspnetcore-virtualservice
spec:
hosts: - "*"
gateways: - aspnetcore-gateway
http: - route:
- destination:
host: aspnetcore-service
subset: v2
更新VirtualService:
$ kubectl apply -f aspnetcore-virtualservice.yaml
virtualservice.networking.istio.io "aspnetcore-virtualservice" configured
如果你現在繼續瀏覽EXTERNAL-IP,您現在應該只能看到應用程序的v2版本。 # ServiceEntry 我想在Istio Routing中提到的最后一件事是ServiceEntry。默認情況下,Istio中的所有外部流量都被阻止。如果要啟用外部流量,則需要創建ServiceEntry以列出為外部流量啟用的協議和主機。我不會在這篇文章中展示一個例子,但你可以在這里閱讀更多相關內容。 希望這篇文章對你有用!如果您想了解更多信息,可以使用codelab系列以下兩部分,其中所有這些概念和更多內容將在逐步的詳細教程中進行說明:
Deploy ASP.NET Core app to Google Kubernetes Engine with Istio (Part 1)
Deploy ASP.NET Core app to Google Kubernetes Engine with Istio (Part 2)
原文鏈接:Istio Routing Basics(翻譯:kelvinji2009)
- destination: