Cilium 透明代理注入(Proxy Injection)与独立 Envoy DaemonSet 部署指南
2026/9/14 17:50:34 网站建设 项目流程

Cilium 透明代理注入(Proxy Injection)与独立 Envoy DaemonSet 部署指南

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

Cilium 能够透明地将 Layer 4 代理注入到任何网络连接中,为上层网络策略(如 DNS 策略与 L7 策略)的强制执行提供基础设施。本文以 Documentation/security/network/proxy/index.rst 和 envoy.rst 为主体,结合仓库源码(pkg/proxy、pkg/envoy、install/kubernetes)与 proxylib 架构图,系统讲解 Cilium 代理注入的工作原理、Envoy 作为宿主机代理的两种部署模式(Agent Pod 内嵌与独立 DaemonSet),以及启用和配置cilium-envoyDaemonSet 的完整操作步骤。读完后你将掌握如何在 Kubernetes 集群中选择、启用并运维 Cilium 的 Envoy 代理,从而为 L7 网络策略、Ingress、Gateway API 和 L7 协议可见性提供稳定的代理底座。

一、什么是 Proxy Injection

Cilium 具备将 Layer 4 代理透明注入到任意网络连接的能力。这里的"透明"意味着:应用 Pod 无需感知代理的存在,其发出的流量会被 Cilium 的 datapath 层(BPF)捕获,并转发给代理处理,处理完成后再由代理把流量送达真正的对端。这一机制构成了 Cilium 强制执行更高层网络策略的基础设施,官方文档明确说明它是 DNS 策略 与 L7 策略 的底层支撑。

.. _proxy_injection: Proxy Injection --------------- Cilium is capable of transparently injecting a Layer 4 proxy into any network connection. This is used as the foundation to enforce higher level network policies (see DNS based and l7_policy).

目前可以注入的代理类型在文档 toctree 中给出:

.. toctree:: :maxdepth: 1 :glob: envoy

即当前唯一被注入的宿主代理是Envoy(见 envoy.rst)。Cilium 将 Envoy 作为宿主机代理,用于执行集群网络策略中规定的 HTTP 及其他 L7 策略。

1.1 proxylib:策略匹配与访问日志的数据面

从文档_static目录中的架构图(proxylib_key_functions.png 与 proxylib_logical_flow.png)可以看到,Cilium 的代理库(proxylib)负责在 Envoy 中解析、匹配与记录代理流量:

  • Downstream / Upstream Socket:分别承载客户端与服务器方向的recv()/send()数据。
  • <NewProto>Parser.OnData():核心解析器,通过返回PASS/DROP/MORE控制数据流,决定请求放行、丢弃或需要更多数据。
  • Matches():测试请求是否匹配策略映射(Policy Map)中的规则。
  • <NewProto>RuleParser():解析并验证自定义协议规则(如 HTTP/HTTP2),解析结果存入 Policy Map。
  • Inject():当策略判定为DROP时插入错误消息。
  • Log():向 Cilium Access Log 写入访问日志条目,供 L7 协议可见性使用。

从逻辑流程上看(proxylib_logical_flow.png),Cilium Agent 生成 Policy JSON(含 endpointSelector、端口与协议规则),通过 Policy Config 推送给 Envoy;TCP 连接进入 BPF 层后被<NewProto>Parser按策略允许/拒绝,放行流量转发至目标 Pod(如app=newproto-server)。

1.2 数据面与控制面的分离:Cilium Agent ↔ Envoy

在现代 Cilium 代码库中,代理注入的控制面位于 pkg/proxy(redirect.goproxy.godns.goenvoyproxy.goproxyports.go),而 Envoy 的 xDS 服务器、访问日志服务器与进程管理位于 pkg/envoy。

Cilium Agent 与 Envoy 之间的通信全部通过UNIX domain socket完成,这一点在两种部署模式下保持一致,具体包括:

  • 流式传输访问日志(access log,用于 L7 协议可见性):见 pkg/envoy/accesslog_server.go,其中socketPath使用util.GetAccessLogSocketPath(envoySocketDir),监听类型为unixpacket,并设置 socket 权限0o660(属主与属组可读写)。
  • 通过 xDS 协议更新配置:见 pkg/envoy/cell.go,Envoy 的 xDS 服务器(newXDSServer/newADSServer)在启动后作为后台 job 运行,负责向 Envoy 下发监听器、集群、路由等配置。
  • 访问 Envoy admin 接口:见 pkg/envoy/standalone_envoy.go,admin 接口也通过 UNIX socket(util.GetAdminSocketPath(util.GetSocketDir(config.runDir)))暴露。

