MoreRSS

site iconJimmy Song | 宋净超修改

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

Inoreader Feedly Follow Feedbin Local Reader

Jimmy Song | 宋净超的 RSS 预览

从 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,一起交流讨论。祝大家编码愉快,效率倍增!

超越 Sidecar:深入解析 Istio Ambient Mode 的流量机制与成本效益

2025-03-22 14:45:55

欢迎阅读我的这篇博客——“超越 Sidecar:深入解析 Istio Ambient Mode 的流量机制与成本效益”。本文内容源自我在 KCD 北京的一次演讲。主要探讨的是 Istio 全新推出的一种数据面模式 —— Ambient Mode。它的核心理念是去除 Sidecar,减少资源开销与运维复杂度。本文将带大家了解 Ambient Mode 的出现背景、核心组件、流量路径机制以及与现有 Sidecar 模式的对比,从而帮助你快速评估并上手这项新特性。

点击查看幻灯片

为什么关注 Ambient Mode?

首先,我们来思考一个问题:为什么要关注、甚至尝试这种新模式?Sidecar 在服务网格里一直都用得好好的,为什么要“去 Sidecar”呢?

让我们看看当前服务网格面临的一些问题和挑战。

服务网格的挑战

  • Sidecar 代理带来的 资源开销运维复杂度
  • 升级重启 Envoy 时,常常需要连带重启所有 Pod
  • 越来越多对 高性能、低成本 的需求

思考:有没有一种方式在保留服务网格核心能力(安全、可观测、流量控制)的同时,减少对每个 Pod 的侵入和额外资源消耗?

服务网格的几种部署模式

image
代理的位置

服务网格架构一直在探索代理部署位置的多种可能性。例如:

  • Sidecar:每个 Pod 内跑一个 Envoy。
  • Ambient:将代理从 Pod 中剥离到节点级(即本篇要谈的模式)。
  • Cilium Mesh:利用 eBPF 在内核空间做 L4,然后结合 Envoy 提供 L7 功能。
  • gRPC:直接将网格能力集成到 SDK 中。

这些模式在功能、安全、性能和管理复杂度上都有不同的侧重。Istio Ambient Mode 则是针对 Sidecar 带来的高资源消耗和运维成本,而提出的新尝试。

Ambient Mode 的诞生

  • Istio 的新一代架构,移除 Sidecar,通过 ztunnel + Waypoint Proxy 实现数据面的轻量化。
  • 节省资源、降低运维复杂度。
  • 依然支持 mTLS、策略管控,并为需要 L7 功能的流量提供可选的 Waypoint Proxy
image
部署模式象限

以下表格是对比常见服务网格部署模式的一些简要特点:

模式 安全性 效率 可管理性 性能
Sidecar 模式 高安全性,隔离的代理 资源使用率高 集中化管理但较为复杂 增加一定延迟
Ambient 模式 通过 ztunnel 提供安全性,仍在发展中 更高效,共享代理 管理更简单但功能在完善中 良好;跨可用区时需注意网络开销
Cilium mesh 中等安全性,基于 eBPF 内核级效率 配置复杂 可视场景不同而异
gRPC 应用集成安全,依赖应用自身 高效 更新管理复杂 低延迟,适用于实时场景

Istio Ambient Mode 核心概念

接下来我们正式进入第二部分,深入看看 Ambient Mode 的具体组件,包括 ztunnel、Waypoint Proxy 以及 Istio CNI 在其中扮演的角色。

Ambient Mode 的核心组件

  1. ztunnel (L4)
    • 以 Node 级代理的方式运行
    • 负责 透明流量拦截mTLS 加密
    • 适用于大部分只需 L4 转发的流量
  2. Waypoint Proxy (L7)
    • 可选部署(根据命名空间 / Service / Pod 粒度灵活配置)
    • 处理 HTTP / gRPC 等高级功能(鉴权、路由、可观测等)
  3. Istio CNI
    • 取代 istio-init 容器,负责流量劫持
    • 兼容 Sidecar 模式和 Ambient 模式
    • 允许在非特权模式下为 Pod 设置流量重定向

