MoreRSS

site iconJimmy Song | 宋净超修改

Tetrate 布道师,云原生社区 创始人,CNCF Ambassador,云原生技术专家。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Jimmy Song | 宋净超的 RSS 预览

理解 Envoy 的扩展与集成机制:从内置扩展到动态模块

2025-05-08 15:00:00

随着 Envoy 在云原生网络领域的广泛应用,越来越多开发者开始关注如何扩展它的功能。Envoy 提供了多种扩展机制,不同机制在性能、安全性、开发复杂度和兼容性方面各有差异。

这篇文章是我在调研 Envoy 扩展机制过程中的总结,希望能为你理解和选择合适的扩展方式提供一些参考。

两类机制:扩展 vs 集成

在讨论 Envoy 的“扩展机制”时,我们需要先明确一点:并非所有用于扩展功能的方式都算作 Envoy 的原生扩展(in-process extensions)。从架构上看,Envoy 的机制大致分为两类:

  • 进程内扩展机制(in-process extensions):
    • 内置 C++ 过滤器
    • Lua 脚本
    • Wasm 插件
    • 动态模块(Dynamic Modules)
  • 进程外集成机制(out-of-process integrations):
image
Envoy 代理扩展机制

Ext_proc 和 ext_authz 本质上是通过 Envoy 提供的 gRPC/HTTP API 接口调用外部服务来实现请求处理逻辑,它们运行在独立进程中,并不注册为 Envoy 本地的过滤器链一部分。因此,严格来说,它们是“集成机制”而非“扩展机制”。

不过,为了更完整地覆盖用户常用的方式,在本文中我将它们一并纳入比较和讨论中。毕竟在实际使用中,它们和原生扩展一样,常用于处理 HTTP 请求和响应。

简要概览:六种机制各有优劣

每种机制的使用成本、性能表现、适用范围都不一样。下面是我对它们的简要归纳。

内置 C++ 扩展:性能至上,但维护成本高

这是一种最原始也最强大的方式,把自定义逻辑直接写入 Envoy 的源码中编译。这种方式拥有最好的性能(包括零拷贝和低延迟),适合对性能极致要求的场景。但缺点是:你需要维护自定义构建流程,分发自己的 Envoy 二进制文件,升级成本高。

Lua 脚本:轻量、灵活、但无隔离机制

Lua 是一种比较老牌的扩展机制,支持在 Envoy 同一进程中以协程方式运行逻辑代码。它的优点是轻量、上手快、无需重新构建 Envoy,可直接内联到配置中。但它也没有任何隔离机制,脚本运行崩溃可能影响整个 Envoy,因此应仅在信任的环境中使用。

Wasm 扩展:跨语言支持 + 沙箱隔离,但尚未成熟

Proxy-Wasm 提供了更现代的方式,可以用 Rust、Go 等语言编写逻辑,并以 WebAssembly 模块动态加载到 Envoy 中运行。它运行在沙箱 VM 中,有一定安全隔离,但当前生态仍不成熟,调试困难,性能略逊于 C++ 和动态模块,仍在不断演进中。

动态模块:Rust 驱动的“原生扩展替代品”

动态模块是最近出现的新机制(从 Envoy v1.34),它允许你用 Rust 编写符合 C ABI 的扩展逻辑,并以 .so 共享库形式在运行时加载到 Envoy 中。相比内置 C++,它不需要你自己编译 Envoy,但仍然具有近似的性能表现。适合性能敏感、同时又想避免维护 Envoy 构建的团队。

External Processing(ext_proc):功能强大但延迟高

ext_proc 提供了一个灵活的方式:你可以在外部服务中完全自定义对请求和响应的处理,包括访问和修改 Body 内容。它通过 gRPC 调用,对数据进行深度检查(如 DLP、病毒扫描等)很有用。但由于是进程外调用,它的性能显然无法与进程内机制相比。

External Authorization(ext_authz):轻量级认证过滤器

ext_authz 的功能类似,只不过它只处理请求路径,不能修改响应内容。典型场景是 OAuth2、JWT 鉴权、Header 检查等访问控制逻辑。它可以远程部署,不影响主流程,是最常用的认证机制之一。

对比表:各机制在不同维度下的能力评估

