Kourier 网关介绍

发布时间: 更新时间: 总字数:3317 阅读时间:7m 作者: IP上海 分享 网址

Kourier 是一个基于 Envoy 架构实现的轻量级网关,是 Knative 社区提供的开源网关实现,提供 Knative Revisions 流量分发,支持 gRPC 服务、超时和重试、TLS 证书和外部认证授权等功能。

介绍

Kourier 已达到 GA 状态

Kourier 是 Knative Serving 的一个 Ingress。Kourier 是 Istio Ingress 的一个轻量级替代方案,因为它部署时只包含一个 Envoy 代理和一个用于它的控制平面。

Kourier 正在通过 Knative Serving 的端到端(e2e)和一致性测试:Kourier Testgrid

功能

  • 在 Knative 修订版本(revisions)之间进行流量拆分
  • 自动更新随着扩展而变化的端点
  • 支持 gRPC 服务
  • 支持超时和重试
  • 支持 TLS
  • 支持密码套件
  • 支持外部授权
  • 支持 Proxy Protocol(一项实验性/Alpha 功能)

特点

  • 轻量级:相比 Istio,Kourier 的部署更为轻量,减少了资源消耗和管理复杂度
  • 高性能:基于 Envoy Proxy,Kourier 提供了高性能的流量管理和路由能力
  • 易用性:Kourier 的安装和配置非常简单,适合快速上手和部署
  • 灵活性:支持多种高级功能,如流量拆分、自动更新端点、gRPC 支持、TLS 配置等
  • 实验性功能:Kourier 还提供了一些实验性功能,如 Proxy Protocol 支持,为用户提供更多选择

部署

默认情况下,Kourier 组件的部署被分割到两个不同的命名空间:

  • Kourier 控制平面部署在 knative-serving 命名空间
  • Kourier 网关部署在 kourier-system 命名空间

要更改 Kourier 网关的命名空间,需要:

  • 修改 config/ 目录下的文件,将所有带有 kourier-system 的命名空间字段替换为所需的命名空间

  • 在 kourier-control 部署中,将 KOURIER_GATEWAY_NAMESPACE 环境变量设置为新的命名空间

  • 安装 Knative Serving,最好不要包含 Istio:

kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-core.yaml
  • 然后安装 Kourier:
kubectl apply -f https://github.com/knative/net-kourier/releases/latest/download/kourier.yaml
  • 配置 Knative Serving 以使用正确的 “ingress.class”:
kubectl patch configmap/config-network \
  -n knative-serving \
  --type merge \
  -p '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'
  • (可选)设置你想要的域名(将 127.0.0.1.nip.io 替换为你偏好的域名):
kubectl patch configmap/config-domain \
  -n knative-serving \
  --type merge \
  -p '{"data":{"127.0.0.1.nip.io":""}}'
  • (可选)部署一个示例的 hello world 应用:
cat <<-EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    spec:
      containers:
      - image: gcr.io/knative-samples/helloworld-go
        env:
        - name: TARGET
          value: Go Sample v1
EOF
  • (可选)为了测试目的,你可以使用端口转发(port-forwarding)从你的机器向 Kourier 发出请求:
kubectl port-forward --namespace kourier-system $(kubectl get pod -n kourier-system -l "app=3scale-kourier-gateway" --output=jsonpath="{.items[0].metadata.name}") 8080:8080 19000:9000 8443:8443

curl -v -H "Host: helloworld-go.default.127.0.0.1.nip.io" http://localhost:8080

代码解析

配置解析

Envoy 动态配置 (dynamic_resources)的基本设置,主要用于通过 ADS (Aggregated Discovery Service) 动态发现服务、集群和监听器等资源。