Ambient 模式整体架构

image
Istio Ambient 模式架构

在 Ambient 模式下,Istio 数据面可分为两层:

  1. 安全层 (ztunnel):每个节点部署一个轻量级 L4 代理。
  2. 可选的 L7 层 (Waypoint Proxy):需要 HTTP/gRPC 代理时才部署。

Control Plane 依然由 Istiod 提供,主要负责给 ztunnel、Waypoint 下发配置和证书。

Waypoint Proxy 部署策略

  • Namespace 级(默认):适用于该命名空间下所有 Workload
  • Service 级:仅特定关键服务需要 L7
  • Pod 级:更精细化控制
  • 跨 Namespace:可以使用 Gateway 资源共享

Istio CNI

  • 流量拦截:取代 istio-init 容器,使安装更加清晰简洁。
  • 支持两种模式:兼容 Sidecar 模式Ambient 模式
  • 非特权模式兼容性:允许 Pod 运行在无特权模式下,增强安全性。
  • CNI 链接(Chaining):通过添加 Istio CNI 扩展节点的 CNI 配置。
  • Pod 内部流量重定向(Ambient 模式)
    • 在 Pod 的网络命名空间内使用 iptables REDIRECT 规则。
    • 创建 Pod 内部的 socket 以拦截和代理流量。

这张图简单示意了 Istio CNI 如何与 Kubernetes 本身的网络插件(如 Calico、Cilium 等)组合在一起。它修改了本机的 CNI 配置,增加了 CNI 链,在 Kubernetes 分配完 Pod IP 后,紧接着就会执行 Istio CNI 的拦截逻辑,把网络流量规则注入到 Pod netns。并且为不同模式中 Pod 配置不同的 iptables 规则。 这样就与原本的 CNI 配置(包括网络策略)形成一个链式流程,不会相互冲突。

image
Istio CNI 插件的运行步骤

Istio CNI 插件工作原理

这张图详细描绘了当 Pod 启动时,Istio CNI 会怎么做:

image
Istio CNI 插件工作原理
  1. 它会进入 Pod 的网络命名空间,创建一套 iptables 规则,把流量劫持到 ztunnel 监听的 socket 上。
  2. 不再需要在每个 Pod 里注入 init 容器,也不需要特权权限,这就让整体部署更干净、也更安全。
  3. ztunnel会在pod的网络命名空间中建立一个socket,并且为节点上的每个pod都会建立一个。

流量路径与关键机制

介绍完组件之后,我们来看看最核心的“流量路径”。zTunnel 和 Waypoint 究竟是怎么拦截并转发流量的?我们会从透明流量拦截、HBONE 协议等角度进行解析。

透明流量拦截

在 Ambient 模式中,Istio CNI 会在 Pod 网络命名空间中注入 iptables 规则,将出站流量透明拦截到所在节点的 ztunnel 进程。之后由 ztunnel 决定是直接进行 L4 转发,还是将流量转发至 Waypoint Proxy 做进一步的 L7 处理。

如图所示,Kubelet 在节点上启动了一个 Pod,这个事件被 Istio CNI Agent 监听到,Istio CNI Agent 进入 Pod 的网络空间,设置 iptables 规则将流量重定向到本地 socket,并将 Pod 的文件描述符(FD)发送为 ztunnel。ztunnel 获取到 FD 之后就可以在 Pod 的网络空间中创建 socket。

Pod 在发送流量时,本该直连目标地址,但是 iptables 规则会把它拦截到本节点的 ztunnel 进程里,然后 ztunnel 决定这条流量需不需要交给 Waypoint 做 L7 代理。 如果不需要,就直接在 L4 层把它加密转发到目标 Pod;如果要 L7,例如鉴权,就再把流量隧道给 Waypoint。

image
透明流量拦截