为了更直观地理解六种机制的异同,我整理了下表,从执行方式、性能、安全性、兼容性等维度进行对比:

维度 内置 C++ 过滤器 Lua 脚本 Wasm 动态模块 ext_proc ext_authz
实现方式/执行环境 原生 C++,编译入 Envoy LuaJIT,进程内协程 VM 中运行(V8/Wazero) 共享库形式加载,进程内执行 gRPC/REST,进程外服务 gRPC/REST,进程外服务
性能 极致性能,零复制 中等,低于 C++ 高于 Wasm 中等,数据需进出 VM 高,接近原生性能 较低,需跨网络栈复制 高效处理元数据,适合轻量鉴权
开发语言/SDK C++ Lua,无 SDK,使用 stream API Rust 最佳,支持 Go/C++ Rust 官方支持,也可用 Go 等构建 任意支持 gRPC/REST 的语言 任意支持 gRPC/REST 的语言
部署/加载方式 静态编译 配置内联或引用脚本 动态加载 Wasm 模块 动态加载 .so 远程服务或 Sidecar 部署 可远程部署
安全性/信任模型 完全受信任 无隔离机制,与 Envoy 等价信任 沙箱执行,隔离性好 与主进程共享内存,需完全信任 进程隔离,独立部署更安全 进程隔离,独立部署更安全
兼容性 与 Envoy 版本强耦合 依赖 Lua API 稳定性,兼容性尚可 ABI 相对稳定,跨版本较友好 严格要求 ABI 匹配,版本锁定 API 稳定,跨版本兼容性好 API 稳定,跨版本兼容性好
适用场景 核心路径、流量关键路径 快速修改逻辑、请求头部调整 跨语言开发、安全执行、原型快速迭代 性能敏感 HTTP 扩展,不想自建构建链 响应检查、DLP、安全扫描 授权认证、用户访问控制

我为什么倾向于使用“动态模块”

在我自己的实践与调研过程中,动态模块(Dynamic Modules)逐渐成为我最推荐的扩展机制

它不仅具备接近内置 C++ 的性能,而且避免了重构 Envoy 构建系统的复杂性。这对很多需要性能保障又不愿意维护 forked Envoy 的团队来说,提供了一个优雅的折中方案。

相比 Wasm,动态模块直接运行于主进程中,无需数据序列化、无需跨 VM 边界复制数据,也没有 VM 启动和内存沙箱的负担,在处理请求头部、body 时具备天然优势。

当然,它目前还属于实验阶段,缺乏跨版本 ABI 兼容性,这意味着每个 Envoy 版本都需要重新构建对应模块。但对很多使用 固定版本或内部发布节奏的企业场景来说,这个限制是完全可以接受的。

从扩展机制演进来看,我认为动态模块很可能会逐步替代大部分 Wasm 的使用场景,特别是在要求高性能和低调试复杂度的企业环境中。

在接下来的博客中,我会分享一个基于 Rust 构建动态模块的完整示例,演示如何快速编写、构建并在 Envoy 中加载一个 HTTP 过滤器,敬请关注。

总结:如何选择合适的机制?

我的建议是:

  • 如果你对性能有极致要求,又希望避免维护自定义 Envoy 构建流程,动态模块是我最推荐的选择。它兼具高性能和灵活性,虽然目前仍处于实验阶段,但我认为它将逐步取代大多数 Wasm 的使用场景。
  • 内置 C++ 扩展依然是极致性能下的终极方案,但维护成本高,适合掌控力强的团队。
  • 如果你需要快速实现简单逻辑,Lua 脚本是最容易上手、部署最轻量的扩展方式。
  • 对于关注安全隔离、希望跨语言开发的场景,Wasm 虽然设计先进,但在生产中的性能开销、调试复杂性和生态成熟度仍是现实挑战。相比之下,动态模块以更贴近“原生”的方式解决了这类问题。
  • 若你希望将控制逻辑完全从 Envoy 中解耦,ext_proc 和 ext_authz 提供了可靠的集成方式,特别适合做认证、策略检查和请求外部处理。

每种机制都不是完美的银弹,理解它们背后的设计理念和权衡,才能做出最适合自己业务需求的选择。总之,如果你正在评估在 Envoy 中构建扩展的长期方案,我建议你密切关注动态模块的发展,并提前做好技术选型准备。