dynamic_resources:
  ads_config:
    transport_api_version: V3
    api_type: GRPC
    rate_limit_settings: {}
    grpc_services:
    - envoy_grpc: {cluster_name: xds_cluster}
  cds_config:
    resource_api_version: V3
    ads: {}
  lds_config:
    resource_api_version: V3
    ads: {}
  • dynamic_resources: 这个顶级字段表明 Envoy 正在使用动态配置,而不是静态文件。这意味着 Envoy 会在运行时从一个或多个 xDS (Discovery Service) 服务器获取配置信息。
    • ads_config: 这是核心配置,定义了 ADS 的连接方式。ADS 是一种 聚合发现服务,它允许 Envoy 通过一个单一的 gRPC 流同时接收所有类型的动态配置(如 CDS、LDS、RDS、EDS)。这简化了管理,因为你不需要为每种资源类型设置单独的连接。
      • transport_api_version: V3: 指定了用于 xDS 通信的 API 版本,这里是 V3。V3 是 Envoy 目前推荐使用的最新版本,提供了更丰富的特性和更好的稳定性。
      • api_type: GRPC: 明确了 Envoy 将使用 gRPC 协议与 xDS 服务器通信。gRPC 是一种高性能的 RPC(远程过程调用)框架,非常适合这种持续的、双向的数据流。
      • rate_limit_settings: {}: 这是一个空对象,表示目前没有对 xDS 资源的请求速率进行限制。在生产环境中,可以配置这个字段来防止 xDS 服务器被过多的请求淹没。
      • grpc_services: 定义了用于连接 xDS 服务器的 gRPC 服务。
        • envoy_grpc: {cluster_name: xds_cluster}: 这表明 Envoy 将使用名为 xds_cluster 的上游集群来建立与 xDS 服务器的 gRPC 连接。xds_cluster 本身需要在配置的 static_resources 或其他动态配置中定义,以指定 xDS 服务器的地址、端口等信息。
    • cds_configlds_config: 这两个字段是 ADS 的一个重要部分,它们告诉 Envoy 启用 CDS (Cluster Discovery Service)LDS (Listener Discovery Service),并通过 ADS 来获取这些资源。
      • resource_api_version: V3: 再次确认这些资源也将使用 V3 版本的 API。
      • ads: {}: 这个空对象是关键,它指示 Envoy:
        • 请不要为 CDS/LDS 建立单独的连接
        • 请使用上面 ads_config 定义的统一连接来获取 CDS/LDS 资源
  • 工作流程 🔄
    1. Envoy 启动后,读取这份配置。
    2. 它看到 dynamic_resources 并找到了 ads_config
    3. 它根据 grpc_services 中指定的 xds_cluster,向 xDS 服务器建立一个 gRPC 长连接
    4. 通过这个单一连接,Envoy 会向 xDS 服务器发送 CDS 请求LDS 请求
    5. xDS 服务器接收到请求后,会通过同一个 gRPC 流 推送 相应的集群配置 (CDS) 和监听器配置 (LDS) 给 Envoy。
    6. 当集群或监听器配置在 xDS 服务器端发生变化时,它会主动通过这个流将更新推送到 Envoy,实现 配置的热更新

核心思想是利用 ADS,通过一个统一的 gRPC 连接,高效且动态地管理 Envoy 的所有配置,这极大地简化了大规模微服务架构下的服务发现和流量管理。

使用

设置 TLS 证书

创建证书:

openssl genrsa -out tls.key 4096
openssl req -subj "/CN=*.xiexianbin.cn/L=*.xiexianbin.cn" -sha256  -new -key tls.key -out tls.csr
echo subjectAltName = DNS:default.xiexianbin.cn,DNS:*.default.xiexianbin.cn > extfile.cnf
openssl x509 -req -days 3650 -sha256 -in tls.csr -signkey tls.key -out tls.crt -extfile extfile.cnf

创建一个包含 TLS 证书和私钥的 Secret:

kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}

kubectl -n knative-serving create secret tls kourier-cert --key tls.key --cert tls.crt

在 “kourier” 容器中,为 net-kourier-controller 添加以下环境变量(kubectl -n knative-serving edit deployment net-kourier-controller):

...
   spec:
      containers:
      - env:
        - name: CERTS_SECRET_NAMESPACE
          value: ${NAMESPACES_WHERE_THE_SECRET_HAS_BEEN_CREATED-knative-serving}
        - name: CERTS_SECRET_NAME
          value: ${CERT_NAME-kourier-cert}
...

访问:

curl -H "host: helloworld-go.default.127.0.0.1.nip.io" -k --cert tls.crt --key tls.key http://localhost:8080 -v

密码套件/Cipher Suites

可以为外部 TLS 监听器指定密码套件。要指定你想要允许的密码套件,请运行以下命令来修补 config-kourier ConfigMap:

