# Kubernetes Ingress 完全指南(适用于 Kubernetes v1.35)

📅 2026/7/23 10:16:18
# Kubernetes Ingress 完全指南(适用于 Kubernetes v1.35)
Kubernetes Ingress 完全指南适用于 Kubernetes v1.35文档说明适用版本Kubernetes v1.35.4networking.k8s.io/v1前置知识了解 Pod、Service 的基本概念目标从零掌握 Ingress 的原理、配置、部署与流量路径第一章为什么需要 Ingress在 Kubernetes 中Service 是 Pod 的稳定访问入口但 Service 类型存在明显局限Service 类型局限ClusterIP仅集群内部可访问无法对外提供服务NodePort端口范围固定30000-32767不易记忆Node IP 变更频繁无法支持域名和路径路由LoadBalancer每个 Service 需独立公网 IP成本高昂不支持 L7HTTP/HTTPS层面的高级路由Ingress 解决了什么问题Ingress 是 Kubernetes 中管理集群外部访问集群内服务的 API 对象它通过定义 HTTP/HTTPS 路由规则将外部流量从集群边界路由到集群内的 Service。一句话总结Ingress 让你用一个公网 IP/域名对外暴露多个内部服务并支持基于域名、路径的精细化路由。第二章核心概念务必分清很多初学者混淆这三者实际上它们分工明确概念作用通俗类比Ingress Controller实际的程序Pod负责处理流量并执行路由转发如 Nginx、Traefik、Envoy。真正的“保安”站在门口拦截和指引访客Ingress 资源你写的 YAML 配置文件定义了“哪个域名指向哪个服务”的规则。给保安的“工作手册”告诉他遇到谁该带去哪个房间IngressClass标识集群中安装了多个 Controller 时该 Ingress 资源由哪个 Controller 处理。标识“这是保安 A 负责的片区”还是“保安 B 负责的片区”⚠️ 重要提示仅创建 Ingress 资源YAML不会生效你必须在集群中安装并运行一个 Ingress Controller如 Nginx Ingress Controller否则 Kubernetes 只会忽略它。第三章流量全链路解析请求是如何到达 Pod 的理解了概念之后你需要明白一件事一条外部请求是如何最终进入你的容器里的本章从请求进入集群的那一刻开始拆解完整路径。3.1 整体路径概览默认模式hostNetwork: false互联网用户 │ ▼ 访问 http://example.com/api ┌─────────────────────────────────────────────────────────────┐ │ Kubernetes 集群边界 │ │ │ │ 第1步请求到达宿主机 NodePort如 30080 │ │ └─ 由 Ingress Controller 的 ServiceNodePort 类型暴露│ │ │ │ 第2步kube-proxy 拦截并转发 │ │ └─ iptables/IPVS 规则将流量转发到 Controller Pod IP │ │ │ │ 第3步Ingress Controller PodNginx 容器接收请求 │ │ └─ 根据 Ingress 规则Host/Path匹配后端 Service │ │ │ │ 第4步Nginx 通过 Service 的 ClusterIP 转发请求 │ │ └─ 再次经过 kube-proxy负载均衡到后端 Pod │ │ │ │ 第5步目标 Pod 接收请求处理并返回响应 │ └─────────────────────────────────────────────────────────────┘ │ ▼ 返回响应原路返回3.2 各步骤详解第 1 步外部流量如何进入集群Ingress Controller 本身是一个 Deployment 或 DaemonSet但它并不直接暴露在公网上。它依赖一个类型为NodePort或LoadBalancer的Service来接收外部流量。场景 A使用 NodePort 方式kubectl get svc-ningress-nginxNAME TYPE CLUSTER-IP PORT(S) AGE ingress-nginx-controller NodePort 10.96.0.1 80:30080/TCP,443:30443/TCP 10dService 将容器的80 端口映射到宿主机的30080 端口外部用户访问http://任意节点IP:30080请求进入集群场景 B使用 LoadBalancer 方式云环境设置 Service 为LoadBalancer类型云厂商自动分配公网 IP将流量直接转发到 Controller Pod。第 2 步kube-proxy 如何把流量交给 Controller Podkube-proxy运行在每个节点上维护网络规则请求到达节点的30080端口时内核中的iptables或IPVS规则拦截请求规则由kube-proxy根据 Service 的 Endpoints 动态生成将请求随机或轮询地转发到其中一个 Ingress Controller Pod 的 IP 上此时请求已经从“宿主机网卡”进入了“容器网络”。第 3 步ControllerNginx内部做了什么请求进入 Ingress Controller Pod 内部的Nginx 容器Nginx 监听容器内部的 80/443 端口Nginx 配置文件动态生成由 Ingress Controller 进程根据 Ingress 资源实时更新匹配server_name域名和location路径决定转发目标自动生成的 Nginx 配置片段示例server { listen 80; server_name example.com; location /api { proxy_pass http://backend-api-service.default.svc.cluster.local:8080; } location / { proxy_pass http://frontend-service.default.svc.cluster.local:80; } }关键点Nginx 转发时使用的是Service 的 DNS 域名ClusterIP利用 Kubernetes 内置的服务发现能力。第 4 步从 Controller 到后端 ServiceNginx 将请求发往backend-api-service.default.svc.cluster.local:8080解析到Service 的 ClusterIP如10.96.0.100再次被kube-proxy拦截根据 Endpoints 负载均衡到其中一个 Pod第 5 步Pod 处理并返回响应业务应用处理请求生成响应响应沿完全相同路径原路返回Pod → kube-proxy → Ingress Controller Pod → kube-proxy → 宿主机 → 用户第四章Ingress YAML 核心字段详解4.1 API 版本Kubernetes v1.35apiVersion:networking.k8s.io/v1# 唯一的稳定版本v1.22 唯一支持kind:Ingress4.2 完整 YAML 结构apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:my-app-ingressnamespace:defaultannotations:# 关键通过注解控制 Controller 行为nginx.ingress.kubernetes.io/rewrite-target:/nginx.ingress.kubernetes.io/proxy-body-size:50mspec:ingressClassName:nginx# v1.35 推荐方式指定 ControllerdefaultBackend:# 可选所有规则不匹配时的默认后端service:name:default-backendport:number:80rules:# 核心路由规则列表-host:www.example.com# 可选不写则匹配所有域名http:paths:-path:/apipathType:Prefix# 路径匹配类型Exact / Prefix / ImplementationSpecificbackend:service:name:api-serviceport:number:8080-path:/pathType:Prefixbackend:service:name:web-serviceport:number:80tls:# 配置 HTTPS-hosts:-www.example.comsecretName:example-tls-secret4.3 关键字段深度解析pathType路径匹配类型类型行为示例Exact严格区分大小写完全匹配 URL 路径/foo匹配/foo不匹配/foo/或/foobarPrefix基于/分隔的前缀匹配/foo匹配/foo、/foo/、/foobarImplementationSpecific由具体 Ingress Controller 自行决定可移植性差不推荐ingressClassNamev1.35 推荐方式当集群中有多个 Ingress Controller 时通过此字段精确指定# 查看集群中的 IngressClasskubectl get ingressclass# 输出示例NAME CONTROLLER PARAMETERS AGE nginx k8s.io/ingress-nginxnone10d traefik traefik.io/ingress-controllernone5dbackend后端服务定义在 v1.35 中backend必须指向具体的 Service 对象支持两种写法Service最常见Resource指向自定义资源极少用第五章实战场景配置5.1 场景一基于路径的路由微服务拆分需求example.com/api/*→ API 服务example.com/*→ Web 服务。apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:path-routingannotations:nginx.ingress.kubernetes.io/rewrite-target:/$2spec:ingressClassName:nginxrules:-host:example.comhttp:paths:-path:/api(/|$)(.*)pathType:Prefixbackend:service:name:backend-apiport:number:8080-path:/pathType:Prefixbackend:service:name:frontend-webport:number:80注解说明rewrite-target: /$2将/api/v1/users重写为/v1/users发送给后端。5.2 场景二基于域名的虚拟主机多租户需求blog.example.com→ Blog 服务shop.example.com→ Shop 服务。apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:virtual-host-routingspec:ingressClassName:nginxrules:-host:blog.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:blog-serviceport:number:80-host:shop.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:shop-serviceport:number:805.3 场景三配置 HTTPSTLS 终止Step 1创建 TLS Secret# Secret 必须与 Ingress 在同一 Namespacekubectl create secret tls example-tls\--key./tls.key\--cert./tls.crtStep 2在 Ingress 中引用apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:tls-ingressspec:ingressClassName:nginxtls:-hosts:-example.comsecretName:example-tlsrules:-host:example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:web-serviceport:number:80效果访问https://example.com时流量到达 Controller 后被解密再转发给后端。5.4 场景四默认后端自定义 404访问的域名或路径不在任何规则中时流量进入defaultBackend。apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:with-default-backendspec:ingressClassName:nginxdefaultBackend:service:name:custom-404-serviceport:number:80rules:-host:valid.example.comhttp:paths:-path:/pathType:Prefixbackend:service:name:main-appport:number:80第六章常用 Ingress Controller 注解速查表NginxIngress 本身功能有限强大的流量治理能力完全依赖Annotations注解。分类注解示例值用途路径重写nginx.ingress.kubernetes.io/rewrite-target/$2重写 URL 路径后再转发Session 保持nginx.ingress.kubernetes.io/affinitycookie开启会话粘滞Session 保持nginx.ingress.kubernetes.io/session-cookie-nameroute自定义 Cookie 名超时设置nginx.ingress.kubernetes.io/proxy-connect-timeout30连接后端超时秒超时设置nginx.ingress.kubernetes.io/proxy-read-timeout180读取响应超时秒速率限制nginx.ingress.kubernetes.io/limit-rps10每秒请求数限制速率限制nginx.ingress.kubernetes.io/limit-whitelist192.168.1.0/24白名单 IP 不限制CORSnginx.ingress.kubernetes.io/enable-corstrue开启跨域支持认证nginx.ingress.kubernetes.io/auth-typebasic基础认证认证nginx.ingress.kubernetes.io/auth-secretmy-secret存储用户名密码的 SecretBody 大小nginx.ingress.kubernetes.io/proxy-body-size50m上传文件大小限制第七章高级配置——hostNetwork: true7.1 什么是hostNetwork: true当你在 Ingress Controller 的 Deployment 中设置hostNetwork: true时Pod不再拥有独立的容器网络命名空间而是直接共享宿主机的网络栈。Pod 里的 Nginx 监听的 80 端口就等于直接绑定了宿主机的 80 端口。7.2 开启前后的流量路径对比默认模式hostNetwork: false用户 → 宿主机IP:30080(NodePort) → kube-proxy(iptables) → CNI网络跨越节点 → Ingress Controller Pod IP如 10.244.1.5:80 → Nginx 处理路由 → 再次经过 kube-proxy → 业务 Pod10.244.2.6:8080开启 hostNetwork: true用户 → 宿主机IP:80 (直接请求) → 宿主机网络协议栈 → 直接命中 Nginx 进程因为共享内核 → Nginx 根据规则转发 → 可能经过或不经过 kube-proxy → 业务 Pod7.3 关键变化对比项默认模式hostNetwork: true用户访问目标宿主机IP:30080宿主机IP:80标准端口是否支持标准 80/443 端口❌ 需端口映射✅ 直接监听是否经过 kube-proxy 第一跳✅ 必须经过❌ 直接绕过性能中等有 NAT 损耗极佳无损耗7.4 优缺点分析优点极致性能去除了 CNI 网络的 overlay 封装和 kube-proxy 的第一层 NAT延迟更低获取真实客户端 IPNginx 直接看到$remote_addr的真实用户 IP使用标准端口可以直接使用 80/443无需 NodePort 的 30000 端口缺点端口冲突同一台宿主机只能运行一个监听 80 端口的 Controller Pod宿主机网络依赖Pod 不受NetworkPolicy限制防火墙规则需自行维护可移植性降低对宿主机网络有强依赖7.5 YAML 配置示例apiVersion:apps/v1kind:Deploymentmetadata:name:ingress-nginx-controllernamespace:ingress-nginxspec:template:spec:hostNetwork:true# 关键开启宿主机网络模式dnsPolicy:ClusterFirstWithHostNet# 重要确保 DNS 解析走集群内部containers:-name:controllerimage:registry.k8s.io/ingress-nginx/controller:v1.11.07.6 适用场景DaemonSet 部署每个节点运行一个 Controller 副本避免端口冲突高性能网关场景对延迟极度敏感需要极致性能边缘节点部署将 Controller 部署在特定边缘节点作为集群的统一流量入口第八章安装 Ingress Controller正如前面强调的YAML 写完后必须安装 Controller。以Nginx Ingress Controller为例8.1 使用 Helm 安装推荐# 注意创建ingress controller 有最低配置需求如果测试环境遇到配置低需要多加配置# 添加 Helm 仓库helm repoaddingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update# 安装默认 NodePort 模式helminstallingress-nginx ingress-nginx/ingress-nginx\--setcontroller.service.typeNodePort# 或安装为 DaemonSet hostNetwork 模式高性能helminstallingress-nginx ingress-nginx/ingress-nginx\--setcontroller.kindDaemonSet\--setcontroller.hostNetworktrue\--setdnsPolicyClusterFirstWithHostNet# 或者安装阿里的higresshelm repoaddhigress.io https://higress.io/helm-charts helminstallhigress higress.io/higress-nhigress-system --create-namespace8.2 验证安装# 查看 Controller Podkubectl get pods-ningress-nginx# 查看 Servicekubectl get svc-ningress-nginx# 查看 IngressClasskubectl get ingressclass第九章故障排查三板斧创建 Ingress 后发现无法访问按此顺序排查9.1 检查 Ingress 资源状态kubectl describe ingressingress-name查看Events字段是否有Succeeded或报错信息。9.2 检查 Ingress Controller 状态# 查看 Controller Pod 状态kubectl get pods-ningress-nginx# 查看 Controller 日志kubectl logs-fdeployment/ingress-nginx-controller-ningress-nginx9.3 检查 Service Endpointskubectl get endpointsservice-name如果ENDPOINTS列为空说明 Service 的 Label Selector 没有匹配到任何 Pod。9.4 从 Controller Pod 内测试连通性# 进入 Controller 容器kubectlexec-itcontroller-pod-ningress-nginx -- /bin/bash# 测试能否访问后端 Servicecurl-vhttp://backend-service-ip第十章最佳实践总结始终指定ingressClassName明确指定 Ingress Controller避免多 Controller 环境下的歧义使用 TLS/HTTPS生产环境务必开启 TLS证书存放为 Secret善用默认后端配置自定义 404 页面避免暴露 Nginx 默认错误页谨慎使用正则表达式过度使用正则可能降低路由性能设置资源请求与限制为 Ingress Controller Pod 设置 CPU/内存限制根据场景选择部署模式一般场景Deployment NodePort/LoadBalancer高性能场景DaemonSet hostNetwork: true附录快速索引需求命令/配置查看 Ingress 列表kubectl get ingress -A查看 Ingress 详情kubectl describe ingress name查看 IngressClasskubectl get ingressclass查看 Controller 日志kubectl logs -f deployment/ingress-nginx-controller -n ingress-nginx检查 Service Endpointskubectl get endpoints service-name开启 hostNetworkhostNetwork: truednsPolicy: ClusterFirstWithHostNet路径重写nginx.ingress.kubernetes.io/rewrite-target: /$2开启 HTTPStls.secretName引用包含证书的 Secret文档版本v1.0整合完整版适用环境Kubernetes v1.35 / networking.k8s.io/v1推荐 ControllerNginx Ingress Controllerv1.11