如你对某种扩展机制有实战经验或深入探索,也欢迎留言交流。欢迎关注我的博客 jimmysong.io,我会持续分享有关 Envoy、Istio 和服务网格的文章。

从 ingress-nginx 迁移到 Envoy Gateway 指南

2025-04-18 16:31:36

本文旨在帮助当前依赖 ingress-nginx 的用户迁移至 Envoy Gateway 并采用 Gateway API。我们将介绍迁移的动因,提供一个基于 Minikube 的实操示例,并展示如 ingress2gateway 工具如何简化整个迁移流程。

为什么要迁移?

Kubernetes 中的 Ingress 控制器是网络流量管理的基础组件,许多团队在初期会选择使用 ingress-nginx,因为它易于部署且社区广泛支持。然而,随着生产环境需求的提升,传统 Ingress API 与 nginx 控制器的局限性也日益显现,比如依赖注解的配置方式难以理解,更新配置时容易导致流量中断等问题。

更值得注意的是,近期的安全漏洞(如 CVE-2025-1974)暴露了继续依赖 ingress-nginx 所带来的安全风险。此外,维护团队已宣布,ingress-nginx 将在 18 个月后进入维护模式参考视频),这意味着现在是时候评估更现代、更具可扩展性的替代方案了。

Envoy Gateway 是一个值得关注的选择,它原生支持 Kubernetes Gateway API,具备更强的可观测性和可扩展性,能够更好地满足企业级流量管理的需求。

认识 Envoy Gateway 和 Gateway API

Envoy Proxy 是一个现代的、为云原生设计的代理,具备可观测性、热更新和良好的可运维性。Envoy Gateway(EG) 基于 Envoy 构建,提供了基于 Kubernetes Gateway API 的强大 Ingress 解决方案。

与传统的 Ingress API 不同,Gateway API 提供了 GatewayHTTPRouteGatewayClass 等结构化资源,支持更清晰、无注解的配置方式。EG 支持如下高级特性:

这些特性往往可以替代额外的 API Gateway 产品。Envoy Gateway 是完全开源的,并由 CNCF 社区治理。

迁移流程:从 nginx 迁移到 Envoy Gateway

在动手迁移之前,先来了解 ingress2gateway 工具的工作原理。这个 CLI 工具会扫描现有的 Kubernetes Ingress 资源(特别是为 ingress-nginx 配置的资源),并将其转换为 Gateway API 的资源,即 GatewayHTTPRoute。该工具不会生成 GatewayClass,因此用户需要提前创建好并进行引用。借助此工具,用户无需重写所有配置,就能平滑过渡至 Gateway API 和现代的 Ingress Controller(如 Envoy Gateway)。

image
ingress2gateway 工作流程

下面我们将以 macOS 上的 Minikube 为例,演示从 ingress-nginx 迁移至 Envoy Gateway 的完整过程。

步骤 1:启动 Minikube 并启用 NGINX Ingress 插件

minikube start
minikube addons enable ingress

步骤 2:部署 httpbin 服务及 Ingress 资源

kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
spec:
  selector:
    app: httpbin
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: httpbin.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: httpbin
            port:
              number: 80
EOF

步骤 3:通过 tunnel 启用 LoadBalancer 访问

minikube tunnel

步骤 4:测试 NGINX Ingress 是否生效

curl -H "Host: httpbin.local" http://127.0.0.1/get

步骤 5:安装 Envoy Gateway

helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.3.2 \
  -n envoy-gateway-system --create-namespace

步骤 6:创建名为 nginx 的 GatewayClass

kubectl apply -f - << EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

步骤 7:使用 ingress2gateway 转换配置

安装工具:

go install github.com/kubernetes-sigs/ingress2gateway@latest

转换配置:

ingress2gateway print --providers ingress-nginx | kubectl apply -f -

如果 Ingress 不在 default 命名空间,需添加 --namespace 参数。

步骤 8:验证迁移是否成功

测试路由:

curl --header 'Host: httpbin.local' http://127.0.0.1/get

步骤 9:清理 NGINX Ingress(可选)

终止 tunnel 并关闭 ingress 插件:

minikube addons disable ingress

总结