xDS(x Discovery Service)是 Envoy 原生的动态配置协议,Cilium 借助它把网络策略翻译成 Envoy 的 Listener / Cluster / Route 配置;admin 接口则用于查询server_info、下发 quit 指令等运维操作(见 pkg/envoy/envoyadminclient.go)。

二、Envoy:Cilium 的宿主机 L7 代理

随 Cilium 一起分发的 Envoy 代理是精简构建的:仅包含最少的 Envoy 扩展,并加入了 Cilium 自定义的策略强制过滤(custom policy enforcement filters)。该代理随 Cilium 镜像一起发布(images/cilium/images/runtime/等构建产物),作为 Cilium 的宿主代理执行集群网络策略中规定的 HTTP 与其他 L7 策略。

Envoy 版本兼容性矩阵请参考 Cilium Proxy 官方文档(github.com/cilium/proxy#version-compatibility-matrix,原文 envoy.rst 有指向该仓库的说明)。

2.1 何时会启动 Envoy

当以下任一 L7 功能在 Kubernetes 集群中启用或安装时,Cilium Agent 会在 Cilium Agent Pod 内部启动一个独立的 Envoy 进程:

  • Ingress(集群入口流量管理)
  • Gateway API(基于 Kubernetes Gateway API 的南北向流量治理)
  • 含 L7 功能的 Network Policy(如 HTTP/HTTPS/TLS 等七层网络策略)
  • L7 协议可见性(L7 Protocol Visibility,通过访问日志展示七层流量)

在该内嵌模式下,这个 Envoy 实例负责代理该节点上所有匹配的 L7 请求。因此,被 L7 策略覆盖的流量依赖于 Cilium Agent Pod 的可用性——Agent 重启或升级期间,代理流量会受影响。

2.2 两种部署模式对比

维度内嵌模式(默认)独立 DaemonSet(cilium-envoy
Envoy 进程位置Cilium Agent Pod 内部独立的cilium-envoyDaemonSet
生命周期与 Agent 同生命周期独立生命周期
通信方式UNIX domain socketUNIX domain socket(与内嵌一致)
Agent 重启影响代理流量受影响无影响(Agent 重启不影响 Envoy 代理的在线流量)
资源隔离Envoy 与 Agent 共享限制CPU/内存限制独立,便于性能隔离
日志与 Agent 日志混合Envoy 应用日志独立
健康探针内嵌专用健康探针(startup/liveness/readiness,见 install/kubernetes/cilium/templates/_extensions.tpl)
部署时机需要时按需启动安装时显式部署

三、部署cilium-envoy独立 DaemonSet

3.1 启用方式

要将 Envoy 代理部署为独立生命周期的 DaemonSet(名为cilium-envoy),在安装 Cilium 时设置 Helm 值envoy.enabled=true

helm install cilium cilium/cilium \ --namespace kube-system \ --set envoy.enabled=true

关于envoy.*前缀的所有可配置键的详细说明,请参见 Helm 参考文档 中envoy.*相关条目。在 install/kubernetes/cilium/README.md 中记录着该值的语义:

envoy.enabledstringtruefor new installation — Enable Envoy Proxy in standalone DaemonSet. This field is enabled by default for new installation.

即:对于新安装,envoy.enabled默认即为true。模板 install/kubernetes/cilium/templates/_helpers.tpl 中的逻辑会根据upgradeCompatibility(升级兼容性配置)决定返回用户显式指定的envoy.enabled值还是默认值,用于兼容旧版本的升级场景。

3.2 两种模式下的通信方式与 SELinux 注意点

无论是内嵌模式还是 DaemonSet 模式,Cilium Agent 与 Envoy 的通信都通过 UNIX domain socket 进行,覆盖:

  • 流式访问日志(L7 协议可见性)
  • 通过 xDS 更新配置
  • 访问 admin 接口

由于使用 UNIX domain socket,当宿主机启用 SELinux 时,Envoy DaemonSet 与 Cilium Agent 需要具有兼容的类型(SELinux type)。在未特别指定其他类型的情况下,两者都使用高特权类型spc_t。Red Hat OpenShift Container Platform 默认启用 SELinux,因此在该平台上运行cilium-envoyDaemonSet 时需要特别注意这一兼容性要求。

3.3 独立 DaemonSet 的潜在收益

采用独立cilium-envoyDaemonSet 模式,可以获得以下收益(原文 envoy.rst 所列,并结合 Helm 模板佐证):

  1. Cilium Agent 重启(如升级)不影响 Envoy 正在代理的在线流量——代理生命周期与 Agent 解耦,这是最大的收益。
  2. Envoy 补丁版本升级不影响 Cilium Agent——可以独立滚动升级 Envoy 而不动 Agent。
  3. Envoy 与 Cilium Agent 拥有独立的 CPU 和内存限制,实现性能隔离。
  4. Envoy 应用日志不与 Cilium Agent 日志混合,日志排障更清晰。
  5. Envoy 代理拥有专用的健康探针——install/kubernetes/cilium/templates/_extensions.tpl 中允许为cilium-envoy容器自定义 startup probe、liveness probe 与 readiness probe。
  6. 在 Cilium 安装时显式部署 Envoy 代理(相比内嵌模式的按需启动),部署时机更明确、更可控。

3.4 可扩展的部署自定义点

从 Helm 模板 install/kubernetes/cilium/templates/_extensions.tpl 可以看出,cilium-envoyDaemonSet 提供了丰富的打包级自定义入口,包括:lifecycle hooks、init containers、额外启动参数、额外环境变量、额外卷挂载、额外 hostPath 挂载、容器端口、更新策略(update strategy)以及 Pod 亲和性(affinity)。在生产环境中,你可以据此为 Envoy 配置独立的资源配额、节点亲和与滚动更新策略。

另外,若你启用了 Envoy 的 Prometheus 监控,install/kubernetes/cilium/templates/cilium-agent/servicemonitor.yaml 会在envoy.enabledenvoy.prometheus.serviceMonitor.enabled为真时,为 Envoy 生成 ServiceMonitor 供 Prometheus 抓取指标。

四、Agent 与 Envoy 的交互链路(源码视角)

4.1 访问日志:UNIX socket 流式传输

pkg/envoy/accesslog_server.go 中,Cilium Agent 作为服务端在envoySocketDir下创建访问日志 socket:

  • 启动时先移除旧的 socket 文件(os.Remove(s.socketPath),见第 94-95 行),再以net.ListenUnix("unixpacket", ...)监听(第 98 行);
  • 设置权限0o660(第 105 行)并将 socket 的属组改为proxyGID(第 109 行);
  • 每个 Envoy listener 都会在该 socket 上建立独立连接(第 70-72 行注释),Cilium 为每个连接启动 goroutine 并发处理访问日志(第 85 行),支持多连接同时流式上报。

4.2 xDS:动态下发改配置

pkg/envoy/cell.go 中,Cilium 的 xDS 服务器根据配置选择newADSServer(ADS 聚合发现服务)或newXDSServer,并在启动后以后台 job(job.OneShot("xds-server", ...))持续运行。Envoy 通过 xDS 协议从 Agent 获取 Listener/Cluster/Route 等配置,从而将 Cilium Network Policy 中的 L7 规则实时翻译为 Envoy 的转发行为。

4.3 Admin 接口:通过 UNIX socket 运维

pkg/envoy/standalone_envoy.go 中,独立模式下 Envoy 的 admin 接口同样挂载在 UNIX socket 上(util.GetAdminSocketPath(util.GetSocketDir(config.runDir))),并配置Pipe类型的上游集群(第 543-570 行)。Agent 通过 pkg/envoy/envoyadminclient.go 的EnvoyAdminClient访问envoy-admin地址(第 24 行),可执行查询server_info(第 151 行)与下发quit(第 55 行)等管理操作;在优雅关闭流程中,Agent 会先调用admin.quit()再结束 Envoy 进程(第 264 行)。

五、小结

Cilium 的透明代理注入能力是其 L7 网络策略体系的基石:BPF datapath 将流量导向宿主代理,Cilium Agent 通过 UNIX domain socket 与 Envoy 完成配置下发(xDS)、访问日志回流与 admin 运维。当集群中启用 Ingress、Gateway API、L7 Network Policy 或 L7 协议可见性时,Envoy 即以独立进程形式承担该节点全部匹配 L7 请求的代理职责。

对于生产环境,若希望将代理流量与 Agent 生命周期解耦(升级、重启互不影响),可以通过envoy.enabled=true启用cilium-envoy独立 DaemonSet,并利用其独立的资源限制、健康探针、日志与显式部署时机获得更可控的运维体验。需要注意在启用 SELinux 的平台(如 Red Hat OpenShift)上保持 Agent 与 Envoy 使用兼容的 SELinux 类型(默认均为spc_t)。

进一步阅读:

  • Proxy Injection 章节文档
  • Envoy 部署详解
  • Cilium 代理实现源码
  • Envoy 控制面实现源码
  • Helm 参考(envoy.* 配置键)

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询