麼是Envoy Gateway?

Envoy Gateway 是一個用於管理Envoy Proxy 的開源項目,可單獨使用或作為Kubernetes 中應用的網關。它通過了Gateway API 核心一致性測試,使用Gateway API 作為其唯一的配置語言來管理Envoy 代理,支持GatewayClass、Gateway、HTTPRoute和 TLSRoute 資源。

Envoy Gateway 的目標是降低用戶採用Envoy 作為API 網關的障礙,以吸引更多用戶採用Envoy。它通過入口和L4/L7 流量路由,表達式、可擴展、面向角色的API 設計,使其成為供應商建立API 網關增值產品的基礎。

Envoy Gateway 的核心優勢是輕量級、開放、可動態編程,尤其是為後端增加了安全功能,這些優勢使得它很適合作為後端API 網關。

架構
下圖展示的是Envoy Gateway 的架構,圖中的陰影部分錶示是Envoy Gateway。你可以通過靜態和動態兩種方式來配置它,其中的Provider 是針對不同的供應商開發的。

image
在這篇文章中,我們將親身體驗Envoy GatewayGateway API。以下是逐步指導你安裝Envoy Gateway 的說明,以及通過Envoy 代理在集群外公開HTTP 應用程序的簡單用例。

安裝Envoy Gateway

回想一下,Envoy Gateway 是由新的Gateway API 配置的,而不是舊的Ingress API。Gateway API 尚未合併到上游Kubernetes,因此我們的集群將無法使用它。我們通過為其部署CRD 來安裝該API。Envoy Gateway 項目提供了一個文件,用於安裝Gateway API 和部署Envoy Gateway。
 
$ kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.2.0/install.yaml
 
這會產生大量資源,我將分幾個部分中討論它們。首先是Gateway API:
 
[root@dev-rancher EnvoyGateway]# kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.2.0/install.yaml
namespace/envoy-gateway-system created
namespace/gateway-system created
customresourcedefinition.apiextensions.k8s.io/envoyproxies.config.gateway.envoyproxy.io created
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io configured
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io configured
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io configured
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencepolicies.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/tcproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/tlsroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/udproutes.gateway.networking.k8s.io created
serviceaccount/certgen created
serviceaccount/envoy-gateway created
serviceaccount/gateway-api-admission created
role.rbac.authorization.k8s.io/certgen created
role.rbac.authorization.k8s.io/infra-manager created
role.rbac.authorization.k8s.io/leader-election-role created
role.rbac.authorization.k8s.io/gateway-api-admission created
clusterrole.rbac.authorization.k8s.io/envoy-gateway-role created
clusterrole.rbac.authorization.k8s.io/gateway-api-admission created
clusterrole.rbac.authorization.k8s.io/metrics-reader created
clusterrole.rbac.authorization.k8s.io/proxy-role created
rolebinding.rbac.authorization.k8s.io/certgen created
rolebinding.rbac.authorization.k8s.io/infra-manager created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
rolebinding.rbac.authorization.k8s.io/gateway-api-admission created
clusterrolebinding.rbac.authorization.k8s.io/gateway-api-admission created
clusterrolebinding.rbac.authorization.k8s.io/envoy-gateway-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/proxy-rolebinding created
configmap/envoy-gateway-config created
service/envoy-gateway created
service/envoy-gateway-metrics-service created
service/gateway-api-admission-server created
deployment.apps/envoy-gateway created
deployment.apps/gateway-api-admission-server created
job.batch/certgen created
job.batch/gateway-api-admission created
job.batch/gateway-api-admission-patch created
validatingwebhookconfiguration.admissionregistration.k8s.io/gateway-api-admission created

 

如你所見,主要是CRD。但請注意,安裝Gateway API 還部署了一些工作負載資源,包括Deployment 等——Gateway API 帶有一個webhook 准入控制器來驗證我們部署的資源,可以使用以下命令查看:
 
[root@dev-rancher EnvoyGateway]# kubectl get pods --namespace gateway-system
NAME                                            READY   STATUS              RESTARTS   AGE
gateway-api-admission-bvptn                     0/1     Completed           0          7s
gateway-api-admission-patch-l967z               0/1     Completed           0          6s
gateway-api-admission-server-5bf65c669b-67sjq   0/1     ContainerCreating   0          8s

 

添加到集群API 中的新CRD:
 
[root@dev-rancher EnvoyGateway]# kubectl api-resources | grep gateway.networking
gatewayclasses                    gc                 gateway.networking.k8s.io/v1beta1       false        GatewayClass
gateways                          gtw                gateway.networking.k8s.io/v1beta1       true         Gateway
httproutes                                           gateway.networking.k8s.io/v1beta1       true         HTTPRoute
referencegrants                   refgrant           gateway.networking.k8s.io/v1alpha2      true         ReferenceGrant
referencepolicies                 refpol             gateway.networking.k8s.io/v1alpha2      true         ReferencePolicy
tcproutes                                            gateway.networking.k8s.io/v1alpha2      true         TCPRoute
tlsroutes                                            gateway.networking.k8s.io/v1alpha2      true         TLSRoute
udproutes                                            gateway.networking.k8s.io/v1alpha2      true         UDPRoute
 