通过迁移到 Envoy Gateway,你可以获得更加结构化、功能丰富的 Ingress 配置方式。这种方式由 CNCF 社区驱动,支持速率限制、身份认证和 Web 防护等开箱即用的功能,且标准一致、可移植性强。

延伸阅读

Envoy Gateway 数据平面可观测性指南

2025-04-17 20:12:11

注意:本文基于 Envoy Gateway v1.3.2 编写。

在大规模微服务架构中,可观测性是理解与运维系统的核心能力。Envoy Gateway 构建于 Envoy Proxy 之上,提供了丰富的可观测性功能,包括指标、日志和追踪。本文将通过动手实践的方式,讲解如何基于 Prometheus、Loki 和 Tempo 等开源后端,为 Envoy Gateway 的数据平面(即 Envoy proxy 本身)配置可观测性功能。

前置条件

在开始配置之前,请确保你已经完成 Envoy Gateway 的基本安装。下图展示了 Envoy Gateway 的可观测性组件架构:

image
Envoy Gateway 可观测性管道

OpenTelemetry Collector 是一个可插拔的数据中转组件,负责接收、处理和转发可观测性数据(如指标和追踪),来源包括 Envoy Gateway 等系统。通过将数据生成与数据消费解耦,它能够灵活对接多种可观测性后端(如 Prometheus、Tempo、Jaeger),同时支持数据增强、格式转换和多路导出。

安装 Envoy Gateway

按照官方 快速开始指南 安装 Envoy Gateway:

helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.3.2 -n envoy-gateway-system --create-namespace
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.3.2/quickstart.yaml -n default

安装可观测性组件

使用官方 Helm chart 安装可观测性组件:

helm install eg-addons oci://docker.io/envoyproxy/gateway-addons-helm --version v1.3.2 -n monitoring --create-namespace --set opentelemetry-collector.enabled=true

注意:OpenTelemetry Collector 默认未启用,需显式开启。

安装完成后,将部署以下组件:

组件 角色 描述
FluentBit 日志收集器 收集并转发日志到 Loki
Grafana 可视化界面 展示指标、日志和追踪的仪表盘
Loki 日志存储 聚合和索引日志
OpenTelemetry Collector 遥测收集器 将指标/追踪数据导出到 Prometheus / Tempo
Prometheus 指标后端 收集并存储 Prometheus 指标数据
Tempo 追踪后端 存储和查询分布式追踪数据

生成测试流量

为了测试可观测性组件,我们可以向 Envoy Gateway 发送一些简单的请求。由于使用的是 Minikube,本地可通过端口转发的方式访问:

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}')
kubectl port-forward -n envoy-gateway-system svc/${ENVOY_SERVICE} 8888:80
curl --verbose --header "Host: www.example.com" http://localhost:8888/get

指标(Metrics)

通过以下配置禁用默认的 Prometheus 指标输出,并启用 OpenTelemetry Sink:

cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
  namespace: envoy-gateway-system
spec:
  gatewayClassName: eg
  infrastructure:
    parametersRef:
      group: gateway.envoyproxy.io
      kind: EnvoyProxy
      name: unified-telemetry
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: unified-telemetry
  namespace: envoy-gateway-system
spec:
  telemetry:
    metrics:
      prometheus:
        disable: true
      sinks:
        - type: OpenTelemetry
          openTelemetry:
            host: otel-collector.monitoring.svc.cluster.local
            port: 4317
EOF

下图展示了 Envoy Proxy 指标可观测性的整体流程:Envoy 原生采集网络流量等关键指标,并通过 /stats/prometheus 接口暴露,Prometheus 进行抓取并在 Grafana 中可视化。此外,Envoy 还支持自定义指标,并可选集成 StatsD 等系统,实现灵活的监控体系。

image
指标可观测性

使用 Prometheus 查看指标

本地暴露 Prometheus:

kubectl port-forward -n monitoring svc/prometheus 9090:80

访问 http://localhost:9090 并执行如下查询:

topk(1,envoy_cluster_upstream_cx_connect_ms_sum)
image
Prometheus UI

使用 Grafana 查看指标

kubectl port-forward -n monitoring svc/grafana 3000:80

打开 http://localhost:3000,默认账户密码为 admin/admin

image
Grafana - Envoy Clusters dashboard

详细配置参考 Proxy Metrics 指南

