This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

任务

通过任务学习 Envoy Gateway 实践。

1 - 快速入门

只需几个简单的步骤即可开始使用 Envoy Gateway。

本指南将帮助您通过几个简单的步骤开始使用 Envoy Gateway。

前置条件

一个 Kubernetes 集群。

注意: 请参考兼容性表格来查看所支持的 Kubernetes 版本。

注意: 如果您的 Kubernetes 集群没有负载均衡器实现,我们建议安装一个 ,以便 Gateway 资源能够关联一个地址。我们推荐使用 MetalLB

安装

安装 Gateway API CRD 和 Envoy Gateway:

helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespace

等待 Envoy Gateway 至可用后:

kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available

安装 GatewayClass,Gateway,HTTPRoute 和示例应用:

kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n default

注意:quickstart.yaml 定义了 Envoy Gateway 将侦听其全局可路由 IP 地址上端口 80 上的流量,以便轻松使用浏览器测试 Envoy Gateway。当 Envoy Gateway 看到它的侦听器使用特权端口(<1024), 它将在内部映射到非特权端口,因此 Envoy Gateway 不需要额外的特权。 了解此映射很重要,当您调试时您可能需要将其考虑在内。

测试配置

获取由示例 Gateway 创建的 Envoy 服务的名称:

export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')

端口转发到 Envoy 服务:

kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &

通过 Envoy 代理,使用 curl 测试示例应用:

curl --verbose --header "Host: www.example.com" http://localhost:8888/get

您还可以通过将流量发送到外部 IP 来测试相同的功能。运行下面的命令可以获取 Envoy 服务的外部 IP 地址:

