系列文章:
總目錄索引:九析帶你輕鬆完爆 istio 服務網格系列教程
目錄
1 前言
2 邀約
3 虛擬服務(Virtual Service)
4 虛擬服務跟 K8s 服務的關係
5 虛擬服務實例
5.1 k8s 資源
5.2 Istio 資源
5.3 Istio 注入
5.4 創建客戶端和客戶端 Istio 注入
1 前言
如果你對博客有任何疑問,請告訴我。
2 邀約
你可以從 b 站搜索 “九析”,獲取免費的、更生動的視頻資料:
3 虛擬服務(Virtual Service)
虛擬服務(Virtual Service)以及目標規則(Destination Rule)是 Istio 流量路由的兩大基石。虛擬服務可以將流量路由到 Istio 服務網格中的服務。每個虛擬服務由一組路由規則組成,這些路由規則按順序進行評估。
如果沒有 Istio virtual service,僅僅使用 k8s service 的話,那麼只能實現最基本的流量負載均衡轉發,但是就不能實現類似按百分比來分配流量等更加複雜、豐富、細粒度的流量控制了。
4 虛擬服務跟 K8s 服務的關係
虛擬服務相當於 K8s 服務的 sidecar,在原本 K8s 服務的功能之上,提供了更加豐富的路由控制。
5 虛擬服務實例
以下介紹使用 “虛擬服務(virtual service)+目標規則(destination rule)” 實現一個流量分流的例子。本示例共需要四種資源,k8s 和 istio 各兩種:
k8s 資源介紹如下:
1 兩個 deployment,一個 tomcat,一個 nginx
2 一個 service 關聯上面這兩個 deployment
Istio 資源介紹如下:
1 一個 destination rule,設置目標規則定義
2 一個 virtual service 關聯上面的 service,用來設置分流權重(weight)和設置分流目標規則定義)
5.1 k8s 資源
k8s 資源共有兩類,分別爲 deployment 和 service,其中 deployment 資源文件明細如下:
# jiuxi-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels:
type: web
app: nginx
template:
metadata:
labels:
type: web
app: nginx
spec:
containers:
- image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
name: port
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deploy
spec:
replicas: 1
selector:
matchLabels:
type: web
app: tomcat
template:
metadata:
labels:
type: web
app: tomcat
spec:
containers:
- image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent
name: tomcat
ports:
- containerPort: 8080
name: port
protocol: TCP
部署上面的 jiuxi-deploy.yaml 文件,語句如下:
kubectl apply -f jiuxi-deploy.yaml
service 資源文件明細如下:
# jiuxi-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
ports:
- name: port
port: 8080
protocol: TCP
targetPort: 8080
selector:
type: web
部署上面的 service 文件,語句如下:
kubectl apply -f jiuxi-svc.yaml
自此,k8s 層面的資源文件準備完畢,現在通過訪問 service,可以發現自動實現了RoundBin的負載均衡策略,即分配到 tomcat 和 nginx 的流量各爲 50%。
5.2 Istio 資源
Istio 資源共有兩類,分別爲虛擬服務(Virtual Service)和目的地規則(Destination Rule)。虛擬服務作用在 k8s 服務之上,並加強了原 k8s 服務的功能:
指定目的地(tomcat 或 nginx)
重新分配流量(即不再是 50% / 50%,而是 75% / 25%)
目的地規則文件 jiux-dr.yaml 如下:
# jiuxi-dr.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: jiuxi-dr
spec:
host: jiuxi-svc
subsets:
- name: tomcat
labels:
app: tomcat
- name: nginx
labels:
app: nginx
上面的目的地資源文件作用在 jiux-svc 這個 k8s 服務上,通過 labels 字段指定不同的 pod,然後通過 name 字段提供給下面的 virtual service,起到關聯到具體 pod 的作用。
如果這裏你不好理解,可以這麼來理解。以前 k8s service 跟 pod 關聯是一維座標關聯,從上面例子可知,nginx 跟 tomcat 對 svc 而言是沒什麼區別的,因爲都是相同的 labels 指定。但是如果採用了 virtual service 和 destination 相當於對 service 後面的 pod 使用了二維座標關聯,這樣就可以明確定義 service 後面的 pod 到底有哪些業務含義了(比如一個是 nginx,另外一個是 tomcat)。這裏大家仔細琢磨一下。
虛擬服務文件 jiuxi-vs.yaml 如下:
# jiuxi-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: jiuxi-virtual-svc
spec:
hosts:
- jiuxi-svc
http:
- route:
- destination:
host: jiuxi-svc
subset: nginx
weight: 25
- destination:
host: jiuxi-svc
subset: tomcat
weight: 75
執行上面這兩個資源文件:
kubectl apply -f jiuxi-dr.yaml
kubectl apply -f jiuxi-vs.yaml
命令執行後的結果如下截圖所示:
5.3 Istio 注入
執行如下命令進行 Istio 注入:
istioctl kube-inject -f jiuxi-deploy.yaml | kubectl apply -f -
因爲 nginx 默認啓動是 80 端口,爲了保持跟 tomcat 端口保持一致,這裏需要登錄到 pod 中修改 nginx 端口,操作方法如下:
# pod 後綴根據實際情況進行修改
kubectl exec -it nginx-deploy-957f689f5-7svdz -- sh
然後編輯 nginx 配置文件:
vi /etc/nginx/conf.d/default.conf
修改內容如下截圖:
5.4 創建客戶端和客戶端 Istio 注入
創建客戶端訪問經過 Istio 流控過的 k8s 服務,客戶端資源文件如下:
# jiuxi-busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: nginx
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 3600" ]
執行如下 Istio 注入命令:
istioctl kube-inject -f jiuxi-busybox.yaml | kubectl apply -f -
Istio 注入成功後,通過 kubectl exec 登錄到 busybox 容器中,然後執行如下語句,驗證 virtual service 和 destination rule 功能:
注意這裏的客戶端也必須經過 Istio 注入,因爲只有客戶端被 Istio 注入,客戶端纔可以接收到來自 Pilot server 端有關 virtual service 和 destination rule 的配置信息,纔可以保證 Istio 的 traffic management 真正生效。
自此,九析帶你輕鬆完爆 Istio virtual service + Destination Rule 功能。