日志(Logs)

Envoy Gateway 使用访问日志(Access Log)进行流量记录,支持格式和输出目标的自定义。

应用以下配置,启用将日志发送至 OpenTelemetry Sink:

kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/refs/heads/main/examples/kubernetes/accesslog/otel-accesslog.yaml

通过 Loki 查询日志示例:

curl -s "http://localhost:3100/loki/api/v1/query_range" --data-urlencode "query={exporter=\"OTLP\"}" | jq '.data.result[0].values'

你将看到类似以下格式的输出:

 [
   [
     "1693314563284333000",
     "{"body":"[2025-04-17T13:09:23.284Z] \"- - HTTP/1.1\" 400 DPE 0 11 0 \"-\" \"-\" \"-\" \"-\" \"-\"\n","resources":{"cluster_name":"default/eg","k8s.cluster.name":"cluster-1","log_name":"otel_envoy_accesslog","node_name":"envoy-default-eg-64656661-6fccffddc5-662np","zone_name":""}}"
   ]
 ]

下图展示了日志可观测性流程:Envoy 支持自定义日志格式、输出到文件/stdout/syslog/HTTP 目标,亦支持按需采样、过滤,并可包含安全相关字段用于审计。

image
日志可观测性

日志配置详情参考 Proxy Access Logs 指南

在 Grafana 中查看日志

  1. 暴露 Grafana:
kubectl port-forward -n monitoring svc/grafana 3000:80
  1. 打开浏览器访问 http://localhost:3000,首次登录使用 admin/admin

  2. 点击左侧导航栏的齿轮图标 → Data sources,确保 Loki 数据源配置正确,地址为 http://loki:3100

  3. 下载并导入日志仪表盘:envoy-gateway-logs-dashboard.json

  4. 打开 Envoy Gateway Logs 仪表盘,即可查询和过滤日志数据:

image
Envoy Gateway Logs dashboard

追踪(Traces)

追踪提供了请求路径的详细可视化,是定位性能瓶颈的重要手段。

Envoy Gateway 原生支持 OpenTelemetry 格式的追踪,生成带有 Trace ID 和 Span ID 的请求链路数据,可通过配置发送到 Tempo、Zipkin 等支持 OpenTracing 协议的后端。

启用追踪:

kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/refs/heads/main/examples/kubernetes/tracing/default.yaml

使用 Tempo 验证追踪数据

暴露 Tempo:

kubectl port-forward svc/tempo 3100:3100 -n monitoring

查询 trace 概览:

curl -s "http://localhost:3100/api/search" --data-urlencode "q={ component=envoy }" | jq .traces

示例输出:

[
  {
   "traceID": "8010d4fd89e024c0626d984621babd71",
   "rootServiceName": "eg.default",
   "rootTraceName": "ingress",
   "startTimeUnixNano": "1693377719403756000"
  }
]

查询指定 trace:

curl -s "http://localhost:3100/api/traces/<trace_id>" | jq

返回信息将包含完整的 trace span 数据,包括服务名、请求起止时间、状态码、上下游节点等详细字段。

详细参考 Proxy Tracing 指南

在 Grafana 中查看追踪数据

  1. 在 Grafana 左侧导航栏点击 Data sources,确认已配置名为 tempo 的 Tempo 数据源,地址为 http://tempo:3100

  2. 下载并导入追踪仪表盘:envoy-gateway-traces-dashboard.json

  3. 打开 Envoy Gateway Traces 仪表盘,浏览可用的 trace 数据:

image
Envoy Gateway Traces Dashboard

点击任意 trace 可查看其详细的 span 结构:

image
Trace Spans

总结

通过本文的实践操作,你已掌握了如何为 Envoy Gateway 的数据平面启用完整的可观测性功能。结合 OpenTelemetry Collector 的中转能力,以及 Prometheus、Loki 和 Tempo 等后端系统,你可以构建一个具备可扩展性、可插拔性和一致性的可观测性体系,帮助你在无需修改应用代码的前提下,实现对系统流量、性能和错误的深入洞察与排障能力。

利用 EnvoyPatchPolicy 拓展 Envoy Gateway 的能力

2025-04-14 13:16:35

注意:本文基于 Envoy Gateway v1.3.2。

