iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
DevOps

學會 Kubernetes 然後呢?由 Istio 進入 DevOps 偉大航路系列 第 15

Day15 - 結合 Ingress 與 Service Mesh 的 Istio Gateway,究竟要如何使用?

  • 分享至 

  • xImage
  •  

前言

上一篇 提到 Istio Gateway 作為 Istio 架構下負責導入外部流量的元件,除了有 Kubernetes Ingress 的功能之外,還能與 Service Mesh 的功能相結合,本篇就來實際操作看看,加深各位對 Istio Gateway 的了解。

安裝 Istio Gateway 到應用程式

本文參考 Istio Getting Started,這次需要在 Bookinfo 應用程式安裝 Istio Gateway,將外部流量導入到服務中,若還沒準備好應用程式,請參考 Day10 的教學,將 Istio 及 Bookinfo Application 環境準備完成,接著就可以依照以下步驟建立 Gateway。
https://ithelp.ithome.com.tw/upload/images/20220924/20139235o8mE66tsvx.png

建立 Istio Gateway,將外部流量導入 Productage 微服務

  1. 建立 gateway.yaml 檔案
  • gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "ironman2022.istio.com"
  • spec.selector.istio: ingressgateway
    • 使用 Istio Default Gateway 服務
  • spec.servers.port
    • 設定要監聽流量的 Port 以及協定
  • spec.servers.host
    • 設定應用程式的 Domain Name
  1. 使用 gateway.yaml 建立 Istio gateway
kubectl apply -f gateway.yaml
kubectl get gateway

(輸出結果)

NAME               AGE
bookinfo-gateway   5m

在 Gateway 設定的只有 Port 及 Domain Name 相關設定,至於要如何 Match 與如何執行 Action,就會在 VirtualService 上做設定。

  1. 建立 virtual-service.yaml 檔案
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "ironman2022.istio.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
  • spec.hosts

    • 要監聽的 Domain Name
  • spec.gateways

    • 要監聽的 Gateway
  • spec.http.match

    • match 規則
  • spec.http.route

    • 若 match 時執行的路由規則

    此 Virtual Service 會監聽 bookinfo-gateway 的流量,若進入流量符合 Match 的其中一條規定,就會將流量導入 productage service 的 9080 port

  1. 使用 virtual-service.yaml 建立 VirtualService
kubectl apply -f virtual-service.yaml
kubectl get virtualService

(輸出結果)

NAME       GATEWAYS               HOSTS                       AGE
bookinfo   ["bookinfo-gateway"]   ["ironman2022.istio.com"]   5m

建立完一組 Gateway 與 VirtualService ,就完成將外部流量轉入內部的準備。

設定 EXTERNAL-IP 與 Domain Name

至於要如何連接至服務,需要透過 istio-ingressgateway 的 EXTERNAL-IP。

  1. 檢查 Istio-gateway 是否有 EXTERNAL-IP
kubectl -n istio-system get service istio-ingressgateway

(輸出結果)

NAME                 TYPE         CLUSTER-IP    EXTERNAL-IP ...
istio-ingressgateway LoadBalancer 10.111.31.188 <pending>   ...

External-IP 欄位為 Pending 狀態,代表還沒有 IP 可以連接

因為我使用的是 Minikube,所以預設是不會分發 IP 給 istio-ingressgateway ,這時就需使用 Minikube Tunnel 讓 istio-ingressgateway 取得 External-IP

  1. 設定 Minikube Tunnel
minikube tunnel

(輸出結果)

Status:
        machine: minikube
        pid: 1604696
        route: 10.96.0.0/12 -> 192.168.49.2
        minikube: Running
        services: [istio-ingressgateway]
...

需要開著 Terminal 保持 tunnel 功能開啟

  1. 開啟新的 Terminal,檢查 Istio-gateway 是否有 EXTERNAL-IP
kubectl -n istio-system get service istio-ingressgateway

(輸出結果)

