API Gateway作為成熟的雲產品,已經整合了非常豐富的接入能力。將API Gateway作為Kubernetes叢集應用的接入服務使用,將大大提高Kubernetes叢集的服務能力,並可以作為大型互連網應用的標準架構。本文介紹API Gateway如何作為Kubernetes叢集的接入層。
概述
Kubernetes 叢集介紹
Kubernetes(k8s)已經成為主流的自動化容器平台,因其開源性而備受讚譽。Kubernetes在容器技術的基礎上,增加調度和節點叢集間擴充能力,可以非常輕鬆地讓你快速建立一個企業級容器應用叢集,這個叢集主要擁有以下能力:
自動化容器的部署和複製
隨時擴充或收縮容器規模
將容器組織成組,並且提供容器間的負載平衡
很容易地升級應用程式容器的新版本
提供容器彈性,如果容器失效就替換它
API Gateway作為Kubernetes叢集的接入層架構
我們可以看到Kubernetes叢集是可以作為應用服務的,但是Kubernetes叢集沒有足夠的接入能力,特別是在大型應用中,它是不能夠直接對使用者提供服務的,否則會有非常大的安全風險。將API Gateway放在Kubernetes叢集前面作為應用叢集的接入服務使用,可以作為標準的大型互連網應用的標準架構。下面是使用阿里雲架構圖:

是否啟用Ingress Control?
從架構圖中我們可以看到,API Gateway作為Kubernetes叢集的橋頭堡,負責處理所有用戶端的接入及安全工作,API Gateway和Kubernetes叢集中Ingress Control的內網CLB或者服務的內網CLB進行通訊。具體什麼時候用Ingress Control呢?如果Kubernetes叢集內只有一個服務,網關直接和此服務關聯的內網CLB進行通訊最高效。如果Kubernetes叢集內有多個服務,如果使用服務的內網CLB對網關提供服務,將會產生很多CLB,資源管理起來會比較麻煩,此時我們可以使用Ingress Control做Kubernetes中服務發現與七層代理工作,API Gateway的所有請求發送到Ingress Control關聯的內網CLB上,由Ingress Control將請求分發到Kubernetes叢集內的容器內,這樣我們也只需要一個內網CLB就能將Kubernetes叢集內的所有服務暴露出去了。
API Gateway接入能力
接入了API Gateway具體能為整個架構帶來哪些好處呢?下面我們列一下這種架構中,API Gateway具體能給整個應用帶來什麼價值。
API Gateway允許用戶端和API Gateway使用多種協議進行通訊,其中包括:
* HTTP * HTTP2API Gateway使用多種方法保證和用戶端之間的通訊安全:
* 允許定義API和APP之間的授權關係,只有授權的APP允許調用; * 全鏈路通訊都使用簽名驗證機制,包括用戶端和API Gateway之間的通訊和API Gateway和後端服務之間的通訊,保證請求在整個鏈路上不會被篡改; * 支援使用者使用自己的SSL認證進行HTTPS通訊; * 支援OPENID CONNECT;API Gateway具備iOS/Android/Java三種SDK的自動產生能力,並且具備API調用文檔自動產生能力。
API Gateway支援入參混排能力,請求中的參數可以映射到後端請求中的任何位置。
API Gateway提供參數清洗能力,使用者定義API的時候可以指定參數的類型,正則等規則,API Gateway會幫使用者確認傳輸給後端服務的請求是符合規則的資料。
API Gateway支援流量控制能力,支援的維度為使用者/APP/API。
API Gateway提供基於請求數/錯誤數/應答逾時時間/流量監控警示能力,所有的警示資訊會使用簡訊或者郵件在一分鐘內發出。
API Gateway已經和阿里雲的SLS產品打通,使用者可以將所有請求日誌自動上傳到使用者自己的SLS中,以便後續更好地對訪問日誌進行統計分析。
API Gateway支援Mock模式,在聯調中這個能力非常方便。
API Gateway支援使用者配置調用方的IP白名單和黑名單。
API Gateway結合阿里雲的雲市場,為Provider提供向API使用者收費的能力。
阿里雲的API Gateway是一個上線數年的成熟雲產品,在穩定性和效能方面,經過了時間和阿里雲的工程師的不斷打磨,適用於有高效能需求的使用者。
快速配置Kubernetes叢集和API Gateway
阿里雲支援快速建立Kubernetes叢集,同一個Region內的Kubernetes叢集和API Gateway的整合也非常簡單。在API Gateway作為Kubernetes叢集的接入層架構設計中,API Gateway和Kubernetes有兩種結合的模式:
方式一:API Gateway將請求發送到Ingress Control前的CLB,由Ingress Control將請求路由到Kubernetes對應的節點中。只需要Ingress Control前有一個CLB就可以了,由Ingress Contro做服務發現與路由。
方式二:API Gateway直接將請求發送到Kubernetes中服務前的CLB,由CLB直接將請求轉寄到Kubernetes中服務對應的節點中。每個服務前都需要申請一個CLB,適合并發量大的情境。
方式一:Ingress Control模式的配置
建立Kubernetes叢集並安裝Ingress
建立ACK 託管版叢集或ACK Serverless叢集時,在組件配置階段的Ingress參數配置地區,選擇安裝ALB Ingress。關於建立叢集,請參見建立ACK託管叢集或建立ACK Serverless叢集。