Envoy Gateway 构建在 Envoy Proxy 之上,提供了一套丰富的功能。然而,在某些情况下,你可能希望使用 Envoy Proxy 的一些功能,而这些功能并未通过 Envoy Gateway 的 API 暴露出来。这时就可以使用从 Envoy Gateway v0.5.0 引入的 EnvoyPatchPolicy API。它允许你自定义 Envoy Gateway 生成的 xDS 资源。本文将指导你如何启用该 API,并实现一个非常实用的功能 —— 本地响应修改(Local Reply Modification)

我们将从前置条件开始介绍,然后讲解如何启用 EnvoyPatchPolicy、如何编写自定义响应逻辑,并最终验证效果。

前置条件

在开始之前,请确保你已正确安装 Envoy Gateway 和示例资源清单。运行以下命令完成环境准备并确保可以通过 HTTP 访问示例 backend:

# 安装 Envoy Gateway 和示例清单
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.3.2 -n envoy-gateway-system --create-namespace
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.3.2/quickstart.yaml -n default
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}')
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &

启用 EnvoyPatchPolicy

默认情况下,EnvoyPatchPolicy 是关闭的。启用该功能需要创建一个配置文件 ConfigMap,并将其挂载到 Envoy Gateway。执行以下命令:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy-gateway-config
  namespace: envoy-gateway-system
data:
  envoy-gateway.yaml: |
    apiVersion: config.gateway.envoyproxy.io/v1alpha1
    kind: EnvoyGateway
    provider:
      type: Kubernetes
    gateway:
      controllerName: gateway.envoyproxy.io/gatewayclass-controller
    extensionApis:
      enableEnvoyPatchPolicy: true
EOF

自定义响应逻辑

使用 EnvoyPatchPolicy API,你可以修改 Envoy Gateway 生成的 xDS 资源。目前仅支持 JSONPatch 类型。

Envoy 提供了修改本地响应内容的能力,你可以通过配置 mappers 来指定需要变更的响应内容。每个 mapper 包含一个 filter 和多个改写规则,例如:

Envoy 会按顺序处理这些 mapper,匹配成功后即应用对应改写规则。

我们来构建一个案例:当后端返回 404 时,Envoy Gateway 将其替换为 406,并附带一段自定义文本提示。

下面是该案例的架构图:

image
使用 EnvoyPatchPolicy 实现 Local Reply Modification

执行以下配置:

cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
  name: custom-response-patch-policy
  namespace: default
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: eg
  type: JSONPatch
  jsonPatches:
    - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
      name: default/eg/http
      operation:
        op: add
        path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
        value:
          mappers:
          - filter:
              status_code_filter:
                comparison:
                  op: EQ
                  value:
                    default_value: 404
                    runtime_key: key_b
            status_code: 406
            body:
              inline_string: "could not find what you are looking for"
EOF

然后我们需要修改示例中的 HTTPRoute,仅匹配 /get 路径:

kubectl patch httproute backend --type=json -n default --patch '[{
   "op": "add",
   "path": "/spec/rules/0/matches/0/path/value",
   "value": "/get",
}]'

接下来我们访问 /find 路径进行验证:

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

你将看到如下响应:

could not find what you are looking for

如前所述,由于 EnvoyPatchPolicy 依赖底层的 Envoy 和 Gateway API 结构,未来版本可能存在差异,请关注官方文档并做好兼容性准备。

尽情探索这个强大的扩展机制,让你的 Envoy Gateway 实现更强的可编程能力吧!

参考资料

KubeCon EU 2025 参会报告:塑造云原生格局的洞察与趋势

2025-04-13 19:22:45

上周,我前往伦敦参加了 KubeCon + CloudNativeCon Europe 2025,这是云原生领域在欧洲一年一度的盛会。今年的大会汇聚了超过 12,500 名开发者、维护者和用户,场面热烈、话题深度十足。

为了更好地总结这次大会的内容和趋势,我制作了一份 HTML/PDF 格式的报告,对重点主题进行了归纳,包括:

  • AI 在 Kubernetes 中的落地与趋势
  • 安全策略演进(供应链、身份信任等)
  • 平台工程从工具走向体验与指标
  • 多集群与边缘计算的现实应用
  • 可持续性与绿色计算的呼声增强

