Tetrate Enterprise Gateway(TEG)是基于 Envoy Gateway (EG) 的企业级解决方案,专门针对 Envoy Proxy 设计,通过 Kubernetes Gateway API 提供更易于消费的 Envoy 代理配置和管理包。TEG 结合了 Kubernetes Gateway API 的特性,支持在 Kubernetes 中轻松暴露服务和应用程序。
TEG 相对于 Envoy Gateway 的主要新增特性包括:
mod_security
兼容的 WAF 功能,增强了安全防护能力。TEG 将 Envoy 的高级网络流量处理能力带入 Kubernetes 环境,提供了一种简化的方法来部署和管理负载平衡、API 网关功能、安全控制等,同时支持现代的、开放的应用程序暴露 API,如 Kubernetes Gateway API。这些特性使 TEG 成为一个功能丰富、易于管理的企业级网关解决方案。
Tetrate Enterprise Gateway for Envoy (TEG) 构建于 Envoy Gateway 项目之上,提供了一种易于使用和操作的入口,具有先进的按请求流量控制功能、与现有环境的轻松集成,以及一流的可观测性,以理解应用流量和入口健康状况。
TEG 从头到尾注重易用性:从首次安装到启用应用团队,从故障排查到执行升级。TEG 的初始安装只需几分钟,你就可以开始使用高级功能,如速率限制、单点登录和金丝雀流量路由。TEG 还简化了运维流程,与你现有的指标、跟踪和日志记录管道相适应,我们还提供了一个完整的、预配置的可观测性堆栈,以评估 EG 产生的数据,并帮助你计划如何将 TEG 集成到你的现有指标堆栈中。
TEG 由在生产环境中运行大型、关键系统的经验丰富团队构建。TEG 简化了漏洞检查和持续升级过程,与你现有的指标和跟踪提供商轻松集成,并为你现有的 Grafana 部署提供了一套强大的入口可观测性仪表板。
TEG 不仅适用于绿地部署的启动,还可以直接与传统环境以及现代云原生环境集成。它可以帮助你在现有的应用生态系统和你正在构建的云原生目标之间架起桥梁。
你的组织可能已经有一个可观测性系统,你的应用和运营团队已经训练有素地使用它。TEG 可以轻松地嵌入到现有的基础设施中,并在你的组织中运行。TEG 将使 Envoy 的丰富指标集导出,让你的应用团队对其应用流量的行为有最佳的洞察,并看到他们所做配置更改的效果。TEG 还为运行它的平台团队提供了仪表板和警报功能,使你能够自信地操作并快速解决发现的问题。
Envoy 非常强大,但要使其启动并运行简单用例可能很难——像 Istio 这样的系统提供 Envoy 入口管理作为更广泛功能套件的一部分,也附带了许多与简单、流畅的操作体验相冲突的额外功能。这就是 Envoy Gateway 存在的原因:使 Envoy 的强大功能易于用于入口用例。
组织中绝大多数 API 网关的使用归结为三件事:认证发起请求的用户;限制用户对服务的访问;在此 API 端点的服务实例之间进行负载平衡。TEG 简化了在传统和云原生环境中完成这三项任务的过程。
下图展示的是 TEG 的架构图。
从架构图中可以看出,Tetrate Enterprise Gateway for Envoy (TEG) 的架构设计包括以下主要组件和流程:
Kubernetes Cluster
Envoy Proxy
Coraza WAF
Redis Rate Limit Store
Your OIDC Server
流量入口
Envoy Proxy 处理
安全和认证
速率限制
性能监控
这种架构设计利用了 Kubernetes 的灵活性和扩展性,并通过 Envoy 提供了强大的流量管理和安全功能。
执行下面的命令部署 TEG V0.0.0:
export REGISTRY="oci://docker.io/tetrate"
export CHART_VERSION="v0.0.0-latest"
helm install teg ${REGISTRY}/teg-envoy-gateway-helm \
--version ${CHART_VERSION} \
-n envoy-gateway-system --create-namespace
检查部署:
kubectl get pod -n envoy-gateway-system
你将看到下面的结果:
NAMESPACE NAME READY STATUS RESTARTS AGE
envoy-gateway-system envoy-gateway-596dfbcb88-tx7xb 1/1 Running 0 3m55s
envoy-gateway-system envoy-ratelimit-674b8c955c-jhlfn 2/2 Running 2 (3m48s ago) 3m54s
envoy-gateway-system teg-envoy-gateway-64fd8c8fbb-59b4l 1/1 Running 0 3m55s
envoy-gateway-system teg-redis-86bb7d9b9d-27n44 1/1 Running 0 3m55s
部署示例应用:
kubectl create namespace httpbin
kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
部署 Envoy Proxy:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: dedicated-gateway
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: http
protocol: HTTP
port: 80
EOF
然后你会在 envoy-gateway-system
命名空间下看到一个新的 Envoy 代理。
部署 HTTPRoute,给网关配置路由:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: dedicated-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /httpbin/
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- group: ""
kind: Service
name: httpbin
port: 8000
EOF
这个路由配置中有一个 URLRewrite filter,重写 URL 前缀,去掉了 /httpbin/
部分。
发送流量测试:
export DEDICATED_GATEWAY_IP=$(kubectl get gateway/dedicated-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')
curl -i http://${DEDICATED_GATEWAY_IP}/httpbin/get
/httpbin/get
?
在通过 Tetrate Enterprise Gateway for Envoy (TEG) 暴露 httpbin
应用时,选择 /httpbin/get
作为访问路径的原因主要是为了在同一个 Envoy 网关下能够同时支持多个应用或服务,并能根据不同的路径将流量正确地路由到指定的服务。
这种路径前缀的设置方法允许系统管理员或开发人员为每个服务配置独立的路径前缀,从而通过单一的入口点(即 Envoy 网关)来管理对多个后端服务的访问。这样的配置增加了路由的灵活性,使得在不更改现有服务配置的情况下,轻松地扩展或修改服务的暴露方式。
Istio 提供了成熟且灵活的入口网关支持,基于与 Tetrate Enterprise Gateway(TEG)相同的 Envoy 代理。Istio 主要专注于处理集群内服务之间的通信。相较之下,TEG 设计用于向外界暴露应用,处理人类用户的请求,并支持如 OIDC 单点登录等高级功能。通过结合 Istio 网格和 TEG 的高级网关功能,两者可以共同使用,以提升整体应用的可访问性和安全性。
以下图示展示了 Istio 网格中入口网关的流量路径。
下图展示了在引入 TEG 之后,流量如何从 Istio 网格边缘进入到内部。
将 TEG 集成到 Istio 网格中,通过在 TEG 上配置 sidecar 来颁发证书,同时避免 sidecar 拦截 TEG 中的流量。然后通过 Envoy Gateway 控制入口网关的流量路径。
为了使 TEG 作为 Istio 的入口网关,应注意以下关键点:
Service
而非 Endpoint
,确保 Envoy 代理能正确找到路由。为 TEG 的命名空间添加标签,以确保数据平面获得 Istio sidecar 的注入。
kubectl label namespace envoy-gateway-system --overwrite=true istio-injection=enabled
我们还需要配置 TEG 的 sidecar,使其不处理进入网关的 Envoy 流量。注入 sidecar 的目的是使 Envoy Gateway 的组件及其创建的代理能够被纳入 Istio 网格,并挂载正确的证书进行安全通信。
spec:
ports:
- port: 18000
appProtocol: tls
kubectl patch service -n envoy-gateway-system envoy-gateway \
--type strategic --patch-file control-plane-tls.yaml
配置 Envoy Gateway 中的 sidecar 不拦截流量:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: data-plane-sidecars
namespace: envoy-gateway-system
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
annotations:
traffic.sidecar.istio.io/includeInboundPorts: ""
routingType: Service
kubectl apply -f teg-sidecars-no-inbound.yaml
修改 GatewayClass 的配置,将上述 sidecar 配置应用到 Envoy Gateway 数据平面的所有 EnvoyProxy
上:
spec:
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
namespace: envoy-gateway-system
name: data-plane-sidecars
kubectl patch gatewayclass teg --patch-file gtwcls-use-envoyproxy.yaml --type merge
使用 minimal profile 部署 Istio,从而不部署 Ingress Gateway:
istioctl install --set profile=minimal -y
现在 Istio 的 sidecar 注入已准备就绪,我们将重启所有 TEG 控制平面 Pod,它们将带有 sidecar 重新启动。
for d in envoy-gateway envoy-ratelimit teg-envoy-gateway teg-redis; \
do kubectl rollout restart deployment -n envoy-gateway-system $d; \
done
此步应在安装 Istio 之后进行,以确保它们也获得 sidecar 的注入。
kubectl create namespace httpbin
kubectl label namespace httpbin --overwrite=true istio-injection=enabled
kubectl apply -n httpbin -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml
现在我们配置 TEG 处理边缘流量。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: http
protocol: HTTP
port: 80
kubectl apply -f apps-gateway.yaml
部署应用网关,包含以下容器:
istio-init
:由 Istio 注入,负责修改 pod 中的 iptablesenvoy
:由 TEG 控制,作为入口网关istio-proxy
:由 Istio 注入,负责与集群内部 pod 联系shutdown-manager
:由 TEG 控制,负责 Pod 启停创建 HTTP 路由:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: apps
hostnames:
- "www.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /httpbin/
filters:
- type: URLRewrite
urlRewrite:
hostname: httpbin.httpbin.svc.cluster.local
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- kind: Service
name: httpbin
port: 8000
kubectl apply -f httpbin-route.yaml
获取网关的负载均衡器 IP 地址,并发送测试请求:
export GATEWAY_URL=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=apps -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
curl -v -H Host:www.example.com http://$GATEWAY_URL/httpbin/get
你将看到来自 httpbin
服务的正确响应,如下所示:
* Trying 34.41.0.90:80...
* Connected to 34.41.0.90 (34.41.0.90) port 80
> GET /httpbin/get HTTP/1.1
> Host:www.example.com
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< server: envoy
< date: Wed, 31 Jul 2024 08:21:58 GMT
< content-type: application/json
< content-length: 282
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 11
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "www.example.com",
"User-Agent": "curl/8.7.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-External-Address": "123.120.227.173"
},
"origin": "123.120.227.173",
"url": "http://www.example.com/get"
}
* Connection #0 to host 34.41.0.90 left intact
运行下面的命令启用严格的 mTLS:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: STRICT
kubectl apply -f strict-mtls.yaml
创建用于服务签名的根证书和私钥:
mkdir example_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
为 www.example.com
创建证书和私钥:
openssl req -out example_certs/www.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/www.example.com.key -subj "/CN=www.example.com/O=www organization"
openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/www.example.com.csr -out example_certs/www.example.com.crt
为入口网关创建 secret:
kubectl create -n httpbin secret tls httpbin-credential \
--key=example_certs/www.example.com.key \
--cert=example_certs/www.example.com.crt
配置入口网关:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apps
namespace: httpbin
spec:
gatewayClassName: teg
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: httpbin-credential
kubectl apply -f tls-apps-gateway.yaml
发送测试请求:
curl -v -H Host:www.example.com --resolve "www.example.com:443:$GATEWAY_URL" \
--cacert example_certs/example.com.crt "https://www.example.com:443/httpbin/get"
你将可以通过 HTTPS 访问网格内的 httpbin
服务。
Tetrate Enterprise Gateway 为企业提供了一种强大的网关解决方案,能够在云原生环境中高效地暴露和管理应用服务。通过其基于 Envoy 的架构和对 Kubernetes Gateway API 的支持,TEG 不仅确保了高性能的流量管理,还大幅简化了网关的部署和维护。无论是面对复杂的安全需求还是高流量的业务场景,TEG 都能提供可靠的支持,帮助企业实现其业务连续性和技术创新。
最后更新于 2024/09/06