在叢集內建立一個多容器的服務
我們需要在叢集內建立一個服務,這個服務由2個容器組成,每個容器都由Nginx鏡像產生。容器的連接埠是80,Ingress Control提供服務的連接埠是80。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在無狀態頁面,單擊使用YAML建立資源,輸入下面的Resource Orchestration Service文本單擊建立。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: nginx sessionAffinity: None type: NodePort說明編排模板YAML文本解釋如下:
使用Nginx鏡像建立兩個容器,容器的服務連接埠是80,並且建立一個命名為nginx-service的服務,對外服務的連接埠為80,映射到容器80的連接埠。
每個容器上面跑著一個Nginx。這兩個容器組成一個無狀態應用,並且組成了一個命名為nginx-service的服務。可以進入無狀態應用詳情頁面看到整個應用的運行情況。目前API Gateway不能訪問到這個服務,需要在Ingress Control上建立一條到這個服務的路由才能把全鏈路打通。
在Ingress Control上給服務配置路由
應用有了,還需要在Ingress Control上為這個應用建立一個服務,然後在服務上建立一條路由,這樣API Gateway將請求發送給Ingress Control時,Ingress Control會根據配置的路由資訊將請求代理到對應的應用節點上。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
單擊建立 Ingress按鈕,在建立 Ingress頁面的規則地區,填寫網域名稱,配置路徑映射參數並單擊確定。

對Ingress Control的內網CLB授權
API Gateway如果要訪問Ingress Control的內網CLB,需要在API Gateway控制台上增加VPC網路的授權。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在路由頁面複製端點資訊。

- 登入應用型負載平衡ALB控制台。
在左側導覽列選擇概覽,在資源清單處搜尋複製的端點資訊,單擊搜尋到的ALB執行個體。

在ALB執行個體詳情頁面,複製VPC網路ID和ALB執行個體的DNS 名稱。

登入API Gateway控制台,選擇地區並在左側導覽列選擇API管理 > VPC授權。
在授權列表頁面,單擊右上方建立授權。
在建立VPC授權頁面,輸入VPC授權名稱、VPC Id、執行個體Id或地址、連接埠號碼,單擊確定。

建立API
登入API Gateway控制台,選擇地區並在左側導覽列選擇API管理 > 分組管理。
在分組列表頁面下,單擊所建立的目標分組操作列下的API管理。
在API列表頁面,單擊右上方建立API。
在建立API頁面的基本資料欄,配置如下基本資料,單擊下一步。

在定義API請求欄,配置如下資訊,單擊下一步。

在定義API後端服務欄,配置如下資訊,單擊下一步。
重要建立API頁面的常量參數添加一個名字為host,位置header的參數,參數值設定為Ingress Control上給服務配置路由的網域名稱。
在定義返回結果欄,單擊建立。
在建立成功之後彈框中單擊發布。
在發布彈框中發布的環境選擇線上,輸入請填寫變更備忘,單擊發布。
調用測試
API發布到線上就可以使用API Gateway的測試載入器進行測試,查看能否將請求發送到剛才建立的Kubernetes叢集中去。
登入API Gateway控制台,在左側導覽列選擇API調用 > 調試。
在調試頁面選擇,所建立的
nginx-testAPI,然後單擊發送請求,即可看到如下圖資訊說明配置成功。
方式二:Kubernetes服務內網CLB結合模式的配置
本節主要描述建立攜帶內網CLB的Kubernetes服務。
建立Kubernetes叢集
建立ACK 託管版叢集或ACK Serverless叢集,請參見建立ACK託管叢集或建立ACK Serverless叢集。
在叢集內建立一個多容器的服務
有了Kubernetes叢集,現在我們通過Resource Orchestration Service文本在這個叢集中建立帶有內網CLB的服務。本段Resource Orchestration Service代碼和方式一中的Resource Orchestration Service代碼不同的是,我們把最後一行的Type變成了LoadBalancer,並且指定了這個CLB LoadBalancer為內網。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在無狀態頁面,單擊使用YAML建立資源,輸入下面的Resource Orchestration Service文本並單擊建立。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service annotations: service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancer說明編排模板YAML文本解釋是:使用Nginx鏡像建立兩個容器,容器的服務連接埠是80,並且建立一個命名為nginx-service的服務,這個服務前有一個內網CLB,對外服務的連接埠為80,映射到容器80的連接埠。
對Kubernetes叢集中服務的內網CLB授權
我們成功建立了一個攜帶內網CLB的服務,可以在Kubernetes控制台的網路菜單的服務子頁面找到這個內網CLB的內網IP。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在服務頁面找到外部 IP 位址(External IP)列下的地址。