👉 点击此处查看完整报告

欢迎你阅读报告,也欢迎通过评论、邮件等方式与我交流你对大会趋势的看法!

探索 GitHub Copilot:当 AI 成为你的贴身编码助手

2025-03-27 14:57:27

过去一年中,我一直享有 GitHub Copilot 的免费使用资格,但是由于种种原因,我并没有深入地使用它。最近看到了 GitHub 官方发布的一篇关于 Copilot 的博客《Mastering GitHub Copilot: When to use AI agent mode》,让我对如何更好地使用 Copilot 有了新的灵感和思考。

在这篇文章里,我想和大家分享一下我对 Copilot 强大功能的理解,尤其是 Copilot EditsAgent Mode 这两个模式之间的差异和使用场景。最后,我还想呼吁所有开源项目的贡献者:如果你符合条件,一定要去积极申请 Copilot 免费使用资格,让自己的开发效率更上一个台阶!

为什么你的 AI 辅助写码好像“不给力”?

大多数开发者在接触 AI 辅助编码工具(比如 GitHub Copilot)时,都会或多或少地遇到一些状况,比如:

  • 生成的代码和你所需的功能“差那么一点”;
  • 需要在多个文件间跳来跳去修改,却希望 AI 能自动帮忙“通盘考虑”。

其实,这些小挫折往往不在于工具本身,而在于你是否找对了使用方式。GitHub Copilot 内部包含多个侧重点各不相同的功能,它们各自适合在不同的情景下使用。正确地选择合适的功能,就是解锁 Copilot 真正实力的关键

Copilot Edits:快速精确的“微调”

什么时候用它?

  • 小范围的修复:修复一个函数的 bug。
  • 重构特定模块:给函数或组件做局部优化。
  • 做跨文件的一致性改动:例如统一日志打印格式,或者统一变量命名方式。

Copilot Edits 的功能就像是给你配备了一个能读懂上下文的“超级编辑器”。你可以快速发出命令,让它在有限范围内对现有代码进行改动,并在提交前查看 diff,随时保持对改动的掌控。

Agent Mode:你的“多文件大管家”

与 Copilot Edits 相比,Agent Mode 更像是一个能够宏观统筹全局的 AI 助手。它不只是在一个文件里给你提建议,更可以去你的整个项目里做深度搜索、自动找出依赖关系、创建或修改多个文件,甚至可以帮你在终端里运行命令、编译、测试项目等。

适合的使用场景

  1. 构建完整功能:如“为应用添加全局的事件跟踪”。
  2. 理解和浏览陌生项目:如“帮我搞懂这个项目里认证系统是怎么运作的”。
  3. 整合测试:如“为 UserService 写测试并确保全部通过”。
  4. 需要运行大量终端操作:如“创建新的 React + TS + Redux + styled-components 项目”。
  5. 复杂的重构:如“统一替换所有 API 调用并加入新的错误处理逻辑”。

我在个人网站上的应用场景

博主(也就是我)在给个人网站的 GitHub Action 中增加一个更新索引文件的工作,可以告诉 Copilot Agent:

“给我的 GitHub Action 中增加一个更新 search index 的任务并在本地测试”

然后 Copilot Agent 会扫描我的代码库,聪明地在我的 GitHub Action 配置文件中帮我插入相应的任务,并会自动的安装依赖软件并运行测试。

image
VS Code 中的 Copilot Action

这就是 Agent Mode 的强大之处,它可以一次性处理全局级别的改动,真正让 AI 成为你的“对等”开发伙伴。

核心优势

  • 自动检索整个代码库:不用手动定位所有相关文件。
  • 自我迭代:可以一次性迭代和修复自己生成的代码。
  • 终端命令执行:在得到你授权后,会自动跑命令、编译或测试。
  • 维持整体架构一致:在改动时会考虑跨文件依赖关系,减少顾此失彼的风险。

Chat 窗口:你的“Copilot 指挥中心”

无论你是想使用 Copilot Edits 还是 Agent Mode,你都会用到 VS Code 里的 Copilot Chat 窗口:

  1. 提问常规技术问题,比如:“如何在 Node.js 中实现 JWT 认证?”
  2. 使用 /explain 理解复杂代码片段。
  3. 使用 /fix 让 Copilot 帮你调试。
  4. 使用 /tests 为给定代码自动生成测试用例。
  5. 随时在 Edits 和 Agent Mode 之间切换。