export GATEWAY_HOST=$(kubectl get svc/${ENVOY_SERVICE} -n envoy-gateway-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

在某些环境中,负载均衡器可能会公开主机名而不是 IP 地址,如果是这样,将上述命令中的 ip 替换为 hostname

使用 curl 来通过 Envoy Proxy 访问示例应用:

curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get

接下来的探索?

在快速开始(本节),您将:

  • 完成 Envoy Gateway 的安装
  • 部署一个后端服务和一个网关
  • 使用 Kubernetes Gateway API 资源 GatewayHttpRoute 配置网关。将网关传入的 HTTP 请求转发到后端服务。

以下是建议的后续任务列表,可指导您探索 Envoy Gateway:

请查看与您使用情况相符的场景下的任务部分。Envoy Gateway 的任务按照流量管理、安全、扩展性、可观察性和运维等分类组织。

清理

请按照本节中的步骤将快速入门中的所有内容卸载。

删除 GatewayClass,Gateway,HTTPRoute 和示例应用:

kubectl delete -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml --ignore-not-found=true

删除 Gateway API CRD 和 Envoy Gateway:

helm uninstall eg -n envoy-gateway-system

接下来

浏览开发者指南 ,了解如何参与项目。

2 - GRPC 路由

GRPCRoute 资源允许用户通过匹配 HTTP/2 流量并将其转发到后端 gRPC 服务器来配置 gRPC 路由。 要了解有关 gRPC 路由的更多信息,请参阅Gateway API 文档

先决条件

按照快速入门中的步骤安装 Envoy Gateway 和示例清单。 在继续之前,您应该能够使用 HTTP 查询示例程序后端。

安装

安装 gRPC 路由示例资源:

kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/grpc-routing.yaml

该清单安装 GatewayClassGateway、Deployment、Service 和 GRPCRoute 资源。 GatewayClass 是集群范围的资源,表示可以被实例化的一类 Gateway。

**注意:**Envoy Gateway 默认被配置为使用 controllerName: gateway.envoyproxy.io/gatewayclass-controller 管理 GatewayClass。

验证

检查 GatewayClass 的状态:

kubectl get gc --selector=example=grpc-routing

状态应反映为 Accepted=True,表示 Envoy Gateway 正在管理 GatewayClass。

Gateway 代表基础设施的配置。创建 Gateway 时,Envoy 代理基础设施由 Envoy Gateway 预配或配置。 gatewayClassName 定义此 Gateway 使用的 GatewayClass 的名称。检查 Gateway 状态:

kubectl get gateways --selector=example=grpc-routing

状态应反映为 Ready=True,表示 Envoy 代理基础设施已被配置。 该状态还提供 Gateway 的地址。该地址稍后用于测试与代理后端服务的连接。

检查 GRPCRoute 的状态:

kubectl get grpcroutes --selector=example=grpc-routing -o yaml

GRPCRoute 的状态应显示 Accepted=True 和引用示例 Gateway 的 parentRefexample-route 匹配 grpc-example.com 的任何流量并将其转发到 yages 服务。

测试配置

在测试到 yages 后端的 GRPC 路由之前,请获取 Gateway 的地址。

export GATEWAY_HOST=$(kubectl get gateway/example-gateway -o jsonpath='{.status.addresses[0].value}')

使用 grpcurl 命令测试到 yages 后端的 GRPC 路由。

grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping

您应该看到以下响应:

{
  "text": "pong"
}

Envoy Gateway 还支持此配置的 gRPC-Web 请求。下面的 curl 命令可用于通过 HTTP/2 发送 grpc-Web 请求。 您应该收到与上一个命令相同的响应。

正文 AAAAAAA= 中的数据是 Ping RPC 接受的空消息(数据长度为 0)的 Base64 编码表示。

curl --http2-prior-knowledge -s ${GATEWAY_HOST}:80/yages.Echo/Ping -H 'Host: grpc-example.com'   -H 'Content-Type: application/grpc-web-text'   -H 'Accept: application/grpc-web-text' -XPOST -d'AAAAAAA=' | base64 -d

GRPCRoute 匹配

matches 字段可用于根据 GRPC 的服务和/或方法名称将路由限制到一组特定的请求。 它支持两种匹配类型:Exact(精准)和 RegularExpression(正则)。

精准

Exact(精准)匹配是默认匹配类型。

以下示例显示如何根据 grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo 的服务和方法名称来匹配请求, 以及如何在我们的部署中匹配方法名称为 Ping 且与 yages.Echo/Ping 匹配的所有服务。

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
  name: yages
  labels:
    example: grpc-routing
spec:
  parentRefs:
    - name: example-gateway
  hostnames:
    - "grpc-example.com"
  rules:
    - matches:
      - method:
          method: ServerReflectionInfo
          service: grpc.reflection.v1alpha.ServerReflection
      - method:
          method: Ping
      backendRefs:
        - group: ""
          kind: Service
          name: yages
          port: 9000
          weight: 1
EOF

保存以下资源并将其应用到您的集群:

---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
  name: yages
  labels:
    example: grpc-routing
spec:
  parentRefs:
    - name: example-gateway
  hostnames:
    - "grpc-example.com"
  rules:
    - matches:
      - method:
          method: ServerReflectionInfo
          service: grpc.reflection.v1alpha.ServerReflection
      - method:
          method: Ping
      backendRefs:
        - group: ""
          kind: Service
          name: yages
          port: 9000
          weight: 1

验证 GRPCRoute 状态:

kubectl get grpcroutes --selector=example=grpc-routing -o yaml

使用 grpcurl 命令测试到 yages 后端的 GRPC 路由。

grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping

正则

以下示例演示如何根据服务和方法名称将请求与匹配类型 RegularExpression 进行匹配。 它与模式 /.*.Echo/Pin.+ 匹配所有服务和方法,该模式与我们部署中的 yages.Echo/Ping 匹配。

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
  name: yages
  labels:
    example: grpc-routing
spec:
  parentRefs:
    - name: example-gateway
  hostnames:
    - "grpc-example.com"
  rules:
    - matches:
      - method:
          method: ServerReflectionInfo
          service: grpc.reflection.v1alpha.ServerReflection
      - method:
          method: "Pin.+"
          service: ".*.Echo"
          type: RegularExpression
      backendRefs:
        - group: ""
          kind: Service
          name: yages
          port: 9000
          weight: 1
EOF

保存以下资源并将其应用到您的集群:

---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
  name: yages
  labels:
    example: grpc-routing
spec:
  parentRefs:
    - name: example-gateway
  hostnames:
    - "grpc-example.com"
  rules:
    - matches:
      - method:
          method: ServerReflectionInfo
          service: grpc.reflection.v1alpha.ServerReflection
      - method:
          method: "Pin.+"
          service: ".*.Echo"
          type: RegularExpression
      backendRefs:
        - group: ""
          kind: Service
          name: yages
          port: 9000
          weight: 1

检查 GRPCRoute 状态:

kubectl get grpcroutes --selector=example=grpc-routing -o yaml

使用 grpcurl 命令测试到 yages 后端的 GRPC 路由。

grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping

3 - JWT 身份验证

此任务提供有关配置 JSON Web Token(JWT)身份验证的说明。 JWT 身份验证在将请求路由到后端服务之前检查传入请求是否具有有效的 JWT。 目前,Envoy Gateway 仅支持通过 HTTP 标头验证 JWT,例如 Authorization: Bearer <token>

Envoy Gateway 引入了一个名为 SecurityPolicy 的新 CRD,允许用户配置 JWT 身份验证。 该实例化资源可以链接到 GatewayHTTPRouteGRPCRoute 资源。

先决条件

按照快速入门中的步骤安装 Envoy Gateway 和示例清单。 对于 GRPC - 请按照 GRPC 路由示例中的步骤操作。 在继续之前,您应该能够使用 HTTP 或 GRPC 查询示例程序后端。

配置

通过创建 SecurityPolicy 并将其附加到示例 HTTPRoute 或 GRPCRoute,允许使用具有有效 JWT 的请求。

HTTPRoute

kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/jwt/jwt.yaml

已创建两个 HTTPRoute,一个用于 /foo,另一个用于 /bar。 已创建 SecurityPolicy 并以 HTTPRoute foo 为目标来验证对 /foo 的请求。 HTTPRoute bar 不是 SecurityPolicy 的目标,并且将允许未经身份验证的请求发送到 /bar

验证 HTTPRoute 配置和状态:

kubectl get httproute/foo -o yaml
kubectl get httproute/bar -o yaml

SecurityPolicy 配置为 JWT 身份验证,并使用单个 JSON Web Key Set(JWKS)提供程序来对 JWT 进行身份验证。

验证 SecurityPolicy 配置:

kubectl get securitypolicy/jwt-example -o yaml

GRPCRoute

kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/jwt/grpc-jwt.yaml

已创建 SecurityPolicy 并针对 GRPCRoute yages 来验证 yages 服务的所有请求。

验证 GRPCRoute 配置和状态:

kubectl get grpcroute/yages -o yaml

SecurityPolicy 配置为 JWT 身份验证,并使用单个 JSON Web Key Set(JWKS)提供程序来对 JWT 进行身份验证。

验证 SecurityPolicy 配置:

kubectl get securitypolicy/jwt-example -o yaml

测试

确保设置了快速入门 中的 GATEWAY_HOST 环境变量。如果没有,请按照快速入门说明设置变量。

echo $GATEWAY_HOST

HTTPRoute

验证在没有 JWT 的情况下对 /foo 的请求是否被拒绝:

curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/foo

应返回一个 401 HTTP 响应码。

获取用于测试请求身份验证的 JWT:

TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode

**注意:**上述命令解码并返回令牌的有效内容。您可以将 f2 替换为 f1 来查看令牌的标头。

验证是否允许使用有效 JWT 向 /foo 发出请求:

curl -sS -o /dev/null -H "Host: www.example.com" -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n" http://$GATEWAY_HOST/foo

应返回一个 200 HTTP 响应码。

验证是否允许在没有 JWT 的情况下向 /bar 发出请求:

curl -sS -o /dev/null -H "Host: www.example.com" -w "%{http_code}\n" http://$GATEWAY_HOST/bar

GRPCRoute

验证是否在没有 JWT 的情况下拒绝对 yages 服务的请求:

grpcurl -plaintext -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping

您应该看到以下响应:

Error invoking method "yages.Echo/Ping": rpc error: code = Unauthenticated desc = failed to query for service descriptor "yages.Echo": Jwt is missing

获取用于测试请求身份验证的 JWT:

TOKEN=$(curl https://raw.githubusercontent.com/envoyproxy/gateway/main/examples/kubernetes/jwt/test.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode

**注意:**上述命令解码并返回令牌的有效内容。您可以将 f2 替换为 f1 来查看令牌的标头。

验证是否允许使用有效 JWT 向 yages 服务发出请求:

grpcurl -plaintext -H "authorization: Bearer $TOKEN" -authority=grpc-example.com ${GATEWAY_HOST}:80 yages.Echo/Ping

您应该看到以下响应:

{
  "text": "pong"
}

清理

按照快速入门 中的步骤卸载 Envoy Gateway 和示例清单。

删除 SecurityPolicy:

kubectl delete securitypolicy/jwt-example

后续步骤

查看开发者指南参与该项目。