- 登入應用型負載平衡ALB控制台。
在左側導覽列選擇概覽,在資源清單處搜尋複製的外部 IP 位址,單擊搜尋到的CLB執行個體。

在CLB執行個體詳情頁面,複製VPC網路ID和CLB執行個體ID。

登入API Gateway控制台,選擇地區並在左側導覽列選擇API管理 > VPC授權。
在授權列表頁面,單擊右上方建立授權。
在建立VPC授權頁面,輸入VPC授權名稱、VPC Id、執行個體Id或地址、連接埠號碼,單擊確定。

建立API
登入API Gateway控制台,選擇地區並在左側導覽列選擇API管理 > 分組管理。
在分組列表頁面下,單擊所建立的目標分組操作列下的API管理。
在API列表頁面,單擊右上方建立API。
在建立API頁面的基本資料欄,配置如下基本資料,單擊下一步。

在定義API請求欄,配置如下資訊,單擊下一步。

在定義API後端服務欄,配置如下資訊,單擊下一步。

在定義返回結果欄,單擊建立。
在建立成功之後彈框中單擊發布。
在發布彈框中發布的環境選擇線上,輸入請填寫變更備忘,單擊發布。
調用測試
API發布到線上就可以使用API Gateway的測試載入器進行測試,查看能否將請求發送到剛才建立的Kubernetes叢集中去。
登入API Gateway控制台,在左側導覽列選擇API調用 > 調式。
在調試頁面選擇,所建立的
nginx-test-2API,然後單擊發送請求,即可看到如下圖資訊說明配置成功。
配置總結
我們描述了在阿里雲的公用雲端如何建立一整套API Gateway加Kubernetes的流程,關鍵點在於Kubernetes叢集通過Ingress Control元件服務發現,在API Gateway對Ingress Control組件的內網CLB進行授權後,將所有請求發送到CLB上。下面我們再總結一下通過Ingress結合API Gateway與Kubernetes的步驟:
建立一個帶有Ingress Control組件的Kubernetes的叢集。
使用Resource Orchestration Service命令,在Kubernetes叢集中建立兩個啟動並執行Nginx的容器,並且基於這兩個容器建立對應的服務。
在控制台上給Ingress Control加上一條服務路由。
到CLB控制台找到Ingress Control內網CLB的執行個體ID和VPC ID,在API Gateway控制台建立一個VPC授權。
在API Gateway控制台建立API,後端服務使用剛才建立的VPC授權,並且設定一個名為host的參數,參數值使用Ingress Control服務路由設定的網域名稱。API的請求將發送到Kubernetes叢集的Ingress Control的CLB上,由Ingress Control將請求路由到容器內部的Nginx服務上。
在高並發情境或者只有一個服務的情境,我們可以跳過Ingress Control,直接在服務前面架設一個內網CLB,並且將這個內網CLB授權給API Gateway,供API Gateway進行訪問。
Ingress Control和CLB兩種方案對比
使用CLB+Ingress Control。Ingress Control可以做Kubernetes叢集的服務發現和七層代理工作,如果Kubernetes叢集中有多個服務,可以統一使用Ingress Control進行路由,同時只需要一個內網CLB就可以對外暴露多個服務,便於營運管理和Kubernetes叢集的服務擴充。推薦使用此種方式。
直接使用CLB。如果叢集中某個服務的業務壓力很大,可以考慮為此服務單獨建立一個CLB,API Gateway直接連接此CLB,從而達到更高的通訊效率。此種方式的弊端也比較明顯,如果Kubernetes叢集內有多個服務,需要為每個服務配置一個CLB,因此給營運管理帶來較大的工作量。
總結
我們描述了Kubernetes叢集和API Gateway的各項能力,並且畫出了結合它倆作為後端應用服務生產的架構圖。我們結合API Gateway和Kubernetes叢集的架構,讓系統具備了動態伸縮,動態路由,支援多協議接入,SDK自動產生等各項能力,成為可用性更高,更靈活更可靠的一套架構。