NAME                 TYPE         CLUSTER-IP    EXTERNAL-IP    ...
istio-ingressgateway LoadBalancer 10.111.31.188 10.111.31.188  ...

External-IP 欄位有了 IP,可透過此 IP 連接至 Gateway

除了 IP 之外,另外還需要設定好 Domain Name ,讓我們能用 "ironman2022.istio.com" 連接至服務。

  1. 設定 Static Domain Name
sudo vi /etc/hosts

(要修改的內容)

127.0.0.1 localhost
127.0.1.1 myserver
# 在這底下新增 <ingressgateway-ip domain-name>
10.111.31.188 ironman2022.istio.com

# The following lines are desirable for IPv6 capable hosts
...

筆者是在 Linux 環境操作,若是 Windows 用戶,可參考 手動設定網址與 IP 對應的 hosts

  1. 使用 ping 指令檢查 Domain Name 是否設定成功
ping ironman2022.istio.com 

(輸出結果)

PING ironman2022.istio.com (10.111.31.188) 56(84) bytes of data.
From 192.168.49.2 (192.168.49.2) icmp_seq=2 Redirect Host(New nexthop: 1.49.168.192 (1.49.168.192))
From 192.168.49.2 (192.168.49.2) icmp_seq=3 Redirect Host(New nexthop: 1.49.168.192 (1.49.168.192))

若有看到回應訊息代表成功

  1. 使用 curl 連接至服務
curl ironman2022.istio.com/productpage 

也可以在瀏覽器輸入 ironman2022.istio.com/productpage 連接至服務

(輸出結果)

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Bookstore App</title>
<meta charset="utf-8">
...
...
  </body>
</html>

可以看到回傳 html 檔案,代表我們成功使用 Istio Gateway 暴露服務

Gateway 比 Ingress 還多了什麼功能?

看到這裡大家可能會覺得,目前設置的功能與 Ingress 大同小異,那要如何結合 Service Mesh ?其實靠的就是 Virtual Service,我們可以設置各式的路由規則,對流量進行更細緻的管理,這裡要實驗的是針對進入 Productage 外部流量,需要有特定 Header 才能進入。

  1. 修改 virtual-service.yaml 檔案
  • virtual-service.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "ironman2022.istio.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
      headers:
        key:
          exact: ironman
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080

productpage 網站需要 Header 設置 key: ironman 才能進入

  1. 使用 kubectl apply -f <file> 修改 VirtualService 設定
kubectl apply -f virtual-service.yaml
kubectl get virtualService

(輸出結果)

NAME       GATEWAYS               HOSTS                       AGE
bookinfo   ["bookinfo-gateway"]   ["ironman2022.istio.com"]   36m
  1. 使用 curl 連接至服務
curl -v ironman2022.istio.com/productpage

(輸出結果)

...
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
...

沒有 Header ,無法連接至服務

  1. 使用 curl 連接至服務,並帶入參數 -H,在 Header 中設置 "key: ironman"
curl ironman2022.istio.com/productpage -H "key: ironman" 

(輸出結果)

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Bookstore App</title>
<meta charset="utf-8">
...
...
  </body>
</html>

在 Header 設定 "key: ironman" 後,即可成功連線至服務。


上一篇
Day14 -什麼是 Istio Gateway?與 Kubernetes Ingress 有何不同?
下一篇
Day16 - Observability 介紹,Metrics、Tracing 和 Logging 是什麼?
系列文
學會 Kubernetes 然後呢?由 Istio 進入 DevOps 偉大航路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
vulxk2u4210
iT邦新手 5 級 ‧ 2023-12-18 23:43:19

您好,我想請教一下,如何讓EXTERNAL-IP和CLUSTER-IP為同樣一組,因為我連不上所以想請教一下.
https://ithelp.ithome.com.tw/upload/images/20231218/20152727sozUJ27GUe.png
https://ithelp.ithome.com.tw/upload/images/20231218/20152727D0BoBDZkaO.png

我要留言

立即登入留言