news 2026/9/14 22:33:58

Cilium Gateway API 实战:用 BackendTLSPolicy 为 Gateway 到后端服务的流量启用 TLS

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cilium Gateway API 实战:用 BackendTLSPolicy 为 Gateway 到后端服务的流量启用 TLS

Cilium Gateway API 实战:用 BackendTLSPolicy 为 Gateway 到后端服务的流量启用 TLS

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

本篇基于 Cilium 仓库中的Documentation/network/servicemesh/gateway-api/backendtlspolicy.rst示例文档展开,完整演示如何在 Cilium Gateway 中利用 Gateway API 的BackendTLSPolicy资源,让网关(数据面 Envoy)与后端服务之间建立并验证 TLS 连接。读完本文,你可以掌握:如何用mkcert生成演示证书、如何将证书装入 Kubernetes Secret/ConfigMap、如何把后端echo-server切换为 TLS 模式,以及 Cilium operator 侧是如何校验BackendTLSPolicy并把策略下发到数据面的。

背景:BackendTLSPolicy 解决什么问题

Cilium 的 Gateway API 支持分两段处理 TLS:客户端到 Gateway 的 TLS(由 Gateway Listener 的tls字段处理)与 Gateway 到后端服务的 TLS。BackendTLSPolicy属于后者,它挂在 Gateway 的命名空间中,通过targetRefs指向一个后端 Service,告诉网关"访问该后端时必须使用 TLS 连接,并可以用指定 CA 验证后端证书"。

该示例使用 Gateway API 社区的echo-server演示应用(镜像gcr.io/k8s-staging-gateway-api/echo-basic)。这个应用读取环境变量TLS_SERVER_CERTTLS_SERVER_PRIVKEY:当两个变量都设置时,它会额外在 8443 端口启动 TLS 监听;且当请求经过 TLS 时,响应 JSON 中会多出一个tls字段,用于验证加密确实生效。整个任务使用自签名 CA,仅用于演示目的,不要直接照搬到生产环境

第一步:部署 echo-server 与 Gateway/HTTPRoute

示例清单位于 echo-server.yaml 与 echo-server-gatewaypi-httproute.yaml,直接kubectl apply即可。核心内容如下:

Service 与 Deployment(初始为纯 HTTP,3000 端口):

apiVersion: v1 kind: Service metadata: name: backend labels: app: backend service: backend spec: ports: - name: http port: 3000 targetPort: 3000 selector: app: backend --- apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 1 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: serviceAccountName: backend containers: - image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e imagePullPolicy: IfNotPresent name: backend ports: - containerPort: 3000 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace

Gateway 与 HTTPRoute(gatewayClassName: cilium,即由 Cilium 处理该 Gateway):

apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway spec: gatewayClassName: cilium listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: my-gateway hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: /

用 curl 验证基线(把<GATEWAY_IP_ADDRESS>替换为你的 Gateway 地址):

$ curl -v --resolve www.example.com:80:<GATEWAY_IP_ADDRESS> http://www.example.com/get

正常应返回请求信息的 JSON,例如:

{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": ["*/*"], "User-Agent": ["curl/8.20.0"], "X-Envoy-Internal": ["true"], "X-Forwarded-For": ["172.19.0.1"], "X-Forwarded-Proto": ["http"], "X-Request-Id": ["bb913f3e-7538-4873-88e4-25499fe5b3ff"] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-86c6c76f-ptczl" }

响应中出现了X-Envoy-Internal: true头,说明请求确实经过了 Cilium 内置的 Envoy 数据面。此时尚无tls字段,因为后端走的是明文 HTTP。

第二步:用 mkcert 生成演示证书

需要安装mkcert(上游项目,文档通过github-mkcert链接引用)。它会生成一个本地自签名 CA,并为指定域名签发该 CA 签名的证书。在本地目录执行:

mkcert www.example.com

完成后当前目录会生成两个文件:

  • www.example.com.pem—— 服务端证书;
  • www.example.com-key.pem—— 服务端私钥。

再执行一次mkcert -install(或按 mkcert 提示)可以信任本地 CA;本示例不走系统信任,而是把 CA 通过 ConfigMap 交给 Gateway 做后端校验,因此无需安装到系统。

再次强调:自签名 CA 只用于演示,生产环境应使用正式的证书签发体系(如 cert-manager、云厂商证书服务等)。

第三步:把证书和 CA 装入集群

把服务端证书与私钥存入一个 TLS Secret:

kubectl create secret tls example-cert --key=www.example.com-key.pem --cert=www.example.com.pem

把 CA 证书存入 ConfigMap,键名必须是ca.crt

kubectl create configmap example-ca --from-file=ca.crt=www.example.com.pem

键名ca.crt不是可有可无的约定——Cilium operator 的校验逻辑会显式检查这一点。在 operator/pkg/gateway-api/policychecks/backendtlspolicy.go 中可以看到:

  • ConfigMap 中不存在ca.crt键时,策略被标记为拒绝,原因是InvalidCACertificateRef(消息为 "CA Certificate ConfigMap does not contain aca.crtkey");
  • ca.crt的内容还会经过helpers.IsValidPemFormat校验,不是合法 PEM 编码的证书同样会被拒绝("does not contain at least one valid PEM-encoded certificate")。

此外该校验还要求:CACertificateRefswellKnownCACertificates不可同时设置;CACertificateRefs最多只能有一个引用;引用必须是group: ''kind: ConfigMap,否则会以InvalidKind拒绝(见同文件 ValidateSpec)。这些约束解释了为什么后文的BackendTLSPolicy示例中group为空字符串、kindConfigMap

第四步:把后端切换为 TLS 模式

kubectl patchbackendDeployment 挂载证书 Secret,并注入两个环境变量:

kubectl patch deployment backend --type=json --patch ' - op: add path: /spec/template/spec/containers/0/volumeMounts value: - name: secret-volume mountPath: /etc/secret-volume - op: add path: /spec/template/spec/volumes value: - name: secret-volume secret: secretName: example-cert items: - key: tls.crt path: crt - key: tls.key path: key - op: add path: /spec/template/spec/containers/0/env/- value: name: TLS_SERVER_CERT value: /etc/secret-volume/crt - op: add path: /spec/template/spec/containers/0/env/- value: name: TLS_SERVER_PRIVKEY value: /etc/secret-volume/key '

说明两点:

  • Secret 中的tls.crt/tls.key两个键分别映射为容器内/etc/secret-volume/crt/etc/secret-volume/key
  • 环境变量TLS_SERVER_CERTTLS_SERVER_PRIVKEYecho-basic镜像识别 TLS 模式的开关,设置后应用会在 8443 端口启用 TLS 监听。

然后更新backendService,把端口暴露为 443 并把流量引到后端的 8443:

apiVersion: v1 kind: Service metadata: labels: app: backend service: backend name: backend spec: selector: app: backend ports: - name: https port: 443 protocol: TCP targetPort: 8443

注意https这个端口名后面会被BackendTLSPolicysectionName引用。

第五步:创建 BackendTLSPolicy 并指向 443

创建策略,告诉 Cilium Gateway 以 TLS 方式访问该后端,并用example-caConfigMap 中的 CA 验证后端证书、期望主机名为www.example.com

apiVersion: gateway.networking.k8s.io/v1 kind: BackendTLSPolicy metadata: name: enable-backend-tls namespace: default spec: targetRefs: - group: '' kind: Service name: backend sectionName: https validation: caCertificateRefs: - name: example-ca group: '' kind: ConfigMap hostname: www.example.com

字段要点:

  • spec.targetRefs:定位要施加 TLS 的后端,此处是default命名空间的backendService 的https端口(sectionName: https,对应上一步 Service 中的端口名);
  • spec.validation.hostname:期望后端证书的 SNI/主机名,即www.example.com,与mkcert签发时使用的域名一致;
  • spec.validation.caCertificateRefs:验证后端证书所用的 CA,必须是含ca.crt键的 ConfigMap(见第三步源码分析)。

最后,把 HTTPRoute 中后端引用端口从 3000 改为 443,让路由指向新的 TLS 端口:

kubectl patch HTTPRoute backend --type=json --patch ' - op: replace path: /spec/rules/0/backendRefs/0/port value: 443 '

验证:curl 观察响应中的 TLS 详情

再次通过 Gateway 访问:

$ curl -vI --resolve "www.example.com:80:<YOUR_GATEWAY_EXTERNAL_IP>" http://www.example.com:80/get

应收到200 OK。与最初基线响应的差别在于,现在响应中出现了tls字段:

{ "tls": { "version": "TLSv1.3", "serverName": "www.example.com", "negotiatedProtocol": "http/1.1", "cipherSuite": "TLS_AES_128_GCM_SHA256" } }

这证明 Gateway 与后端之间的连接已经升级为 TLS(本例协商出 TLSv1.3 与TLS_AES_128_GCM_SHA256加密套件,SNI 为www.example.com)。而客户端到 Gateway 这一段仍然是第 1 步里配置的 HTTP Listener(80 端口明文),两段连接的安全属性由不同资源分别控制。

深入:Cilium 侧如何处理 BackendTLSPolicy 事件

除了上面的操作步骤,仓库源码还能回答"改动了 CA ConfigMap 之后,集群如何感知并重新下发数据面配置"这个问题。在 operator/pkg/gateway-api/watch-handlers/backendtlspolicy.go 中注册了两类事件处理器:

  1. EnqueueRequestForBackendTLSPolicy:当某个BackendTLSPolicy变化时,从targetRefs中收集 Service 引用(updateReconcileRequestsForBackendTLSPolicy会把它们整理为命名空间/服务名),再利用BackendServiceHTTPRouteIndex字段索引反查出所有backendRefs引用了这些 Service 的 HTTPRoute,最终汇总出需要 reconcile 的 Gateway 集合。也就是说:策略 → Service → HTTPRoute → Gateway 这条"反向所有链"是 operator 主动推导的;
  2. EnqueueRequestForBackendTLSPolicyConfigMap:当 ConfigMap(如 CA 证书)变化时,通过BackendTLSPolicyConfigMapIndex索引查出引用它的 BackendTLSPolicy,再走同样的反查逻辑入队。这意味着你只更新 ConfigMap 里的ca.crt,operator 也会自动重新触发相关 Gateway 的调和,无需手工 patch 策略。

校验层面,调和流程会调用 BackendTLSPolicyInput.ValidateSpec,校验失败时通过setRejectedConditionsstatus.ancestors上写入Accepted=FalseResolvedRefs=False条件并附具体原因,可用kubectl get backendtlspolicy enable-backend-tls -o yaml观察这些条件来排错(例如忘记在 ConfigMap 中建ca.crt键、PEM 内容损坏、引用了 Secret 而非 ConfigMap 等场景都有明确报错文案)。策略与 Gateway 的关联调和细节另见 operator/pkg/gateway-api/gateway_reconcile.go,相关测试用例覆盖在 operator/pkg/gateway-api/testdata/gateway 目录下(如httproute-backendtlspolicy-reencrypthttproute-backendtlspolicy-invalid-kind等场景)。

小结

本文按仓库示例文档走通了 Cilium Gateway 后端 TLS 的完整闭环:部署echo-server建立明文基线 →mkcert生成演示证书 → Secret/ConfigMap 入集群(CA 键名必须为ca.crt)→ patch Deployment 启用 8443 端口 TLS 并把 Service 切到 443 → 创建BackendTLSPolicy绑定targetRefsvalidation→ 修改 HTTPRoute 端口 → 用 curl 响应中的tls字段确认生效。源码层面的校验与事件反查逻辑说明,Cilium operator 会把 BackendTLSPolicy、CA ConfigMap 的变化自动传导到对应 Gateway 的数据面配置中,配置错误也会以标准 Gateway API 条件形式暴露在资源状态里,便于排查。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 22:33:54

西安成人高考函授站有哪些?四个官方查询渠道(2026 更新)

直接答案&#xff1a;不列名单。函授站名单由各高校继续教育学院官网公示&#xff0c;并在省级考试机构公告中体现&#xff0c;以当年公示为准。 你要是搜到一份“西安函授站名单汇总”&#xff0c;先别急着用。高校每年都在调整校外教学点&#xff0c;静态名单过几个月就可能失…

作者头像 李华
网站建设 2026/9/14 22:32:03

裸机到能跑:Autoware 用 Docker 3 步跑通规划仿真的完整部署指南

裸机到能跑&#xff1a;Autoware 用 Docker 3 步跑通规划仿真的完整部署指南 【免费下载链接】autoware Autoware - the worlds leading open-source software project for autonomous driving 项目地址: https://gitcode.com/GitHub_Trending/au/autoware 如果你手上有…

作者头像 李华
网站建设 2026/9/14 22:31:25

Redis分页查询优化:从原理到实践

1. Redis分页查询的核心价值与应用场景在互联网应用中&#xff0c;分页查询是最基础也是最关键的功能之一。传统数据库分页&#xff08;如MySQL的LIMIT OFFSET&#xff09;在面对海量数据时存在明显的性能瓶颈&#xff1a;当翻到第1000页时&#xff0c;数据库需要先扫描并丢弃前…

作者头像 李华
网站建设 2026/9/14 22:29:48

OpenCode vs Claude Cli:AI编程助手深度对比与实战指南

1. 为什么OpenCode能成为AI助手的终极答案&#xff1f;最近在开发者圈子里&#xff0c;OpenCode的热度直线上升&#xff0c;不少同行都在讨论它如何"秒杀"Claude Cli。作为一个深度使用过两款工具的技术博主&#xff0c;我想分享一下我的实际体验和对比分析。OpenCod…

作者头像 李华
网站建设 2026/9/14 22:29:22

生物样本存储中心一站式整体解决方案:从系统设计到落地避坑

写样本库方案这类东西&#xff0c;最容易踩的坑就是"重硬件轻系统"。很多课题组一开始规划的挺像那么回事&#xff0c;等真正建起来才发现&#xff1a;冰箱买回来了&#xff0c;样本也冻上了&#xff0c;可半年之后想找一管某年某月采的血&#xff0c;得翻三个Excel、…

作者头像 李华