五分鐘k8s實戰-Istio 閘道器

2023-11-15 15:01:13

在上一期 k8s-服務網格實戰-設定 Mesh 中講解了如何設定叢集內的 Mesh 請求,Istio 同樣也可以處理叢集外部流量,也就是我們常見的閘道器。

其實和之前講到的k8s入門到實戰-使用Ingress Ingress 作用類似,都是將內部服務暴露出去的方法。

只是使用 Istio-gateway 會更加靈活。

這裡有一張功能對比圖,可以明顯的看出 Istio-gateway 支援的功能會更多,如果是一箇中大型企業並且已經用上 Istio 後還是更推薦是有 Istio-gateway,使用同一個控制面就可以管理內外網流量。

建立 Gateway

開始之前首先是建立一個 Istio-Gateway 的資源:

apiVersion: networking.istio.io/v1alpha3  
kind: Gateway  
metadata:  
  name: istio-ingress-gateway  
  namespace: default  
spec:  
  servers:  
    - port:  
        number: 80  
        name: http  
        protocol: HTTP  
      hosts:  
        - 'www.service1.io'  
  selector:  
    app: istio-ingressgateway #與現有的 gateway 關聯  
    istio: ingressgateway

其中的 selector 選擇器中匹配的 label 與我們安裝 Istio 時候自帶的 gateway 關聯即可。

# 檢視 gateway 的 label
k get pod -n istio-system
NAME                                    READY   STATUS
istio-ingressgateway-649f75b6b9-klljw   1/1     Running

k describe pod istio-ingressgateway-649f75b6b9-klljw -n istio-system |grep Labels
Labels:           app=istio-ingressgateway

這個 Gateway 在我們第一次安裝 Istio 的時候就會安裝這個元件。


這個設定的含義是閘道器會代理通過 www.service1.io 這個域名存取的所有請求。

之後需要使用剛才的 gateway 與我們的服務的 service 進行繫結,這時就需要使用到 VirtualService

apiVersion: networking.istio.io/v1alpha3  
kind: VirtualService  
metadata:  
  name: k8s-combat-istio-http-vs  
spec:  
  gateways:  
    - istio-ingress-gateway # 繫結剛才建立的 gateway 名稱 
  hosts:  
    - www.service1.io
http:
- name: default  
  route:  
    - destination:  
        host: k8s-combat-service-istio-mesh  #service 名稱
        port:  
          number: 8081  
        subset: v1

這個和我們之前講到的 Mesh 內部流量時所使用到的 VirtualService 設定是一樣的。

這裡的含義也是通過 www.service1.io 以及 istio-ingress-gateway 閘道器的流量會進入這個虛擬服務,但所有的請求都會進入 subset: v1 這個分組。

這個的分組資訊在上一節可以查詢到:

apiVersion: networking.istio.io/v1alpha3  
kind: DestinationRule  
metadata:  
  name: k8s-combat-service-ds  
spec:  
  host: k8s-combat-service-istio-mesh  
  subsets:  
    - name: v1  
      labels:  
        app: k8s-combat-service-v1  
    - name: v2  
      labels:  
        app: k8s-combat-service-v2

之後我們存取這個域名即可拿到響應,同時我們開啟 k8s-combat-service-istio-mesh service 的 Pod 檢視紀錄檔,會發現所有的請求都進入了 v1, 如果不需要這個限制條件,將 subset: v1 刪除即可。

curl  http://www.service1.io/ping

本地需要設定下 host: 127.0.0.1 www.service1.io

還有一點,我們需要拿到 gateway 的外部IP,才能將 IP 和剛才的域名www.service1.io 進行繫結(host,或者是域名管理臺)。

如果使用的是 docker-desktop 自帶的 kubernetes 叢集時候直接使用 127.0.0.1 即可,預設就會繫結上。

如果使用的是 minikube 安裝的,那需要使用 minikube tunnel 手動為 service 為LoadBalancer 型別的繫結一個本地 IP,具體可以參考檔案:
https://minikube.sigs.k8s.io/docs/tasks/loadbalancer

如果是生產環境使用,雲服務廠商會自動繫結一個外網 IP。

原理

這個的存取請求的流程和之前講到的 kubernetes Ingress 流程是類似的,只是 gateway 是通過 VirtualService 來路由的 service,同時在這個 VirtualService 中可以自定義許多的路由規則。

總結

服務網格 Istio 基本上講完了,後續還有關於 Telemetry 相關的 tracelogmetrics 會在運維章節更新,也會和 Istio 有所關聯。
感興趣的朋友可以持續關注。

本文的所有原始碼在這裡可以存取:
https://github.com/crossoverJie/k8s-combat