
Ingress NGINX Controller 自定义错误页面完整指南基于自定义 default-backend 的 Custom Errors 实战【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx导读本文基于 Ingress NGINX Controller 仓库中的官方示例 custom-errors README系统讲解如何用自定义 default-backend 服务渲染自定义错误页面包括 Helm Chart 与手动部署两种方式、custom-http-errors配置的底层原理、curl 验证方法以及用 503 维护页面对整集群做计划内停机。读完本文你将掌握从部署、配置到源码级验证的完整闭环并可直接复用仓库提供的三份 YAML 清单完成落地。一、方案原理错误码如何被劫持到自定义后端默认情况下当 Ingress 后端返回 4xx/5xx 错误时NGINX 会返回一个简单的错误页。Ingress NGINX Controller 提供custom-http-errors配置可让指定错误码不再由 NGINX 直接渲染而是转发给自定义的 default-backend 服务由该服务根据请求的Accept头返回 HTML、JSON 等自定义响应。从 NGINX 配置模板 rootfs/etc/nginx/template/nginx.tmpl 可以看到其底层实现全局 http 层第 493-502 行当设置了CustomHTTPErrors且未禁用DisableProxyInterceptErrors时开启proxy_intercept_errors on;并为每个错误码生成error_page {{ $errCode }} custom_upstream-default-backend_{{ $errCode }};将错误响应内部重定向到 default-backend 上游location 层第 1399-1405 行如果某个 Ingress 通过注解单独指定了错误码则在该 location 内同样开启proxy_intercept_errors on;并生成error_page {{ $errCode }} custom_{{ $location.DefaultBackendUpstreamName }}_{{ $errCode }};实现按 Ingress 粒度的错误页覆盖。也就是说这套机制同时支持全局错误页和单条 Ingress 的错误页覆盖两种粒度。二、前置条件准备一个可用的 Ingress Controller开始之前请确保集群中已部署 Ingress NGINX Controller。若尚未部署请参考官方部署指南完成安装。仓库的示例资源位于 docs/examples/customization/custom-errors/共包含三份关键文件下文将逐一讲解文件用途custom-default-backend.yaml手动部署方式自定义错误后端Service Deploymentcustom-default-backend-error_pages.configMap.yaml自定义 404/503 错误页内容的 ConfigMapcustom-default-backend.helm.values.yamlHelm Chart 部署方式使用的 values 片段三、方式一使用 Helm Chart 部署自定义错误页推荐如果控制器是通过 Helm Chartcharts/ingress-nginx安装的最省事的方式是复用仓库提供的 values 文件 custom-default-backend.helm.values.yaml内容如下controller: config: custom-http-errors: 404,503 defaultBackend: enabled: true image: registry: registry.k8s.io image: ingress-nginx/custom-error-pages tag: v1.2.9sha256:203d3020005dbdd735c1ad51f238d8663b9851399b52cc0c9c9e3f7273b6b299 extraVolumes: - name: custom-error-pages configMap: name: custom-error-pages items: - key: 404 path: 404.html - key: 503 path: 503.html extraVolumeMounts: - name: custom-error-pages mountPath: /www要点说明controller.config.custom-http-errors: 404,503等价于 ConfigMap 中的custom-http-errors键告诉控制器哪些错误码要走自定义错误页defaultBackend.enabled: true启用 Chart 内置的 default-backend并替换为registry.k8s.io/ingress-nginx/custom-error-pages:v1.2.9镜像extraVolumes/extraVolumeMounts将上面提到的custom-error-pagesConfigMap 挂载到容器/www目录即自定义错误页的渲染根目录别忘了同时创建ConfigMap custom-default-backend-error_pages.configMap.yaml否则 Volume 挂载会因找不到 ConfigMap 而失败。其内容为apiVersion: v1 kind: ConfigMap metadata: name: custom-error-pages data: 404: | !DOCTYPE html html headtitlePAGE NOT FOUND/title/head bodyPAGE NOT FOUND/body /html 503: | !DOCTYPE html html headtitleCUSTOM SERVICE UNAVAILABLE/title/head bodyCUSTOM SERVICE UNAVAILABLE/body /html注意ConfigMap 中data的键名404、503对应 HTTP 状态码通过items映射为404.html、503.html写入挂载目录custom-error-pages 镜像会根据请求状态码在/www下查找同名文件渲染页面。你也可以把键改为其他 400-599 的错误码只需保持与custom-http-errors列表一致。四、方式二手动部署自定义 default-backend如果不使用 Helm可按原文档的手动流程操作。4.1 创建自定义错误后端使用仓库提供的 custom-default-backend.yaml 创建资源$ kubectl create -f custom-default-backend.yaml service nginx-errors created deployment.apps nginx-errors created该文件包含一个 Service 和一个 Deployment二者均名为nginx-errors。核心定义如下apiVersion: v1 kind: Service metadata: name: nginx-errors labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: selector: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx ports: - port: 80 targetPort: 8080 name: http --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-errors labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: containers: - name: nginx-error-server image: registry.k8s.io/ingress-nginx/custom-error-pages:v1.2.9sha256:203d3020005dbdd735c1ad51f238d8663b9851399b52cc0c9c9e3f7273b6b299 ports: - containerPort: 8080 # Setting the environment variable DEBUG we can see the headers sent # by the ingress controller to the backend in the client response. # env: # - name: DEBUG # value: true # Mounting custom error page from configMap # volumeMounts: # - name: custom_error_pages # mountPath: /www # Mounting custom error page from configMap # volumes: # - name: custom_error_pages # configMap: # name: custom_error_pages # items: # - key: 404 # path: 404.html # - key: 503 # path: 503.html几点值得注意镜像使用registry.k8s.io/ingress-nginx/custom-error-pages:v1.2.9含 SHA256 摘要以保证可复现性该镜像即仓库images/custom-error-pages/目录下构建的官方错误页服务调试技巧取消注释DEBUGtrue环境变量即可在客户端响应中看到 Ingress Controller 转发给后端时携带的请求头便于排查问题自定义页面取消注释volumeMounts与volumes两段即可把前面创建的custom-error-pagesConfigMap 挂载到/www用你自己的 HTML 替换默认错误页。验证创建结果$ kubectl get deploy,svc NAME DESIRED CURRENT READY AGE deployment.apps/nginx-errors 1 1 1 10s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx-errors ClusterIP 10.0.0.12 none 80/TCP 10s此时集群中已有一个名为nginx-errors的 Deployment 和 Service。4.2 配置 Ingress Controller按原文档的指引需要完成以下三步指定默认后端编辑ingress-nginx-controller的 Deployment将启动参数--default-backend-service的值设置为新创建的错误后端格式为namespace/service-name例如default/nginx-errors声明错误码编辑ingress-nginx-controller的 ConfigMap添加键custom-http-errors值为404,503多个错误码用逗号分隔也支持404, 500这类带空格写法源码解析时会自动去除空白记录 Service 地址查看 Ingress Controller 的 Service IP后续 curl 测试会用到$ kubectl get svc ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx ClusterIP 10.0.0.13 none 80/TCP,443/TCP 10m说明示例中ingress-nginxService 类型为ClusterIP实际环境可能是LoadBalancer或NodePort。无论哪种类型请确保能通过该 Service 访问到 NGINX 后再继续后续步骤。五、源码级原理custom-http-errors 的解析与校验custom-http-errors既可作为ConfigMap 全局配置本文场景也可以作为Ingress 注解按规则覆盖。其解析实现在 internal/ingress/annotations/customhttperrors/main.go关键逻辑如下注解名常量custom-http-errors属于backend组、作用域为location、风险等级Low校验正则^(?:[4,5]\d{2},?)*$只接受 400-599 之间的错误码且必须为逗号分隔如403,503非法值会直接报错Parse方法将逗号分隔的字符串按逗号切分、TrimSpace去除空白后逐个strconv.Atoi转为整数最终返回[]int错误码列表。因此404, 503、404,503均合法而包含非数字如abc则解析失败。对应测试 customhttperrors/main_test.go 验证了合法输入400,404,500,502可正常解析非法输入400,404,abc,502会返回错误。此外internal/ingress/annotations/annotations_test.go 的TestCustomHTTPErrors也覆盖了404,415→[404, 415]、空字符串 →[]等边界场景。关于错误转发到哪个后端可结合两个注解的文档说明理解defaultbackend/main.go 中的default-backend注解组backend、作用域location、风险Low该 Service 用于处理 Ingress 规则中配置的 Service没有可用端点时的响应如果同时设置了default-backend与custom-http-errors注解错误响应会转发给该注解指定的 Servicecustomhttperrors/main.go 的文档说明如果 Ingress 上指定了default-backend注解则custom-http-errors列出的错误码转发到该注解指定的后端否则转发到全局 default-backend即--default-backend-service指向的服务。补充仓库还提供了 disableproxyintercepterrors/main.go 中的disable-proxy-intercept-errors注解用于在设置了custom-http-errors时显式关闭 NGINX 的proxy_intercept_errors可按需查阅。六、验证错误页curl 实战测试配置完成后用 cURL 对 Ingress Controller Service 发起请求验证。场景 1请求到默认后端返回自定义 404 页面$ curl -D- http://10.0.0.13/ HTTP/1.1 404 Not Found Server: nginx/1.13.12 Date: Tue, 12 Jun 2018 19:11:24 GMT Content-Type: */* Transfer-Encoding: chunked Connection: keep-alive spanThe page youre looking for could not be found./span场景 2携带Accept: application/json返回 JSON 格式错误体$ curl -D- -H Accept: application/json http://10.0.0.13/ HTTP/1.1 404 Not Found Server: nginx/1.13.12 Date: Tue, 12 Jun 2018 19:12:36 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding { message: The page youre looking for could not be found }可以看到custom-error-pages 后端会根据客户端的Accept头协商响应格式HTML、JSON 等这正是自定义错误页在前后端分离架构下特别有价值的原因——前端可以直接消费结构化错误体。进一步验证部署你自己的应用与 Ingress 对象然后将某个 Deployment 的副本数缩到 0请求该服务应返回 503且响应体同样为自定义错误格式。这可以验证后端无可用端点 → 返回 503 → 自定义错误页接管的完整链路default-backend注解的文档正是这么描述的用于处理配置的 Service 无可用端点时的响应。七、进阶玩法集群级服务维护中页面custom-http-errors还有一个实用场景为整个集群设置服务维护中页面在计划性维护期间阻止用户访问业务。实现步骤按原文档为 503 启用自定义错误页按前文步骤在custom-http-errors中加入503并确保自定义后端能渲染 503 页面停止读取 Ingress 资源将ingress-nginx-controller的启动参数--watch-namespace-selector设置为一个不存在的命名空间例如nonexistent-namespace。这样控制器不会从任何命名空间读取 Ingress 资源业务流量自然无法被路由强制返回 503给控制器 ConfigMap 配置location-snippet: return 503;或在对应 location 中注入该片段让 NGINX 对所有请求都返回 503 错误码。由于custom-http-errors已包含 503所有请求都会命中自定义错误页客户端将看到统一风格的维护页面同时 HTTP 状态码保持标准的 503 Service Unavailable便于监控与客户端识别。原文档提示--watch-namespace-selector指向不存在命名空间本质上是清空控制器监听的 Ingress 集合维护结束后恢复原值即可正常服务。执行维护前建议先在测试环境演练一遍确认错误页与状态码符合预期。八、相关资源与进一步阅读示例资源目录docs/examples/customization/custom-errors/手动部署清单custom-default-backend.yamlHelm valuescustom-default-backend.helm.values.yaml错误页 ConfigMapcustom-default-backend-error_pages.configMap.yaml默认后端概念default-backend.md注解参考含custom-http-errors、default-backend、disable-proxy-intercept-errorsannotations.mdConfigMap 配置项说明configmap.md控制器部署文档deploy/index.md如需继续深入源码可阅读 customhttperrors/main.go解析逻辑、customhttperrors/main_test.go解析测试、defaultbackend/main.go默认后端注解、nginx.tmplproxy_intercept_errors与error_page的生成逻辑以及 config.go 中CustomHTTPErrors的默认空切片定义第 874 行附近。【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考