数据包生命周期概览

  1. Pod → ztunnel:Pod 的流量先被 CNI 拦截到本节点 ztunnel。
  2. ztunnel:解析目标地址并进行 mTLS 加密。
  3. (如需要 L7 策略)ztunnel → Waypoint Proxy:HTTP 鉴权、路由等操作。
  4. Waypoint Proxy:完成 L7 处理后,再发回 ztunnel。
  5. ztunnel:解封装或继续转发至目标节点 ztunnel。
  6. 到达目标 Pod:目标节点 ztunnel 最终将流量交给目标 Pod。

HBONE 协议

Ambient 模式中,zTunnel 与 Waypoint 之间使用 HBONE (HTTP/2 + CONNECT) 协议来建立安全隧道,实现 mTLS 加密 和多路复用,减少额外的连接开销,简化代理转发流程。

image
HBONE 协议

下面是一个简化的 HBONE CONNECT 请求示例,利用 x-envoy-original-dst-hostx-istio-auth-userinfo 等头信息来传递路由和身份认证所需上下文。

:method: CONNECT
:scheme: https
:authority: Pod_B_IP:9080
:path: /api/v1/users?id=123
x-envoy-original-dst-host: Pod_B_IP:9080
x-forwarded-proto: hbone
x-istio-attributes: ...
...

在这个示例里,假设 ztunnel A 需要把流量发送给 目标节点 B,我们可以看到外层的 TCP 连接其实是从 ztunnel_A_IP:52368 连到 Node_B_IP:15008。这是 ztunnel A 和 ztunnel B 之间的隧道端口,15008 就是 HBONE 监听端口。

进入到 HTTP/2 层后,就会有一个 CONNECT 请求,里面的 :authority 显示的是 Pod_B_IP:9080,表示实际上要连到 Pod B 的 9080 端口。x-envoy-original-dst-host 里也能看出相同信息。

同时我们看到了一些自定义头,比如 x-forwarded-proto、x-istio-attributes 等,用来给目标 ztunnel 或后续代理带去更多上下文和安全验证信息。

可以把这个理解为:在 HTTP/2 CONNECT 之上,流量就像加了一个“内层”隧道,把应用层的请求(例如 /api/v1/users?id=123)封装在这里面,然后在 ztunnel B 端解封装并转发到真实的 Pod B。

整个过程对应用来说是透明的,但对我们来说,通过查看这种 CONNECT 请求头,可以了解 Ambient 模式如何在 HTTP/2 层做流量路由和身份认证。这就是为什么说 HBONE 比传统的 Sidecar-to-Sidecar通信更加灵活,也更便于做 mTLS 以及 L7 扩展。

同节点上的加密流量

如果源 Pod 和目标 Pod 恰好在同一个节点上,流量会走 ztunnel 的 L4 加密流程。 这里显示,ztunnel 是使用 DaemonSet 部署在每个节点上的,并且使用了host Network,共享主机的网络。Istio CNI 将 Pod 的出站流量拦截到 ztunnel的15001端口,如果源和目的 pod 在同一个节点上,ztunnel 直接在内部完成加解密后将流量发送到目的地 pod。

如果需要 L7 的流量处理,比如鉴权,ztunnel 就会与 Waypoint 代理建立 HBONE 隧道,经过 Waypoint 代理的转发到目的 Pod。

image
同节点上的加密流量

跨节点的加密流量(L4)

这是跨节点的情况,也就是最常见的场景:

源节点的 ztunnel 把流量通过 HBONE 隧道加密后发给目标节点的 ztunnel;目标节点 ztunnel 解封装,再把明文流量递给目标 Pod。只要是纯 L4 无需 L7,就不必加一层 Waypoint,减少了代理链路。

image
跨节点的加密流量(L4)

跨节点的加密流量(L7)

当我们需要 L7 处理时,流量就会多经过一下 Waypoint。也就是:

  • 源 ztunnel 先把流量隧道给 Waypoint;
  • Waypoint 在 HTTP 层做鉴权、路由等;
  • Waypoint 再用 HBONE 把流量发给目标 ztunnel;
  • 目标 ztunnel 解封装后给目标 Pod。
image
跨节点的加密流量(L7)

