YARP Kubernetes Ingress Controller 单实例部署指南:构建与部署 Combined 示例
【免费下载链接】reverse-proxyA toolkit for developing high-performance HTTP reverse proxy applications.项目地址: https://gitcode.com/GitHub_Trending/re/reverse-proxy
本篇技术指南围绕 reverse-proxy 仓库中samples/KubernetesIngress.Sample/Combined示例展开,讲解如何将 YARP 反向代理引擎与 Kubernetes Ingress 控制器整合为单个可部署单元,涵盖镜像构建、集群部署、RBAC 授权、IngressClass 绑定与 YARP 配置注入的完整链路。读完本文,你将掌握一键构建 yarp-combined 镜像、通过kubectl apply将控制器部署进集群并正确卸载的全部操作步骤,同时理解底层配置项(如ControllerClass、DefaultSslCertificate)在源码中的真实含义。
一、示例概览:什么是 Combined 部署形态
Combined是samples/KubernetesIngress.Sample提供的三种示例之一。与将"监视 Ingress 资源的 Monitor"和"执行路由转发的 Ingress"拆分为两个部署的 Separate 方案 不同,Combined 将整个 Ingress 控制器做成一个单一部署(single deployable):同一个进程既监听 Kubernetes 中的 Ingress/Service/Endpoints 等资源变化,又把它们翻译为 YARP 路由与集群配置并直接代理流量。
该示例的核心组成如下(目录见 Combined):
| 文件 | 作用 |
|---|---|
Dockerfile | 多阶段构建,产出控制器镜像 |
Program.cs | 应用入口:注册 Kubernetes 控制器运行时、反向代理与证书选择器 |
ingress-controller.yaml | 控制器所需的全部 Kubernetes 清单:Namespace、ConfigMap、RBAC、IngressClass、Service、Deployment |
appsettings.json | 本地调试用的 Yarp 配置节(镜像内由 ConfigMap 的yarp.json覆盖) |
Yarp.Kubernetes.IngressController.csproj | 项目文件,引用src/Kubernetes.Controller工程 |
与 Ingress 控制器对应的核心实现位于 src/Kubernetes.Controller,其中 KubernetesReverseProxyServiceCollectionExtensions.cs 的AddKubernetesReverseProxy方法完成了整套组装:先注册 Kubernetes 控制器运行时(resource informers、缓存、协调器等),再注册KubernetesConfigProvider作为IProxyConfigProvider,最后调用AddReverseProxy()叠加 YARP 核心。
二、构建 Docker 镜像
在仓库根目录(即存放YARP.slnx的位置)执行以下命令构建镜像:
docker build -t yarp-combined:latest -f ./samples/KubernetesIngress.Sample/Combined/Dockerfile .参数说明:
-t yarp-combined:latest:为镜像指定名称与标签,后续部署清单中的镜像引用必须与此保持一致(可自行换成私有仓库地址,如<REGISTRY_NAME>/yarp-combined:<TAG>);-f ./samples/KubernetesIngress.Sample/Combined/Dockerfile:显式指定构建文件路径,因为 Dockerfile 不在仓库根目录;- 末尾的
.为构建上下文,必须为仓库根目录——Dockerfile 中通过相对路径拷贝了samples/...与src/...下的源码和工程文件。
2.1 Dockerfile 构建原理拆解
该 Dockerfile 采用标准多阶段构建:
- 基础镜像阶段(base):基于
mcr.microsoft.com/dotnet/aspnet:8.0,声明运行时工作目录并EXPOSE 80/443; - 发布阶段(publish):基于
mcr.microsoft.com/dotnet/sdk:8.0。由于仓库可能依赖未正式发布的 SDK,会先拷贝根目录global.json,再通过dotnet-install.sh --jsonfile global.json手动安装匹配版本的 SDK;随后仅拷贝各*.csproj、Directory.Build.props、Directory.Build.*、TFMs.props、NuGet.config、eng/Versions.props等文件执行dotnet restore,利用 NuGet 缓存层加速后续重建; - 最终阶段(final):从 publish 阶段拷贝发布产物,
ENTRYPOINT指向dotnet Yarp.Kubernetes.IngressController.dll。
值得注意:Dockerfile 显式设置了DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1,使容器镜像可以精简运行,不依赖系统全球化组件。
三、部署 Combined 示例 Ingress 控制器
3.1 部署三步走
- 打开 ingress-controller.yaml;
- 将 Deployment 中的镜像引用
<REGISTRY_NAME>/yarp-combined:<TAG>改为与本地构建的镜像名一致,例如yarp-combined:latest; - 在仓库根目录执行:
kubectl apply -f ./samples/KubernetesIngress.Sample/Combined/ingress-controller.yaml如需卸载控制器,执行:
kubectl delete -f ./samples/KubernetesIngress.Sample/Combined/ingress-controller.yaml3.2 清单内容逐项解析
ingress-controller.yaml是一个多文档 YAML(以---分隔),依次定义:
- Namespace
yarp:所有控制器资源统一收纳于此命名空间; - ConfigMap
yarp-config:以yarp.json为键存放 YARP 控制器配置,后续挂载到容器/app/config目录。内容如下:
{ "Yarp": { "ControllerClass": "microsoft.com/ingress-yarp", "ServerCertificates": false, "DefaultSslCertificate": "yarp/yarp-ingress-tls", "ControllerServiceName": "ingress-yarp-controller", "ControllerServiceNamespace": "yarp" } }这些配置节直接对应 YarpOptions.cs 中定义的YarpOptions类(通过services.Configure<YarpOptions>(config.GetSection("Yarp"))绑定,见 KubernetesReverseProxyServiceCollectionExtensions.cs):
| 配置项 | 说明 |
|---|---|
ControllerClass | Ingress 控制器名称,必填;必须与IngressClass.spec.controller字段一致(本例为microsoft.com/ingress-yarp),控制器据此识别属于自己的 Ingress 资源 |
ServerCertificates | 是否启用基于 Kubernetes Secret 的服务器证书管理(SNI 选择),此处为false |
DefaultSslCertificate | 默认 SSL 证书的namespace/name引用(如yarp/yarp-ingress-tls),在无匹配证书时兜底 |
ControllerServiceName | 控制器所在 Kubernetes Service 名称,必填 |
ControllerServiceNamespace | 该 Service 所在命名空间,必填 |
- ServiceAccount
yarp-serviceaccount:控制器进程以该身份访问 Kubernetes API; - ClusterRole
yarp-ingress-clusterrole+ ClusterRoleBinding:授予控制器对endpoints、nodes、pods、secrets、namespaces、services的 list/watch/get 权限,对ingresses、ingressclasses(networking.k8s.io、extensions、networking.internal.knative.dev三个 API 组)的 get/list/watch 权限,以及events的 create/patch、ingresses/status的 get/update 权限。其中 Secrets 的监听被限制为type=kubernetes.io/tls字段选择器,避免像 Helm V3 那样产生的大量无关 Secret 造成资源浪费(对应 RegisterResourceInformer 调用); - IngressClass
yarp:声明controller: microsoft.com/ingress-yarp,与 ConfigMap 中的ControllerClass呼应;示例中"默认 IngressClass"注解(ingressclass.kubernetes.io/is-default-class)被注释掉,按需启用后可简化 Ingress 资源配置(不必每个 Ingress 都显式指定ingressClassName); - Service
ingress-yarp-controller:LoadBalancer类型,暴露两个端口——proxy(80 → 容器 8000)与proxy-ssl(443 → 容器 8443),selector 匹配app: ingress-yarp-controller; - Deployment
ingress-yarp:replicas: 1,容器监听ASPNETCORE_URLS=http://*:8000;https://*:8443,将 ConfigMapyarp-config只读挂载到/app/config,并使用yarp-serviceaccount运行。
3.3 入口程序如何串联控制器与反向代理
Program.cs 是整个 Combined 进程的装配点,关键调用如下:
builder.Configuration.AddJsonFile("/app/config/yarp.json", optional: true); builder.WebHost.UseKubernetesReverseProxyCertificateSelector(); builder.Services.AddKubernetesReverseProxy(builder.Configuration); var app = builder.Build(); app.MapReverseProxy(); app.Run();AddJsonFile("/app/config/yarp.json", optional: true):从挂载的 ConfigMap 读取Yarp配置节(本地调试时则回退到 appsettings.json 中的同名配置);UseKubernetesReverseProxyCertificateSelector():见 KubernetesReverseProxyWebHostBuilderExtensions.cs,它通过ConfigureKestrel为 HTTPS 配置ServerCertificateSelector,使 Kestrel 能依据 SNI 域名调用IServerCertificateSelector.GetCertificate从 Kubernetes Secret 中选证——这正是 Ingress TLS 能力的基础;AddKubernetesReverseProxy(...):完成控制器运行时(IngressController托管服务、IngressCache、Reconciler、Ingress/Service/Endpoints/IngressClass/Secret 五类 resource informer 的注册)与KubernetesConfigProvider配置源的注册;MapReverseProxy():挂载 YARP 反向代理中间件管线,接收经 Ingress 规则翻译而来的请求并转发到后端 Service 的 Endpoints。
四、控制器能力边界与 Ingress 注解扩展
Yarp.Kubernetes.Controller当前支持的 Ingress 功能(详见 samples/KubernetesIngress.Sample/README.md):
- Ingress rules:基于主机名与路径的路由转发到后端 Service;
- IngressClass:通过 class 隔离多个相互独立的控制器实例(当前仅支持集群级);
- 默认 IngressClass:简化 Ingress 资源配置。
暂不支持:Ingress 资源的 TLS 规范(即将支持,可与仓库中的 LetsEncrypt 示例组合使用);已被废弃的 annotation 规范。
除标准 Ingress 语义外,控制器还支持一组可选的 YARP 专属注解,它们会映射为路由/集群配置。完整注解清单如下:
| 注解 | 数据类型 |
|---|---|
yarp.ingress.kubernetes.io/authorization-policy | string |
yarp.ingress.kubernetes.io/rate-limiter-policy | string |
yarp.ingress.kubernetes.io/output-cache-policy | string |
yarp.ingress.kubernetes.io/backend-protocol | string |
yarp.ingress.kubernetes.io/cors-policy | string |
yarp.ingress.kubernetes.io/health-check* | ActivateHealthCheckConfig |
yarp.ingress.kubernetes.io/http-client* | HttpClientConfig |
yarp.ingress.kubernetes.io/http-request* | ForwarderRequestConfig |
yarp.ingress.kubernetes.io/load-balancing* | string |
yarp.ingress.kubernetes.io/route-metadata | Dictionary<string, string> |
yarp.ingress.kubernetes.io/session-affinity* | SessionAffinityConfig |
yarp.ingress.kubernetes.io/transforms | List<Dictionary<string, string>> |
yarp.ingress.kubernetes.io/route-headers | List<RouteHeader> |
yarp.ingress.kubernetes.io/route-queryparameters | List<RouteQueryParameter> |
yarp.ingress.kubernetes.io/route-order | int |
yarp.ingress.kubernetes.io/route-methods | List<string> |
注意(集群级注解):标记
*的注解配置的是 YARP 集群而非路由。集群由后端 Service 名称、命名空间与端口共同标识,多个指向同一后端的 Ingress 规则会共享该集群,因此若各规则中这些注解取值冲突,将产生不确定行为——请确保同一后端的所有 Ingress 规则取值一致。
常用注解的配置示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress namespace: default annotations: yarp.ingress.kubernetes.io/authorization-policy: authzpolicy yarp.ingress.kubernetes.io/rate-limiter-policy: ratelimiterpolicy yarp.ingress.kubernetes.io/output-cache-policy: outputcachepolicy yarp.ingress.kubernetes.io/transforms: | - PathRemovePrefix: "/apis" yarp.ingress.kubernetes.io/route-headers: | - Name: the-header-key Values: - the-header-value Mode: Contains IsCaseSensitive: false yarp.ingress.kubernetes.io/route-methods: | - GET - POST spec: rules: - http: paths: - path: /foo pathType: Prefix backend: service: name: frontend port: number: 804.1 关键注解速查
- 后端协议:
yarp.ingress.kubernetes.io/backend-protocol: "https",指定后端 Service 的协议,默认http; - 健康检查(主动探测后端健康端点):
yarp.ingress.kubernetes.io/health-check: | Active: Enabled: true Interval: '00:00:10' Timeout: '00:00:10' Policy: ConsecutiveFailures Path: "/api/health"- HTTP 客户端配置:
yarp.ingress.kubernetes.io/http-client: | SslProtocols: Ssl3 MaxConnectionsPerServer: 2 DangerousAcceptAnyServerCertificate: true- 转发请求配置:
yarp.ingress.kubernetes.io/http-request: | ActivityTimeout: '00:01:00' Version: '2.0' VersionPolicy: 'RequestVersionExact' AllowResponseBuffering: false- 负载均衡策略:
yarp.ingress.kubernetes.io/load-balancing: Random(可选RoundRobin、LeastRequests、PowerOfTwoChoices、First等,对应 LoadBalancing 下的策略实现); - 路由元数据:
yarp.ingress.kubernetes.io/route-metadata: | Custom: "orange" Tenant: "12345"- 会话亲和性:
yarp.ingress.kubernetes.io/session-affinity: | Enabled: true Policy: Cookie FailurePolicy: Redistribute AffinityKeyName: Key1 Cookie: Domain: localhost HttpOnly: true IsEssential: true Path: mypath SameSite: Strict SecurePolicy: Always- 请求转换(键值对语义与 YARP Request Transforms 一致):
yarp.ingress.kubernetes.io/transforms: | - PathPrefix: "/apis" - RequestHeader: header1 Append: bar- 基于请求头的路由:
yarp.ingress.kubernetes.io/route-headers: | - Name: the-header-key Values: - the-header-value Mode: Contains IsCaseSensitive: false- 基于查询参数的路由:
yarp.ingress.kubernetes.io/route-queryparameters: | - Name: the-queryparameter-name Values: - the-queryparameter-value Mode: Contains IsCaseSensitive: false- 路由顺序:
yarp.ingress.kubernetes.io/route-order: '10',用于控制多条路由的匹配优先级; - HTTP 方法约束:
yarp.ingress.kubernetes.io/route-methods: | - GET - POST五、与同仓库其他示例的关系与选型建议
- Combined(本文):控制器 + 代理一体,部署最简单,适合中小集群与快速验证;
- Separate(Ingress 与 Monitor):监视器与代理拆分部署,可独立伸缩,适合需要解耦控制面与数据面的场景(Monitor 通过
AddKubernetesIngressMonitor注册IDispatcher,Ingress 侧通过AddKubernetesDispatchController暴露调度端点,见 KubernetesReverseProxyServiceCollectionExtensions.cs); - Backend(backend):配套的模拟后端应用及其 Ingress 样例,可用于端到端验证控制器路由效果。
两个部署形态共用 src/Kubernetes.Controller 工程,区别仅在服务装配方式。部署后,可通过kubectl get ingress -A、kubectl get svc -n yarp观察控制器生成的资源,并用kubectl logs -n yarp deploy/ingress-yarp查看 Serilog 输出(Program.cs 将日志级别设为 Debug 并输出到控制台)验证 Ingress 事件的监听与协调过程。
六、故障排查与注意事项
- 镜像名不一致:忘记修改 Deployment 中
<REGISTRY_NAME>/yarp-combined:<TAG>会导致ImagePullBackOff; ControllerClass不匹配:ConfigMap 中Yarp:ControllerClass与IngressClass.spec.controller必须一致,否则控制器会忽略对应 Ingress 资源;- 集群级注解冲突:同一后端(Service + Namespace + Port)的多个 Ingress 规则若对
*标注的集群级注解给出不同取值,行为不确定,务必保持取值一致; - 证书功能:示例将
ServerCertificates设为false;若启用,需先在集群中准备好DefaultSslCertificate引用的 TLS Secret(如yarp/yarp-ingress-tls),并确保 ClusterRole 对secrets的 list/watch 权限可用; - 镜像内配置优先级:容器通过挂载
/app/config/yarp.json覆盖内置 appsettings.json,修改 ConfigMap 后需重启 Deployment 才会重新加载配置。
【免费下载链接】reverse-proxyA toolkit for developing high-performance HTTP reverse proxy applications.项目地址: https://gitcode.com/GitHub_Trending/re/reverse-proxy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考