API gateway 是微服務環境,甚至 service mesh 的要角 1

在 Kubernetes 上面,API gateway 選項眾多。有像 HAProxy 及 Nginx 這些石器時代老傢伙跨足過來,也有打從一開始就走 cloud native 路線的後起之秀。

該如何選擇?

根據 Steven Acreman 寫的 Ingress 評比文章的看法:

The safest choice is ingress-nginx. This is the one that most people use and it’s extremely reliable. Before you begin I’d recommend you read this blog to get ahead of some of the problems you may encounter.

My vote for the coolest ingress definitely goes to Ambassador. If you’re just running standard http based micro services and fancy living on the bleeding edge then you should definitely get Istio, Ambassador and Jaeger setup as a proof of concept.

進一步研讀 Ambassador 相關資料 2,發現他們鎖定的 service mesh 路線很合我的胃口,站在 Envoy 巨人肩膀上更是聰明。不過,理論歸理論,我想親自試試看現在的 Ambassador 是否堪當大任?

初步,我只先拿 ingress-nginx 這個所謂的 “the safest choice” 作簡單的性能比較。將來有機會再進行更徹底的 chaos monkey 測試。

實驗環境

為了簡化實驗步驟,我直接採用 Google Cloud Platform 的 GKE

我選用的標靶軟體是 hello-app,分別用以下兩種 API gateway 來對外提供服務介面:

  • Nginx ingress 版本:0.23.0

  • Ambassador 版本:0.52.0

最後,我利用 boom 進行簡單的壓力測試。

Nginx ingress

為了簡單起見,我直接套用以下這份 Qwiklabs 的全部步驟:

照著做完後,Nginx ingress 會在 GKE 開放一個公開的 http 服務存取點。

我們可以先用 kubectl get services 查看 API gateway 的 public IP 位址。假設是 35.222.12.84 的話,這個服務路徑則是 http://35.222.12.84/hello/

Ambassador

首先,仿造前面的 Qwiklabs 步驟,在 GKE 上建立起相同規模的 k8s cluster。也執行一份 hello-app service

為了安裝 Ambassador,我們需要開啟 GKE 權限:

% kubectl create clusterrolebinding my-cluster-admin-binding  \
    --clusterrole=cluster-admin  \
    --user=$(gcloud info --format="value(config.account)")

接下來,就是正常的 Ambassador 安裝步驟:

% kubectl create -f http://bit.ly/2UmsPuE

此刻,我們終於可以透過 Ambassador,替 hello-app 設定 API gateway 規則:

% kubectl create -f https://bit.ly/2YyZzjO

照著做完後,Ambassador 會在 GKE 開放一個公開的 http 服務存取點。

我們可以先用 kubectl get services 查看 API gateway 的 public IP 位址。假設是 35.224.99.169 的話,這個服務路徑則是 http://35.224.99.169/hello2/

簡單的壓測

為了簡單起見,我在 GCP 的 Cloud Shell 進行壓測。我會對 Nginx ingress 及 Ambassador 兩種情況,各送出一萬個 API 存取要求。

針對 Nginx ingress 的情況進行測試:

% docker run --rm  williamyeh/boom  \
    -n 10000 -c 100  http://35.222.12.84/hello/

Summary:
  Total:        16.2312 secs
  Slowest:      0.3252 secs
  Fastest:      0.1568 secs
  Average:      0.1616 secs
  Requests/sec: 616.0963
  Total data:   660000 bytes
  Size/request: 66 bytes

Status code distribution:
  [200] 10000 responses

Response time histogram:
  0.157 [1]     |
  0.174 [9803]  |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  0.190 [96]    |
  0.207 [0]     |
  0.224 [0]     |
  0.241 [0]     |
  0.258 [0]     |
  0.275 [0]     |
  0.292 [0]     |
  0.308 [0]     |
  0.325 [100]   |

Latency distribution:
  10% in 0.1576 secs
  25% in 0.1583 secs
  50% in 0.1593 secs
  75% in 0.1608 secs
  90% in 0.1632 secs
  95% in 0.1661 secs
  99% in 0.3152 secs

針對 Ambassador 的情況進行測試:

% docker run --rm  williamyeh/boom  \
    -n 10000 -c 100  http://35.224.99.169/hello2/

Summary:
  Total:        16.8132 secs
  Slowest:      0.3857 secs
  Fastest:      0.1571 secs
  Average:      0.1662 secs
  Requests/sec: 594.7715
  Total data:   660000 bytes
  Size/request: 66 bytes

Status code distribution:
  [200] 10000 responses

Response time histogram:
  0.157 [1]     |
  0.180 [9595]  |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  0.203 [304]   |∎
  0.226 [0]     |
  0.249 [0]     |
  0.271 [0]     |
  0.294 [0]     |
  0.317 [0]     |
  0.340 [0]     |
  0.363 [8]     |
  0.386 [92]    |

Latency distribution:
  10% in 0.1596 secs
  25% in 0.1607 secs
  50% in 0.1623 secs
  75% in 0.1656 secs
  90% in 0.1717 secs
  95% in 0.1786 secs
  99% in 0.3596 secs

儘管不夠嚴謹,但仍可以約略看出 Ambassador 的性能已經逼近 Nginx ingress。以才兩歲半的 Envoy 3、才滿兩歲的 Ambassador 4 來說,已經很不容易了。

這是一個值得開始嘗試的好物。


  1. 對於 API gateway 來龍去脈感興趣的,可參考 Ricky 的文章〈Overview API Gateway〉、Andrew 的文章〈架構師觀點 - 轉移到微服務架構的經驗分享 (Part 3)〉。 ↩︎

  2. 對於 Ambassador 早期發展歷程感興趣的,可參考他們寫的這兩篇文章:“Building Ambassador, an Open Source API Gateway on Kubernetes and Envoy” 及 “Kubernetes Ingress 101: NodePort, Load Balancers, and Ingress Controllers”。 ↩︎

  3. Envoy 1.0.0 版發布日期為 2016 年 9 月。 ↩︎

  4. Ambassador 0.1.3 版發布日期為 2017 年 3 月。 ↩︎