ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【13-Ingress七层负载均衡器-已停止维护】

【13-Ingress七层负载均衡器-已停止维护】 一、Ingress 基础概念一句话理解Ingress k8s 中的智能化网关用在七层用声明式YAML定义哪个域名/路径——— 转到哪个service 。三大组件关系组件角色Ingress Controller实际干活的nginx进程Ingress 资源路由规则定义YAMLingressClass指定由那种Controller 处理关键点-为什么需要Ingress NodePort 每个service占用一个端口服务多了端口就爆炸 LoadBalancer:每个Service 一个LB —— 成本爆炸 ingress:共享80443端口--- 通过域名路径分流- 经济高效二、Ingress Controller 安装核心理解Controller才是真正干活的光写一个ingress YAML,集群里什么都不会发生。必须有一个Ingress Controller 在运行他会1.watch k8s API ,监听ingress 资源的变化。 2.读取Ingress YAML 中的路由规则。 3.动态生成自身的配置文件比如 nginx.conf 4.reload 配置开始按配置规则转发流量部署nginx-ingress-controller#使用Helm安装推荐方式 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace #验证 kubectl get pods -n ingress-nginx kubectl get svc -n ingress-nginx三、 Ingress 的三大核心组件Ingress Controller 实际的执行者进程监听kubernetes api server ,watch ingress 资源变化将 ingress 规则翻译成自身的代理配置执行实际的流量转发Ingress 资源YAML路由规则的声明式定义定义 host (域名)定义 path (路径pathType(匹配方式)定义 backend (转发到哪个Service的哪个端口)定义TLS 配置IngressClass 指定由那种Controller处理同一个ingress资源可以由指定由nginx 处理或者traefik 处理。四、Ingress 资源对象的内部解构apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: # 注解给 Controller 的额外指令 nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx # 指定 Controller tls: # TLS 配置 - hosts: - app.example.com secretName: tls-secret rules: # 路由规则列表 - host: app.example.com # 域名 http: paths: # 路径列表 - path: /api pathType: Prefix backend: service: name: api-svc # 目标 Service port: number: 80 # 目标端口逐层拆解:一个 Ingress 对象 │ ├── spec.ingressClassName │ └── 决定谁来处理这条规则 │ ├── spec.tls[] │ ├── hosts[]: 要保护的域名列表 │ └── secretName: 存放证书的 Secret │ └── spec.rules[] └── rule (一条规则) ├── host: 匹配的域名可选空则匹配所有域名 └── http.paths[] └── path ├── path: 路径字符串 ├── pathType: 匹配方式 └── backend: 转发目标五、pathType 三种模式详解Ingress 路由匹配的核心机制Exact(精确匹配)规则path:/foo,pathType:Exact 匹配结果 /foo 命中 /foo/ 不命中 /foot/bar /Foot 特点必须一致多一个字符都不行Prefix (前缀匹配)规则 path:/foo,pathType:Prefix 匹配规则 /foo 命中 ✓ /foo/ ✓ /foo/bar ✓ /foobar X /foo/bar/baz ✓ 匹配原理 把path按照“/”分段请求路径的前N段必须完全匹配Prefix 的分段匹配规则ImplementationSpecific (由Controller决定)含义k8s标准不定义匹配逻辑交给具体的Ingress Controller实现不同行为。经典用法需要使用正则表达匹配路径时Contorller有特殊匹配语法时一般不推荐使用除非知道自己在干什么。三种本质区别Exact 我告诉 Controller必须完全等于这个路径 Prefix 我告诉 Controller以这个路径开头的都算 ImplementationSpecific 我告诉 Controller你自己看着办匹配优先级当多条规则都能匹配同一个请求时 Exact Prefix ImplementationSpecific 具体比较时 路径更长的 路径更短的 例/foo/bar (Prefix) 优先于 /foo (Prefix)六 、Ingress Controller的工作呢机制6.1 控制循环Reconciliation Loopk8s API Server | 监听watch持续监听Ingress/Service/Endpoints变化 | - Ingress Controller 1.检测到Ingress 资源创建/修改/删除 2.将Ingress 规则翻译成自身的配置列nginx-ingress 生成- nginx.conf 3.验证配置语法是否正确 4.热加载配置 nginx -s reload 5.更新 Ingress 状态写入LoadBanlacer IP6.2 Ingress Controller 不是DaemonSet 也不是Deployment 的必选项部署方式controller 的部署方式取决于场景 Deployment Service(LB) -- 最常见生产环境做法 DaemonSet ---- 每个节点一个实列适合边缘节点场景 Pod 直接 hostNetwork ---- 绑定宿主机端口减少一层NAT6.3 Ingress Controller 与 kube-proxykube-proxy(四层) 工作在iptables/IPVS层 处理 Service - Pod 的流量转发 只做四层负载均衡 每个Service 独立 Ingress Controller (七层) 工作在应用层 处理外部—— Service的流量路由 做七层智能分流 多个Service共享一个入口 两者的协作关系 客户端- Ingress Controller (L7) - Service - kube-proxy (L4) - POD第一层Ingress 层 —— 选哪个 Service路由 第二层Service 层 —— 选哪个 Pod负载均衡 请求进入 │ ▼ ┌──────────────────────────────────────────────┐ │ 第一层Ingress Controller │ │ │ │ 根据 Host Path 选中一个 Service │ │ 这叫路由不叫负载均衡 │ │ 一个请求只会去一个 Service │ └──────────────────┬───────────────────────────┘ │ 只选中了一个 Service ▼ ┌──────────────────────────────────────────────┐ │ 第二层Service → Pod │ │ │ │ 一个 Service 后面有 3 个 Pod │ │ kube-proxy 或 Controller 选中一个 Pod │ │ 这才叫负载均衡 │ └──────────────────────────────────────────────┘七、Annotations 机制为什么需要AnnotationsIngress 资源本身的spec 字段功能有限 -只定义了host\path\backend\tls -没有限流、重写、跨域、超时等高级功能 但不同的Controller有不同的高级功能 -nginx-ingress 有自己的限流机制 -traefik 有自己的中间件 -HAProxy 有自己的后端健康检测 解决方案用annotations 把Controller特有的指令附加到Ingress对象上 Controller 读取annotations 执行对应逻辑Annotations 的命名空间每种 Controller 用自己的前缀避免冲突 nginx-ingress: nginx.ingress.kubernetes.io/rewrite-target nginx.ingress.kubernetes.io/ssl-redirect nginx.ingress.kubernetes.io/limit-rps traefik: traefik.ingress.kubernetes.io/rule-type traefik.ingress.kubernetes.io/redirect-entry-point Kubernetes 标准通用: kubernetes.io/ingress.class ← 已被 ingressClassName 替代常见nginx-ingress annotations 分类路径操作类 rewrite-target 重写转发路径 use-regex 启用正则路径匹配path :/v[0-9]/(.*) TLS/安全类 ssl-redirect 强制HTTP-HTTPS force-ssl-redirct 即使有X-Forwarded-Proto 也强制跳转 cors-allow-origin 配置CORS 限流类 limit-rps 每秒请求数限制,场景秒杀活动 limit-rpm 每分钟请求数限制,API 对外开放按调用量计费 limit-connections 并发连接数限制 limit-burst-multiplier 突发倍率,限流太严格正常业务也受影响,短暂突发不会被误杀,本质给正常业务留缓冲空间 超时类 proxy-connect-timeout 连接后端超时,场景Controller 连不上后端 Pod网络抖动pod资源不足, 用户刷新资源快速释放 proxy-read-timeout 读取响应超时,场景后端处理一个复杂查询,可以配合后端的处理时间设置;特殊场景WebSocket / SSE(长连接)不然60s断开 proxy-send-timeout 发送请求超时用户上传一个大文件Controller 30 秒内没把请求体发完 → 超时 金丝雀发布类 canary 启用金丝雀 canary-weight 金丝雀流量权重0-100 canary-by-header 按 Header 分流 场景 传统方式把所有POd滚动到新版本 如果新版本有BUG-100%用户受影响 回滚需要时间——大面积 金丝雀方案 保留V1的Pod(90%流量) 同时部署V2的Pod(10%流量) 观察V2 的错误率延迟业务指标 没问题-- 逐步把权重调到 20% → 50% → 100%V1下线 有问题 → 把权重调回 0%v2 零影 canary-by-header场景内部测试 灰度用户 产品团队需要在生产环境提前体验新版本但不能让普通用户看到 测试人员的请求带上特定 Header curl -H X-Canary: always https://www.shop.com 测试人员可以看到新版本 可以验证功能、UI、性能八、TLS终止模型8.1 TLS Termination(最常见会话卸载)客户端 ──── HTTPS ────→ Ingress Controller ──── HTTP ────→ Pod 加密通道 在这里解密 明文内网 优点 - 证书集中管理 - 后端 Pod 不需要处理 TLS - Controller 可以读取 HTTP 头做路由决策 证书存储方式 K8s Secrettype: kubernetes.io/tls ├── tls.crt证书 └── tls.key私钥8.2 TLS Passthrough客户端 ──── HTTPS ────→ Ingress Controller ──── HTTPS ────→ Pod 加密通道 只转发不解密 Pod 自己解密 适用场景 - 需要端到端加密 - 后端需要看客户端证书mTLS - gRPC 等需要 TLS 的协议 要求 Controller 必须支持 passthroughnginx-ingress 默认不开8.3 Re-encrypt两段加密)客户端 ──── HTTPS ────→ Ingress Controller ──── HTTPS ────→ Pod 证书A 解密后重新用证书B加密 Pod 用证书B解密 本质TLS Termination TLS Origination 的组合 适用中间层需要检查流量但内网也要加密九、Ingress 的局限性1. 功能碎片化 高级功能全靠 annotations 不同 Controller 的 annotations 完全不同 从 nginx 迁移到 traefik 重写所有 annotations 2. 协议局限 原生只支持 HTTP/HTTPS TCP/UDP 路由需要各自的 CRD 扩展非标准 3. 没有角色分离 集群管理员和应用开发者操作同一个 Ingress 对象 无法做到运维控制入口开发者只管路由规则 4. 单一 namespace 问题 Ingress 的 backend 只能引用同 namespace 的 Service 跨 namespace 转发需要额外机制 5. 不支持高级匹配 无法按 Header、QueryParam、Method 做路由 需要靠 annotations 或 ImplementationSpecific案例一最基础的域名路由场景公司有两个服务 - 官网www.shop.com → 前端页面 - 后台admin.shop.com → 管理后台 要求共享同一个入口 IP通过域名区分资源拓扑┌──────────────────────┐ │ DNS 解析 │ │ www.shop.com → 1.2.3.4 │ admin.shop.com → 1.2.3.4 └──────────┬───────────┘ │ ▼ ┌──────────────────────┐ │ Ingress Controller │ │ (外部IP: 1.2.3.4) │ └──────────┬───────────┘ │ ┌───────────────┴───────────────┐ │ 根据 Host 头分流 │ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ web-svc:80 │ │ admin-svc:80 │ └──────┬───────┘ └──────┬───────┘ │ │ ┌─────┴─────┐ ┌─────┴─────┐ ▼ ▼ ▼ ▼ [web-pod1] [web-pod2] [admin-pod1] [admin-pod2]YAML 定义apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: shop-ingress spec: ingressClassName: nginx rules: - host: www.shop.com http: paths: - path: / pathType: Prefix backend: service: name: web-svc port: number: 80 - host: admin.shop.com http: paths: - path: / pathType: Prefix backend: service: name: admin-svc port: number: 80如果用户访问admin.shop.com 流量如何打到后端pod时间线 │ 动作 │ 详细说明 ───────┼──────────────────────────────┼────────────────────── T0 │ 用户浏览器输入 │ │ http://www.shop.com │ ───────┼──────────────────────────────┼────────────────────── T1 │ DNS 解析 │ www.shop.com → 1.2.3.4 │ │ ───────┼──────────────────────────────┼────────────────────── T2 │ TCP 三次握手 │ 客户端 → 1.2.3.4:80 │ │ 建立 TCP 连接 ───────┼──────────────────────────────┼────────────────────── T3 │ 发送 HTTP 请求 │ │ │ GET / HTTP/1.1 │ │ Host: www.shop.com ← 关键 │ │ User-Agent: ... ───────┼──────────────────────────────┼────────────────────── T4 │ Ingress Controller 收到请求 │ nginx-ingress 读取 │ │ HTTP 请求头 ───────┼──────────────────────────────┼────────────────────── T5 │ 匹配 Host │ Host: www.shop.com │ │ → 命中第一条 rule │ │ │ 匹配 Path │ path: / pathType: Prefix │ │ → / 匹配一切命中 │ │ │ 确定 backend │ → web-svc:80 ───────┼──────────────────────────────┼────────────────────── T6 │ Controller 查询 Service │ web-svc 的 ClusterIP │ │ → 10.96.0.100 ───────┼──────────────────────────────┼────────────────────── T7 │ kube-proxy 四层转发 │ 10.96.0.100:80 │ │ iptables/IPVS 规则 │ │ → 选中一个 Pod │ │ → 10.244.1.5:8080 ───────┼──────────────────────────────┼────────────────────── T8 │ Pod 处理请求 │ 前端服务返回 HTML 页面 │ │ ───────┼──────────────────────────────┼────────────────────── T9 │ 响应沿原路返回 │ Pod → kube-proxy → │ │ Controller → 客户端 │ │ 用户看到商城首页案例二同域名不同路径分流路径分发场景一个域名下部署两个服务 shop.com/ → 前端页面服务 shop.com/api → 后端 API 服务资源拓扑客户端请求 │ ▼ ┌──────────────────────────────────┐ │ Ingress Controller │ │ Host: shop.com │ │ │ │ /api/* ──→ api-svc:8080 │ │ /* ──→ frontend-svc:80 │ └──────────────────────────────────┘YAML 定义apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: shop-path-ingress spec: ingressClassName: nginx rules: - host: shop.com http: paths: - path: /api pathType: Prefix backend: service: name: api-svc port: number: 8080 - path: / pathType: Prefix backend: service: name: frontend-svc port: number: 80案例三带 TLS 的完整 HTTPS 流程场景用户访问 https://www.shop.com 要求全链路 HTTPS证书自动签发时间线 │ 动作 │ 详细说明 ───────┼──────────────────────────────┼────────────────────── T0 │ 用户输入 │ https://www.shop.com │ │ ───────┼──────────────────────────────┼────────────────────── T1 │ DNS 解析 │ www.shop.com → 1.2.3.4 ───────┼──────────────────────────────┼────────────────────── T2 │ TCP 三次握手 │ 客户端 → 1.2.3.4:443 ───────┼──────────────────────────────┼────────────────────── T3 │ TLS 握手开始 │ │ │ │ ① ClientHello │ 客户端发送支持的加密套件列表 │ │ 随机数 ClientRandom │ │ │ ② ServerHello │ Controller 选择加密套件 │ │ 随机数 ServerRandom │ │ │ ③ Certificate │ Controller 发送证书 │ │从 Secret 中读取 │ │ CN www.shop.com │ │ │ ④ 客户端验证证书 │ 证书链 → 根CA → 信任 ✓ │ │ 域名匹配 ✓ │ │ 有效期 ✓ │ │ │ ⑤ 密钥交换 │ 客户端生成 PreMasterSecret │ │ 用服务器公钥加密发送 │ │ │ ⑥ 双方计算会话密钥 │ ClientRandom │ │ ServerRandom │ │ PreMasterSecret │ │ → SessionKey │ │ │ ⑦ Finished │ 双方确认加密通道建立 │ │ ───────┼──────────────────────────────┼────────────────────── T4 │ 加密的 HTTP 请求 │ 客户端在 TLS 通道内发送 │ │ GET / HTTP/1.1 │ │ Host: www.shop.com │ │ 这段内容对外界不可见 ───────┼──────────────────────────────┼────────────────────── T5 │ TLS Termination 发生 │ Controller 用 SessionKey 解密 │ │ 得到明文 HTTP 请求 │ │ │ │ ★ 从这里开始后续全在内网明文 ───────┼──────────────────────────────┼────────────────────── T6 │ 路由匹配 │ Host Path → backend ───────┼──────────────────────────────┼────────────────────── T7 │ 转发到后端明文 HTTP │ Controller → web-svc:80 │ │ kube-proxy → Pod:8080 ───────┼──────────────────────────────┼────────────────────── T8 │ Pod 处理返回 HTML │ ───────┼──────────────────────────────┼────────────────────── T9 │ Controller 用 TLS 加密响应 │ HTTP 响应 → TLS 加密 │ │ 发送给客户端 ───────┼──────────────────────────────┼────────────────────── T10 │ 客户端解密渲染页面 │ 用户看到商城首页 │ │ 地址栏显示 证书的生命周期管理┌──────────────────────────────────────────────┐ │ 证书存储位置 │ │ │ │ Secret: tls-secret │ │ type: kubernetes.io/tls │ │ ├── tls.crt (证书 中间证书链) │ │ └── tls.key (私钥) │ └──────────────────┬───────────────────────────┘ │ 被 Ingress 的 spec.tls 引用 ▼ ┌──────────────────────────────────────────────┐ │ Ingress Controller 启动时: │ │ ① 读取 Secret → 加载证书到内存 │ │ ② 配置 nginx 使用该证书 │ │ ③ 监听 Secret 变化 → 证书更新时自动 reload │ └──────────────────────────────────────────────┘案例四路径重写Rewrite的完整流程场景前端调用的 API 路径 https://shop.com/api/users 后端实际接收的路径 /users 要求Ingress 在转发前把 /api 前缀剥掉流程客户端 Ingress Controller api-svc Pod │ │ │ │ GET /api/users │ │ │ Host: shop.com │ │ │─────────────────────────────→│ │ │ │ │ │ ① 匹配规则 │ │ path: /api │ │ pathType: Prefix │ │ → api-svc ✓ │ │ │ │ ② 执行 rewrite-target: / │ │ 原始路径: /api/users │ │ 去掉 /api 前缀 │ │ 重写为: /users │ │ │ │ ③ 转发 │ │ GET /users │ │ │ Host: shop.com │ │ │ ─────────────────────────→│ │ │ │ │ │ ④ Pod 收到 │ │ GET /users │ │ 处理并返回 │ │ │ │ │ ←──────────────────────────│ │ │ ⑤ 响应返回客户端 │ │ │ ←─────────────────────│ │ │ 200 OK │ │ │ [用户数据] │ │正则重写的机制解析path: /api(/|$)(.*) ↑ ↑ 组1 组2 rewrite-target: /$2 ↑ 引用组2的内容 举例 请求路径: /api/users 正则匹配: /api(/)(users) 组1 / 组2 users 重写结果: / users /users 请求路径: /api 正则匹配: /api($) 组1 空字符串结尾 组2 空 重写结果: / 空 / 请求路径: /api/v2/users/detail 正则匹配: /api(/)(v2/users/detail) 组1 / 组2 v2/users/detail 重写结果: / v2/users/detail /v2/users/detail案例五金丝雀发布的完整流程场景app-v1 是当前稳定版本 app-v2 是新版本只让10%的流量进来试水 三种金丝雀策略都需要理解策略一按权重分流100% 流量 │ ▼ ┌────────────────┐ │ Ingress │ │ Controller │ │ │ │ canary-weight │ │ : 10 │ └────┬──────┬───┘ │ │ 90% │ │ 10% ▼ ▼ ┌────────┐ ┌────────┐ │ app-v1 │ │ app-v2 │ │ 稳定 │ │ 金丝雀│ └────────┘ └────────┘# 主 Ingress稳定版 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app-stable spec: ingressClassName: nginx rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: app-v1-svc port: number: 80 --- # 金丝雀 Ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app-canary annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-weight: 10 spec: ingressClassName: nginx rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: app-v2-svc port: number: 80权重分流的判定流程每个请求到达 Controller 时 请求进入 │ ▼ ┌───────────────────────────┐ │ 检查是否有 canary Ingress │ │ 且 host path 匹配 │ │ │ │ │ 有 ──┤── 无 │ │ │ │ │ │ ▼ ▼ │ │ 进入金丝雀 直接走主 │ │ 判定逻辑 Ingress │ │ │ │ │ ▼ │ │ 生成随机数 0-100 │ │ │ │ │ ┌────┴────┐ │ │ ▼ ▼ │ │ 10 10 │ │ │ │ │ │ ▼ ▼ │ │ app-v2 app-v1 │ │ (金丝雀) (稳定) │ └───────────────────────────┘策略二按Header 分流annotations : nginx.ingress.kubernetes.io/canary:trune nginx.ingress.kubernetes.io/canary-by-header:X-Cannery nginx.ingress.kubernetes.ip/canery-by-header-value:always判定流程 请求进入 | 检查HTTP Header | X-Canary:alwary ---- app-v2 金丝雀 X-canary:其他值 ---- app-v1 (稳定) 没有X-Canary 头 ---- app-v1 (稳定)实际使用场景 测试人员访问新版本 curl -H X-Canary:always https://app.example.com 看到 V2 版本 普通用户正常访问 curl http://app.example.com/ 看到v1稳定版本金丝雀Ingress 的处理优先级当主Ingress 和 Canary Ingress 同时存在时 先检查 canary-by-head 有就按照匹配走 不匹配或者没设置检查 canary-by-cookie ,有就匹配按照Cookie 结果走 都没有检查canary-weight 按照权重分配canary-weight: 0 所有流量走主Ingress;canary-weight:100所有流量走金丝雀 优先级Header Cookie Weight策略三按照Cookie分流策略annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-by-cookie: canary_cookie判定逻辑 请求 Cookie 中有 canary_cookiealways → 金丝雀 请求 Cookie 中有 canary_cookienever → 稳定版 没有这个 Cookie → 稳定版典型场景 测试人员第一次访问后后端设置 Cookie 后续请求自动路由到金丝雀版本 实现粘性金丝雀——同一个用户始终看到同一个版本任意一个请求到达 Controller │ ▼ ┌───────────────────────────────────────────────────────┐ │ Step 1: 匹配 host path │ │ │ │ 该请求的 host 和 path 是否同时匹配 │ │ 主 Ingress (app-stable) │ │ Canary Ingress (app-canary) │ │ │ │ ├── 不匹配 → 走普通路由逻辑不涉及金丝雀 │ │ └── 同时匹配 → 进入金丝雀判定 │ │ │ │ Step 2: 检查 Header 优先级 │ │ │ │ canary-by-header 设置了吗 │ │ ├── 设置了 → 检查请求 Header │ │ │ ├── Header 值匹配 canary-by-header-value │ │ │ │ └── → 100% 去 v2判定结束 │ │ │ └── Header 值不匹配 │ │ │ └── → 100% 去 v1判定结束 │ │ └── 没设置 → 继续 │ │ │ │ Step 3: 检查 Cookie 优先级 │ │ │ │ canary-by-cookie 设置了吗 │ │ ├── 设置了 → 检查请求 Cookie │ │ │ ├── Cookie always → 100% 去 v2 │ │ │ ├── Cookie never → 100% 去 v1 │ │ │ └── 没有这个 Cookie → 100% 去 v1 │ │ └── 没设置 → 继续 │ │ │ │ Step 4: 按权重随机判定 │ │ │ │ 取 $request_id 做哈希 │ │ 映射到 0% ~ 100% │ │ ├── canary-weight(10%) → 去 v2金丝雀 │ │ └── canary-weight(10%) → 去 v1稳定 │ │ │ └───────────────────────────────────────────────────────┘案例六故障排查流程场景配置了Ingress ,但是访问返货502 Bad Gateway,如何排查 502 Bad Gateway │ │ 含义Ingress Controller 收到了请求 │ 但转发到后端时失败了 │ ▼ 第一步Controller 能连到 Service 吗 │ ├── 检查 Service 是否存在 │ kubectl get svc name -n namespace │ 不存在 → Ingress 写了错误的 Service 名 → 修复 YAML │ ├── 检查 Service 的 Endpoints 是否有值 │ kubectl get endpoints svc-name │ Endpoints 为空 → 没有 Pod 被选中 │ │ │ └── 检查 selector 是否匹配 Pod 的 labels │ kubectl get pods --show-labels │ labels 不匹配 → 修复 Deployment 的 labels 或 Service 的 selector │ └── Endpoints 有值 → Service 和 Pod 连通 │ ▼ 第二步Pod 本身正常吗 │ ├── Pod 状态是 Running 吗 │ kubectl get pods │ CrashLoopBackOff → Pod 启动失败 → 看日志 │ ├── Pod 的端口对吗 │ Service port: 80 → targetPort: 8080 │ 但 Pod 实际监听的是 3000 → 端口不匹配 → 修复 │ └── Pod 的健康检查通过吗 Readiness Probe 失败 → Pod 不会加入 Endpoints │ ▼ 第三步Ingress 规则写对了吗 │ ├── pathType 和 path 匹配对吗 │ 用 kubectl describe ingress 查看规则 │ ├── ingressClassName 指向的 Controller 存在吗 │ kubectl get ingressclass │ └── annotations 语法有没有拼写错误 拼错的 annotation 会被静默忽略 最终定位工具 kubectl describe ingress name → 看 Ingress 状态和事件 kubectl logs -n ingress-nginx pod → 看 Controller 日志 kubectl exec -it pod -- curl localhost:8080 → 直接测 Pod从 502 反推的完整故障树502 Bad Gateway ├── Service 不存在或端口错 │ └── kubectl get svc, kubectl describe svc │ ├── Endpoints 为空 │ ├── selector 不匹配 labels │ ├── Pod 没有 Running │ └── Readiness Probe 失败 │ ├── Pod 无法响应 │ ├── 端口不匹配targetPort vs containerPort │ ├── 应用内部报错看 Pod 日志 │ └── 资源不足导致 OOM │ ├── 网络策略阻断 │ └── NetworkPolicy 阻止了 Controller → Pod 的流量 │ └── Controller 自身问题 ├── nginx.conf 生成错误 └── reload 失败整体学习检验清单□ 能画出请求从客户端到 Pod 的完整路径 □ 能解释 Host 匹配和 Path 匹配的执行顺序 □ 能区分三种 pathType 的行为差异 □ 能解释 TLS Termination 发生在哪个环节 □ 能解释 Controller 的控制循环机制 □ 能解释 annotations 为什么是 Controller 特有的 □ 能描述金丝雀发布的两种分流策略及优先级 □ 能从 502 错误反推排查思路 □ 能对比三种主流 Controller 的核心差异 □ 能解释 Ingress 与 kube-proxy 的协作关系
返回列表