Istio Ingress流量入口配置原理

banq發表於2018-09-02
Istio現在是一項熱門技術。谷歌和IBM等巨頭已經將整個工程師團隊投入到專案中,從而將其推向生產準備階段,最近自從1.0釋出以來,這裡介紹Istio是如何利用Kubernetes的Ingress控制器和服務負載平衡器。

本文介紹Istio的核心概念,就是如何讓外部流量進入你的叢集,需要以下技術:

Minikube 0.28.0
Kubernetes 1.10
Istio 1.0.1

Istio的Gateway型別
Istio有一種名為“Gateway”的資源型別,Istio Gateway告訴k8s的istio-ingressgateway pods可以開啟哪些主機和埠,它這是透過使用Kubernetes創造的標籤選擇器( label selector)模式來實現,讓我們看一下Istio文件中的httpbin閘道器配置:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
<p class="indent">


配置中selector的值是istio: ingressgateway,這裡很有趣,K8s的istio-ingresgateway pod被標記為“istio = ingressgateway”的標籤,這樣可以使用kubectl輕鬆找到它們:

$ kubectl get pod -n istio-system -l istio = ingressgateway -o name 
<p class="indent">

得到結果:
pod/istio-ingressgateway-6fd6575b8b-xls7g
因此,該pod將接收閘道器配置並最終公開開啟相應埠,因為它正好與與Istio Gateway標籤選擇器匹配。太好了!讓我們親眼看看。

Istio會配置Envoy這個主機來接受並路由轉發流量的,Envoy還附帶了一個非常簡單的管理功能,可以直接訪問,Istio是配置Envoy偵聽為15000埠用於管理,這意味著我們可以使用kubectl輕鬆訪問它:

$ kubectl -n istio-system port-forward istio-ingressgateway-6fd6575b8b-tfc7z 15000
<p class="indent">

一旦啟動,我們就可以開啟http:// localhost:15000/listeners並檢視已新增到此pod的監聽器。

這就在Istio的ingress閘道器上開闢了一個埠,但是隻是接受訪問和流量輸入,當流量到達這個閘道器時,它還不知道傳送到哪裡去。

Istio的“VirtualService”型別
現在我們的閘道器已準備好接收流量,我們必須告知它將收到的流量發往何處,Istio使用名為“VirtualService”型別配置流量發往何處。將一個閘道器列表配置給VirtualService,然後Istio使用VirtualService配置中定義的路由再配置那些閘道器,例如,以再次使用httpbin示例:

apiVersion:networking.istio.io/v1alpha3 
kind:VirtualService 
metadata:
  name:httpbin 
spec:
  hosts:
  - “*” 
  gateways:
  -  httpbin-gateway
   http:
  -  match:
    -  uri:
        prefix:/status 
    -  uri:
        prefix:/delay 
    route:
    -  destination:
        port:
          number:8000 
        host:httpbin
<p class="indent">

配置中gateways定義為 httpbin-gateway,這就是將VirtualService配置到指定的閘道器上,然後,URI路徑字首匹配/status的將發往指定目標,URI路徑字首匹配/delay將發往指定目標。

當我們使用此功能時,可以使用Envoy管理功能反覆檢視此情況。開啟http:// localhost:15000/config_dump在輸出的JSON中查詢“routes”部分,如果找到相關定義:

[img index=1]

說明Istio已採用我們的VirtualService定義並將其應用於與名稱匹配的閘道器pod。成功!

透過這一切設定,我們可以使用一個簡單的清單在我們的Kubernetes叢集中安裝HTTPBin專案。配置檔案在github,我們還可以在kubectl上使用方便的port-forward命令來公開我們的httpbin閘道器:

$ kubectl -n istio-system port-forward istio-ingressgateway-6fd6575b8b-tfc7z 80

注意:可能需要使用sudo執行它。

執行此選項後,開啟另一個終端選項卡並嘗試curl訪問:

$ curl -v localhost/status/200
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET /status/200 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< server: envoy
< date: Fri, 31 Aug 2018 16:25:31 GMT
< content-type: text/html; charset=utf-8
< access-control-allow-origin: *
< access-control-allow-credentials: true
< content-length: 0
< x-envoy-upstream-service-time: 2
<
* Connection #0 to host localhost left intact
<p class="indent">


成功!我們的httpbin專案已透過我們的Istio Gateway和VirtualService公開。

總結
1. Gateway: Istio Gateway是負責開啟k8s上相關Istio的pods上的埠並接收主機的流量,是接收流量與路由之間的關鍵連結。

2. VirtualService: Istio VirtualService是“附加”到Gateway上的,並負責定義Gateway應實現的路由。可以將多個VirtualServices連線到Gateway,但不適用於同一個域。


Understanding Istio Ingress – FireHydrant – Medium

相關文章