kubectl -n "knative-serving" patch configmap/config-kourier \
  --type merge \
  -p '{"data":{"cipher-suites":"ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-ECDSA-CHACHA20-POLY1305"}}'

默认情况下,它使用 Envoy 版本的默认密码套件。

外部授权配置

如果你想启用外部授权支持,可以在 net-kourier-controller 部署中设置以下环境变量:

  • KOURIER_EXTAUTHZ_HOST*:外部授权服务及其端口,例如 my-auth:2222
  • KOURIER_EXTAUTHZ_FAILUREMODEALLOW*:如果外部授权服务宕机,是否允许流量通过。接受 truefalse
  • KOURIER_EXTAUTHZ_PROTOCOL:用于查询外部授权服务的协议。可以是:grpchttphttps。默认为 grpc
  • KOURIER_EXTAUTHZ_MAXREQUESTBYTES:最大请求字节数,如果未设置,默认为 8192 字节。更多信息请参阅 Envoy 文档
  • KOURIER_EXTAUTHZ_TIMEOUT:等待外部授权服务的最大时间(毫秒)。默认为 2 秒。
  • KOURIER_EXTAUTHZ_PATHPREFIX:如果 KOURIER_EXTAUTHZ_PROTOCOL 等于 httphttps,此项为查询外部授权服务的路径。例如:如果设置为 /verify,它将查询 /verify/注意末尾的斜杠)。如果未设置,它将查询 /
  • KOURIER_EXTAUTHZ_PACKASBYTES:如果 KOURIER_EXTAUTHZ_PROTOCOL 等于 grpc,此项将请求正文作为原始字节发送,而不是 UTF-8 字符串。仅接受 true/falset/f1/0。尝试设置其他值会抛出错误。默认为 false。更多信息请参阅 Envoy 文档

* 为必填项。

Proxy Protocol 配置

注意:这是一项实验性/Alpha 功能。

要启用 Proxy Protocol 功能,请运行以下命令修补 config-kourier ConfigMap:

kubectl patch configmap/config-kourier \
  -n knative-serving \
  --type merge \
  -p '{"data":{"enable-proxy-protocol":"true"}}'

确保文件已成功更新:

kubectl get configmap config-kourier --namespace knative-serving --output yaml

LoadBalancer 配置

我们需要:

  • 使用你的 LB 提供商的注解来启用 Proxy Protocol。
  • 如果你计划启用外部域名 TLS,使用你的 LB 提供商的注解来指定一个自定义名称用于 LoadBalancer。这是为了解决 kube-proxy 将外部 LB 地址添加到节点本地 iptables 规则的问题,该问题会导致集群内部对 LB 的请求中断(如果 LB 期望终止 SSL 或 Proxy Protocol)。
  • externalTrafficPolicy 更改为 Local,这样 LB 将保留客户端源 IP,并避免了对 LoadBalancer 的第二次跳跃。

示例 (Scaleway 提供商):

apiVersion: v1
kind: Service
metadata:
  name: kourier
  namespace: kourier-system
  annotations:
    service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: '*'
    service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"
  labels:
    networking.knative.dev/ingress-provider: kourier
spec:
  ports:
    - name: http2
      port: 80
      protocol: TCP
      targetPort: 8080
    - name: https
      port: 443
      protocol: TCP
      targetPort: 8443
  selector:
    app: 3scale-kourier-gateway
  externalTrafficPolicy: Local
  type: LoadBalancer

域名映射

域名映射(Domain Mapping)被配置为仅显式使用 http2 协议。通过向域名映射资源添加以下注解可以禁用此行为:

kubectl annotate domainmapping <domain_mapping_name> kourier.knative.dev/disable-http2=true --namespace <namespace>

此配置的一个很好用例是带有 Websocket 的域名映射

注意:此注解是一项实验性/Alpha 功能。我们将来可能会更改注解名称。

日志采集

[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
%RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%"
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n

[2016-04-15T20:17:00.310Z] "POST /api/v1/locations HTTP/2" 204 - 154 0 226 100 "10.0.35.28"
"nsq2http" "cc21d9b0-cf5c-432b-8c7e-98aeb7988cd2" "locations" "tcp://10.0.2.1:80"

扩展

参考

  1. https://github.com/knative-extensions/net-kourier
本文总阅读量 次 本站总访问量 次 本站总访客数
Home Archives Categories Tags Statistics