记住:你提供的上下文信息越完整,Copilot 生成的回答就越准确。请不要吝啬给它多一些提示!

二者并不冲突——混合使用才是王道

原文中强调了一点:Copilot Edits 和 Agent Mode 并不是二选一的对立关系,而是相辅相成。

  • 当你需要快速修复和微调时,选 Copilot Edits;
  • 当你需要做多文件改动、增加大型功能模块或跑终端命令等,启用 Agent Mode。

AI 只是辅助,我们才是项目的主导者,无论在任何模式下,你都随时拥有最终的决定权。与 AI 协作的关键是:在发起需求时确保“意图”足够清晰,并在生成代码后自行进行必要的审查和测试。

如何开启 Copilot Edits 和 Agent Mode

Copilot Edits

  1. 在 VS Code 中打开 Copilot Chat 窗口。
  2. 点击「Edit with Copilot」按钮,进入 Edits 视图。
  3. 把需要修改的文件加入工作集(working set),未纳入工作集的文件默认不会被修改。
  4. 向 Copilot 发出修改需求,比如“请把用户验证逻辑改成基于 JWT 的方式,并把相关函数命名统一为 verifyUserToken”。
  5. 接受修改前,一定要查看 diff,确认无误后再点「接受更改」。

Agent Mode

  1. 需使用 VS Code 1.99 或更高版本。
  2. 在 Copilot Chat 中将模式切换为「Agent」。
  3. 描述你想实现的复杂功能,例如“创建一个带有打字机动画、上下命令历史、tab 补全、主题切换功能的 Terminal 界面。”
  4. Copilot 会在后端自动迭代并提出改动建议,你需要对每一步改动进行审核并决定是否执行。
  5. 如需个性化定制,可在 VS Code 中针对工程的特定需求编写自定义提示(custom instructions)。

号召:开源贡献者可免费使用 GitHub Copilot

在国内外,你的个人和团队如果对开源社区有贡献——比如在 GitHub 上维护或积极参与开源项目,就有机会免费申请 GitHub Copilot,这对提高工作效率、让团队更专注于关键业务逻辑而言非常有帮助。

申请地址(Copilot for Open Source)

建议把你的 GitHub Profile、开源项目链接、贡献度、Stars 等信息准备好,申请通过后就可以体验到 Copilot 的强大功能。

别担心! 只要你确实为开源生态做出过贡献,GitHub 官方是很鼓励你去申请 Copilot 的免费使用资格的。需要注意的是该免费资格是按月赋予的!

结语:拥抱 AI 工具,让开发更高效

从最初的 GitHub Copilot 到如今逐渐涌现的各种 AI 编程工具,比如 CursorAmazon CodeWhispererGoogle Gemini Code Assist、以及基于大语言模型的各种插件等等,AI 编程助手已经不再是新鲜事。Cursor 的特点在于提供类似 IDE 的环境,可直接在其编辑器里集成对话式的 AI 辅助;Replit 的 Ghostwriter 则充分利用 Replit 在线编程环境的优势,为多人协作和实时预览提供极大方便。和 Copilot 相比,这些工具可能在对话交互深度、代码质量、或对特定语言和生态的支持范围上各有所长。但总体而言,它们都在让开发者摆脱那些冗杂、重复、机械的编程工作,从而腾出更多时间和精力进行架构和创新。

“AI 不会取代程序员,但会取代那些拒绝与 AI 合作的程序员。”

如果你正在或即将投入开源项目的开发,或者在商业项目中想要挖掘更多高阶生产力,都推荐你去尝试并深入学习这些 AI 编程工具。在 GitHub 官方文档 中,你还可以找到一份从入门到进阶的 Copilot 教程系列——从最初的安装到高级用法,让你快速掌握 Copilot 的精髓。也欢迎试用其他同类工具,对比各种功能优缺点,探索适合自己团队的工作流。

让我们一起拥抱 AI,做更高效的开发者吧!

如果你对 AI 编程、云原生和开源技术感兴趣,也欢迎访问我的个人博客 jimmysong.io,一起交流讨论。祝大家编码愉快,效率倍增!