面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。
一、遭遇情况:Service 内部正常,域名访问却报错
应用通过集群内部 Service 能访问,外部入口却返回 404、502 或 503。有人马上回滚应用,也有人只盯着 Ingress YAML 的语法。
本篇主案例是直接访问入口 IP,没有携带规则要求的 Host,因此请求没有匹配预期虚拟主机。其他状态还可能来自入口控制器、外部负载均衡或应用本身,不能把所有 503 都等同于“Pod 不健康”。
二、原因分析:Ingress 资源本身不转发请求
Ingress 需要实际控制器读取规则并实施转发。资源创建成功,不代表有控制器接管;控制器接管,也不代表域名、证书和后端都正确。

不同控制器对默认路由、无后端和连接失败的状态码处理可能不同。本文维护已有 Ingress,不安装或推荐某个控制器;使用组织当前维护的控制器与对应版本文档。
三、排查思路:先确认谁返回了错误
kubectl get ingressclass
kubectl get ingress -n 目标命名空间 -o wide
kubectl describe ingress 目标入口 -n 目标命名空间
kubectl get service 目标后端 -n 目标命名空间 -o yaml
kubectl get endpointslice -n 目标命名空间 -l kubernetes.io/service-name=目标后端 -o yaml
核对入口地址是否是预期的负载均衡地址;IngressClass 是否存在并被实际控制器处理;Host 与 path 是否匹配;backend 引用的是 Service 的端口,而不是直接把容器端口填进去。
通过响应头、响应体、请求时间与控制器/应用访问日志定位哪一层响应。头部只能提供线索,不能单凭一个 Server 字段就断言根因。
四、实践:使用测试集群里已有的入口控制器
本实验要求控制器已安装并能访问,不会帮你安装集群组件。先获取实际 IngressClass,将下列 example-class 替换为已有且经过确认的 class 名。
保存 kt12-ingress.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: kt12
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: kt12
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:stable-alpine
readinessProbe:
httpGet:
path: /
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: kt12
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: kt12
spec:
ingressClassName: example-class
rules:
- host: app.example.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
kubectl apply -f kt12-ingress.yaml
kubectl rollout status deployment/web -n kt12 --timeout=120s
kubectl describe ingress web -n kt12
示例域名是保留测试名称,不要求公开 DNS。若控制器不支持或未配置 HTTP 入口,应按现有测试环境调整,不能假设创建资源就会自动出现公网负载均衡。
五、修复实践:让请求带上正确 Host
把下面的文档示例 IP 替换为真实、获准访问的测试入口 IP:
ingress_ip=192.0.2.10
curl -i --connect-timeout 3 --max-time 5 "http://$ingress_ip/"
curl -i --connect-timeout 3 --max-time 5 -H 'Host: app.example.test' "http://$ingress_ip/"
若已接管规则且后端正常,第二条应命中演示服务;第一条可能落到默认路由,常见为 404,但具体响应取决于控制器配置。修复是对齐请求域名与规则,不是给应用首页改状态码。
真实域名访问错误时,还要核对 DNS 是否解析到同一入口。HTTPS 需要同时考虑 SNI、证书与 Host,仅修改 HTTP Host 头不完整;可以在已有正确证书和 TLS 配置的前提下,用 curl 的 --resolve 保持正确域名进行定向测试,而不是关闭证书验证。
六、如果 Host 正确但仍然失败
回到 Service 与 EndpointSlice,检查就绪后端、Service port 与 targetPort。内部客户端访问后端也失败时,先修后端;内部正常而入口失败时,查控制器到后端的网络、策略和协议配置。
不要随便复制某控制器的 rewrite 注解。路径改写、上游 HTTPS 等能力属于具体实现,注解能被 API 接收不等于当前控制器会识别它。
七、验证与总结
在真实预期入口验证正确 Host、路径和业务响应,再核对错误 Host 不会误入该服务。TLS 场景还要验证证书信任与名称匹配,不能仅看页面能打开。
Ingress 的排查闭环是:响应来自哪里 → 谁接管规则 → 请求是否匹配 → Service 是否指向可用后端 → 控制器到应用是否畅通。状态码是起点,链路证据才决定修复位置。