这个流程比 L4 多了一次代理,但好处是只有特定流量才会被 L7 代理解析,减少不必要的开销。

兜底流量(防止流量逃逸)

对于非 Istio网格内部的流量,通过 Pod IP和端口直接访问 Pod时,为了防止这些流量逃出 ztunnel的掌控,也需要拦截这些流量。如果流量是访问的应用端口,通过判断数据包上是否带有 0x539 标记,如果没有,则将其转发到 ztunnel 监听的 15006 明文端口,经 ztunnel 处理后会带上 0x539 标记,然后就可以访问应用的目标端口了;如果流量的目的端口是 15008,那么实际上就会被 ztunnel 监听和处理,判断 HBONE 协议。

image
来自非mesh内部的流量

L4 与 L7 流量差异

流量类型 处理位置 示例场景
L4 ztunnel(透明转发) TCP 级别流量,不需应用层策略
L7 ztunnel → Waypoint Proxy HTTP/gRPC 需要鉴权、熔断、路由、可观测等高级功能

对于大部分只需 TCP 层加密和转发的流量,Ambient Mode 仅通过 ztunnel 即可;只有在需要 HTTP 层策略时才会额外经过 Waypoint。

Ambient Mode vs. Sidecar Mode

有了对 Ambient 的了解后,我们还是得和原有的 Sidecar 模式做对比,来看看哪些功能还不完善,哪些场景更适合 Ambient。

Ambient 模式的限制

与传统 Sidecar 模式相比,Ambient 目前仍有一些不完善之处:

  • 混合使用 Sidecar 与 Ambient 时,难以对单个 Pod 做精准代理定制(例如 EnvoyFilter)。
  • 多集群多网络、以及 虚拟机 工作负载的支持还不够完善,生产环境使用需谨慎。
  • 一些深度定制(例如 WASM 插件)目前无法在 Ambient 下直接一对一实现。

功能与差异对比

指标 Sidecar 模式 Ambient 模式
代理位置 每个 Pod 都运行 Envoy Sidecar Node 级 ztunnel + 可选的 Waypoint Proxy
资源开销 在大规模场景下 CPU/内存消耗相对更高 相对更低:代理共享在节点/命名空间级
运维复杂度 升级 Sidecar 需滚动更新所有关联 Pod,操作较繁琐 部署/升级集中在少数组件(ztunnel / Waypoint),运维更简单
性能 每个 Pod 都有 Envoy,使得隔离性更强,但整体有额外代理开销 L4 性能较好,L7 场景需要多经过一次 Waypoint 转发
功能完整度 成熟稳定,支持多集群、VM、混合网络 尚在演进,多网络、VM 等高级场景支持仍在完善
典型使用场景 注重严格隔离或依赖特定的 EnvoyFilter、WASM 插件等深度定制 大规模集群、需要轻量化管理且大部分流量以 L4 为主的场景

选择建议

  1. 若已有 Sidecar 架构且依赖大量成熟特性:可先继续使用 Sidecar。
  2. 追求 资源节省运维简化 且大部分流量仅需 L4:可尝试 Ambient Mode
  3. 如果部分应用仍需保留 Sidecar,可考虑 混合部署,但需额外规划 Sidecar / Ambient 的边界和策略。

总结

好的,最后我们来总结一下 Ambient Mode 的优缺点,以及当前适合哪些场景。

核心要点回顾

  1. Ambient Mode:通过移除 Sidecar,降低每个 Pod 的代理负担,显著降低资源和运维成本。
  2. ztunnel + Waypoint 架构:需要 L7 功能时才启用 Waypoint,其他流量以 L4 方式快速转发。
  3. 虽然官方已宣布 Ambient Mode GA,但对于 多集群 / VM / 多网络 等仍需进一步观察、测试。
  4. 适用场景:大规模集群 + 主要以 L4 流量为主,对资源和管理要求高的团队可以重点关注。

你也可以通过 jimmysong.io 网站找到更多云原生相关的文章和实践分享。如果对此文或 Istio 有任何疑问,欢迎给我留言或在社区中交流。谢谢!