下面是Envoy Gateway 本身。
 
namespace/envoy-gateway-system created
customresourcedefinition.apiextensions.k8s.io/envoyproxies.config.gateway.envoyproxy.io created
serviceaccount/envoy-gateway created
role.rbac.authorization.k8s.io/leader-election-role created
clusterrole.rbac.authorization.k8s.io/envoy-gateway-role created
clusterrole.rbac.authorization.k8s.io/metrics-reader created
clusterrole.rbac.authorization.k8s.io/proxy-role created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/envoy-gateway-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/proxy-rolebinding created
configmap/envoy-gateway-config created
service/envoy-gateway created
service/envoy-gateway-metrics-service created
deployment.apps/envoy-gateway created
 
這些是工作負載資源以及相關的安全和網絡。片刻之後,我們可以看到正在運行的控制器:
[root@dev-rancher EnvoyGateway]# kubectl get pods --namespace envoy-gateway-system
NAME                             READY   STATUS    RESTARTS   AGE
envoy-gateway-6bd456488c-jf8zx   2/2     Running   0          3m

安裝測試應用

我們還需要一些東西讓網關真正將流量轉發到—— 就像我們的一個應用程序一樣的東西。我們可以使用httpbin,Envoy Gateway 項目提供了方便的清單。
[root@dev-rancher EnvoyGateway]# kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
這將在默認命名空間中運行:
 
[root@dev-rancher EnvoyGateway]# kubectl get pods -n default | grep httpbin
httpbin-847f64cc8d-mxl6v                                          1/1     Running   0              26m

配置Envoy Gateway

現在我們可以繼續配置Envoy Gateway 以執行一些請求路由。我們需要做的第一件事是註冊我們剛剛部署的Envoy Gateway 控制器,以便其他資源可以引用它來識別配置的網關,以防你在一個集群中部署多個網關。controllerName字段匹配控制器向其運行的Kubernetes 集群註冊的值。
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
  name: my-envoy-gateway
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

我們可以看到關於這個新實例的一些有限信息,假設我們的描述是有效的,我們將看到ACCEPTED: True。

 
接下來,讓我們配置一個Gateway 對象—— 這將打開我們希望Envoy 代理監聽的網絡端口。對於這個簡單的演示,我們將綁定到一個端口而不使用TLS,因此我將其稱為“不安全端口”。
 
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: insecure-port
spec:
  gatewayClassName: my-envoy-gateway
  listeners:
    - name: http
      protocol: HTTP
      port: 8080
EOF
當我們檢查它時,我們會發現它並沒有就緒。由於我們使用的本地開發集群無法使這種雲負載均衡器成為“真正的” 負載均衡器(因此地址字段也是空的),因此該批准被擱置。不用擔心這個,它仍然可以正常工作。

最後,我們可以為一些HTTP 流量設置路由。在這個簡單的示例中,我們匹配任何路徑上對vhostwww.example.com的任何請求,並將其發送到我們之前部署的httpbin 實例。
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: httpbin
spec:
  parentRefs: [ {name: insecure-port} ]
  hostnames: ["www.example.com"]
  rules:
    - matches:
        - path: {type: PathPrefix, value: /}
      backendRefs:
        - {group: "", kind: Service, name: httpbin, port: 8000, weight: 1}
EOF

檢查這種資源目前並沒有向我們展示太多東西,但我們可以看到它至少已部署成功。

 
最後要注意的一件事是,直到現在才真正啟動了Envoy 的實例(之前它只是控制器,它本身並不處理流量)。這是代表Envoy Gateway 的優化:代理的懶創建。檢查系統上的 age字段,看看它的創建時間。
 
[root@dev-rancher EnvoyGateway]# kubectl get pods -n envoy-gateway-system
NAME                                                   READY   STATUS    RESTARTS   AGE
envoy-default-insecure-port-64656661-5dbf74d87-gqts9   1/1     Running   0          5m47s
envoy-gateway-6bd456488c-jf8zx                         2/2     Running   0          16

測試流量

[root@dev-rancher EnvoyGateway]# kubectl get svc -n envoy-gateway-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
envoy-default-insecure-port-64656661 LoadBalancer 10.43.190.253 192.168.1.157 8080:30978/TCP 26m
envoy-gateway ClusterIP 10.43.192.54 <none> 18000/TCP 36m
envoy-gateway-metrics-service ClusterIP 10.43.155.250 <none> 8443/TCP 36m

curl --header "Host: www.example.com" 192.168.1.157:8080/headers
回應如下

{
  "headers": {
    "Accept": "*/*", 
    "Host": "www.example.com", 
    "User-Agent": "curl/7.29.0", 
    "X-Envoy-Expected-Rq-Timeout-Ms": "15000"
  }
}

 

By tony

自由軟體愛好者~喜歡不斷的思考各種問題,有新的事物都會想去學習嘗試 做實驗並熱衷研究 沒有所謂頂天的技術 只有謙虛及不斷的學習 精進專業,本站主要以分享系統及網路相關知識、資源而建立。 Github http://stnet253.github.io

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料