当前位置: 首页 > news >正文

K8s 服务太多?一个 Ingress 全搞定

一、你肯定遇到过这个场景

线上跑了 5 个微服务,每个都要对外暴露。如果用 NodePort,就需要给每个服务分配一个 30000+ 的端口,前端配了一堆端口号,运维在防火墙上开端口开到崩溃。再配上 TLS 证书,每个服务单独配一遍,重复劳动。

说白了,Service 的 NodePort 只解决**四层(TCP/UDP)**访问,没有应用层路由能力。NodePort 范围固定在 30000-32767,服务多了端口就不够用;如果用 LoadBalancer,云上每个 Service 都要买一个 CLB,成本直线上升。

这时候你需要的不是更多端口,而是Ingress——K8s 里统一流量入口的七层负载均衡,一个入口搞定所有微服务的域名路由、路径分发、TLS 终止

二、三个概念。

1.概念

很多人一开始把 Ingress、Ingress Controller、IngressClass 当成一回事,其实三层分工明确:

概念是什么类比
Ingress规则文件(YAML),定义"哪个域名走哪个 Service"菜单
Ingress Controller真正干活的 Pod,读取 Ingress 规则并执行厨师
IngressClass标记"这条规则给哪个 Controller 处理"厨房编号

核心逻辑:你写 Ingress YAML → Ingress Controller 读到规则 → 更新内部 Nginx/Envoy 配置 → 流量按规则转发。

2.常见的 Controller 选型

Controller适用场景
ingress-nginx(k8s社区版)最通用,生态最全
nginx-ingress(Nginx公司版)需要商业支持
Traefik自动发现、自带 Dashboard
Istio Gateway服务网格场景

新手用 ingress-nginx 就够了。

等等,Ingress 是不是 K8s 自带的?不是。Ingress 不是 Kubernetes 核心组件,它是一个可选的 API 资源对象,需要单独安装 Controller 才能工作。把它想象成集群的「智能路由器」或「门户守卫」——根据规则(主机名、路径)将请求分发到不同的后端 Service。只创建 Ingress YAML 不管用,必须配合 Controller 一起部署。

3.Ingress 和 Service 对比

Ingress 和 Service 到底什么关系?很多人一开始也迷糊,看这张表就清楚了:

特性IngressService
工作层七层(HTTP/HTTPS)四层(TCP/UDP/SCTP)
路由能力按域名、路径、Header 匹配仅按端口和 ClusterIP
协议支持HTTP、HTTPS、gRPC任意 TCP/UDP
实现方式依赖 Ingress Controller Podkube-proxy(iptables/IPVS)或云 LB
主要目的外部 HTTP 流量入口统一管理集群内部服务发现与负载均衡

简单理解:Service 负责把流量送进集群,Ingress 负责把流量送到正确的 Service。两者是配合关系,不是替代关系。

三、从零搭一个 Ingress

1. 安装 ingress-nginx Controller

1.1 kubectl一键部署
#先下载官方完整 YAMLwgethttps://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml-Onginx-deploy.yaml#修改部署nginx-deploy.yaml YAML 中的 image 字段registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.0 registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.0#修改service类型为 NodePort# type: LoadBalancertype: NodePort#修改deploy使用宿主机端口kind: Deployment... ports: - containerPort:80name: http hostPort:80protocol: TCP - containerPort:443name: https hostPort:443protocol: TCP#部署kubectl apply-fnginx-deploy.yaml

部署文件里都装了些什么?除了 Controller Deployment,官方 YAML 还自动创建了 Namespace、ServiceAccount、Role/ClusterRole、ValidatingWebhook 等资源。其中 RBAC 权限是 Controller 能正常工作的前提——它需要通过 API Server 监听 Ingress 资源的变化:

# Controller 需要的完整 RBAC 权限(官方 deploy.yaml 自动创建)rules:# 监听 Ingress/IngressClass 变化- apiGroups:["networking.k8s.io"]resources:["ingresses","ingressclasses"]verbs:["get","list","watch"]# 更新 Ingress 状态(ADDRESS 字段)- apiGroups:["networking.k8s.io"]resources:["ingresses/status"]verbs:["update"]# 读取 Service/Endpoints/ConfigMap/Secret/Pod(构建 upstream)- apiGroups:[""]resources:["services","endpoints","configmaps","pods","secrets","namespaces"]verbs:["get","list","watch"]

这些权限覆盖了 Controller 的全部工作流:发现 Ingress 规则 → 读取后端 Service/Endpoints → 更新 Nginx 配置 → 回写 Ingress 状态。如果权限不足,Controller 日志会报forbidden,Ingress 规则不会生效。

1.2 使用 Helm 部署,便于后续升级和回滚(生产推荐)
  • 添加仓库、拉取代码
# 添加仓库 & 更新helm repoaddingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update#拉取代码[root@master-1 ingress]# helm pull ingress-nginx/ingress-nginx#内网环境可直接从外网下载https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.12.3/ingress-nginx-4.12.3.tgz
  • 修改关键配置
# values.yaml 关键修改(国内环境)[root@master-1 ingress-nginx]# vim values.yamlglobal: image: registry: registry.aliyuncs.com controller: image: image: google_containers/nginx-ingress-controller tag:"v1.10.0"admissionWebhooks: patch: image: image: google_containers/kube-webhook-certgen tag: v1.4.0 hostPort: enabled:trueports: http:80https:443service: type: NodePort
  • 部署
[root@master-1 ingress-nginx]# cd ../#部署ingress-nginx[root@master-1 ingress]# helm install ingress-nginx ingress-nginx -n ingress-nginx --create-namespace -f ingress-nginx/values.yaml#查看[root@master-1 ingress]# helm list -n ingress-nginxNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION ingress-nginx ingress-nginx12025-07-0114:42:20.362166146 +0800 CST deployed ingress-nginx-4.12.31.12.3

如下图所示,我们已经部署好了ingress controller

  • 补充helm常用命令
#搜索ingress-nginx[root@master-1 ingress]# helm search repo ingress-nginxNAME CHART VERSION APP VERSION DESCRIPTION ingress-nginx/ingress-nginx4.12.31.12.3 Ingress controllerforKubernetes using NGINX a...# 下载ingress-nginx[root@master-1 ingress]# helm pull ingress-nginx/ingress-nginx#安装 ingress-nginx ingress-nginx 第一个是为ingress服务取名称为ingress-nginx,第二个是目录名[root@master-1 ingress]# helm install ingress-nginx ingress-nginx -n ingress-nginx --create-namespace -f ingress-nginx/values.yaml#卸载 ingress-ngin[root@master-1 ingress]# helm uninstall ingress-nginx -n ingress-nginx

⚠️部署前必查hostPort会占用宿主机的 80 和 443 端口。如果宿主机上已经跑了原生 Nginx、Apache 或其他 Web 服务,Ingress Controller 会因端口冲突启动失败。先用ss -tlnp | grep -E ':80 |:443 '确认端口空闲再部署。

2. 部署nginx应用

# nginx.yamlapiVersion: apps/v1 kind: Deployment metadata: name: nginx-v1 spec: replicas:2#基于标签关联pod,会关联env=test或者env=prod的podselector: matchExpressions: - key:envvalues: -"test"-"prod"operator: In template: metadata:#为pod设置了两个标签labels: app: nginx-v1 env:testspec: containers: - name: nginx-v1 image: nginx:1.22.1 imagePullPolicy: IfNotPresent --- apiVersion: v1 kind: Service metadata: name: nginx-service-v1 spec:# 指定svc的类型为NodePort,也就是在默认的ClusterIP基础之上多监听所有worker节点的端口而已。type: NodePort# 基于标签选择器关联Podselector: app: nginx-v1# 配置端口映射ports:# 指定Service服务本身的端口号- port:80# 后端Pod提供服务的端口号targetPort:80

同样方式部署nginx-v2,标签和名称换成nginx-v2

3. 写 Ingress 规则

# ingress.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:my-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target:/spec:ingressClassName:nginxrules:-host:nginx.liux.comhttp:paths:-path:/v1pathType:Prefixbackend:service:name:nginx-service-v1port:number:80-path:/v2pathType:Prefixbackend:service:name:nginx-service-v2port:number:80#ingressClassName: nginx 可以通过以下方式查看[root@master-1 ~]# kubectl get ingressclassesNAME CONTROLLER PARAMETERS AGE nginx k8s.io/ingress-nginx <none>31m#部署[root@master-1 ~]# kubectl apply -f nginx-route.yaml

关键字段解释:

  • ingressClassName: nginx— 指定用 nginx Controller 处理
  • host: nginx.liux.com— 只处理这个域名的请求
  • path: /v1+pathType: Prefix— 前缀匹配,/v1/xxx全部命中
  • rewrite-target: /— 去掉路径前缀再转发(/v1/hello/hello

4. 验证

# 查看 Ingress 状态kubectl get ingress# NAME CLASS HOSTS ADDRESS PORTS# my-ingress nginx app.example.com 192.168.1.x 80# 本地测试(加 hosts 后)curlhttp://nginx.liux.com/v1

浏览器验证:在本地/etc/hosts(Linux/Mac)或C:\Windows\System32\drivers\etc\hosts

(Windows)中添加:

<NodeIP> nginx.liux.com

浏览器访问http://nginx.liux.com/v1即可看到对应服务的返回页面。curl 能通但浏览器不通时,优先检查本地 hosts 是否配置正确。

四、三个进阶配置

1.配置 TLS

spec:#https相关tls:-hosts:-nginx.liux.comsecretName:liux-tls
  • 没有现成证书?快速生成自签证书用于测试:
# 生成 365 天有效期的自签证书openssl req-x509-newkeyrsa:2048-nodes-keyouttls.key-outtls.crt-days365-subj"/CN=nginx.liux.com"# 证书存入 Secretkubectl create secret tls liux-tls--cert=tls.crt--key=tls.key# 确认 Secret 已创建kubectl get secret|grepliux-tls liux-tls kubernetes.io/tls254s

  • 完整 HTTPS 实战示例
[root@master-1 nginx]# cat nginx-route.yaml# ingress.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:my-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target:/spec:ingressClassName:nginxrules:-host:nginx.liux.comhttp:paths:-path:/v1pathType:Prefixbackend:service:name:nginx-service-v1port:number:80-path:/v2pathType:Prefixbackend:service:name:nginx-service-v2port:number:80#https相关tls:-hosts:-nginx.liux.comsecretName:liux-tls
kubectl apply-fnginx-route.yaml# 查看 Ingress,确认同时暴露了 80 和 443 端口kubectl get ingress ingress-https

浏览器访问https://nginx.liux.com/v1验证。如果浏览器提示证书不安全,属于自签证书正常现象,点击「继续访问」即可。

4.2 路径重写(最实用)

annotations:nginx.ingress.kubernetes.io/rewrite-target:/$2spec:rules:-host:nginx.liux.comhttp:paths:-path:/api(/|$)(.*)pathType:ImplementationSpecificbackend:service:name:user-serviceport:number:80

效果:/api/user→ 转发到 user-service 的/user

4.3 多域名分流

rules:-host:nginx.liux.comhttp:paths:-path:/pathType:Prefixbackend:service:name:nginx-serviceport:number:80-host:api.liux.comhttp:paths:-path:/pathType:Prefixbackend:service:name:api-serviceport:number:80

一个 Ingress 搞定多域名,不用多开端口。

五、实战场景:微服务统一入口

假设有一个典型的 web 应用架构:前端页面(Nginx 静态资源)、后端 API(Java 服务)、管理后台(Admin),三个服务架构图如下:

用户请求 │ ├─ app.liux.com/ → frontend (前端页面) ├─ app.liux.com/api → api (后端接口) └─ admin.liux.com/ → admin (管理后台)

5.1 部署服务

# 1. 部署前端kubectl create deployment frontend--image=nginx:1.22.1--replicas=2kubectl expose deployment frontend--port=80# 2. 部署后端 API 示例kubectl create deployment api--image=ealen/echo-server--replicas=1kubectl expose deployment api--port=80# 3. 部署管理后台kubectl create deployment admin--image=nginx:1.22.1--replicas=1kubectl expose deployment admin--port=80

5.2 配置Ingress规则 统一接入

# common-ingress.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:common-ingressannotations:# /api 路径转发时去掉 /api 前缀nginx.ingress.kubernetes.io/rewrite-target:/$2spec:ingressClassName:nginxrules:# 主域名:前端 + API-host:app.liux.comhttp:paths:-path:/pathType:Prefixbackend:service:name:frontendport:number:80-path:/api(/|$)(.*)pathType:ImplementationSpecificbackend:service:name:apiport:number:80# 子域名:管理后台-host:admin.liux.comhttp:paths:-path:/pathType:Prefixbackend:service:name:adminport:number:80#部署kubectl apply-f common-ingress.yaml

5.3 验证入口是否生效

# 检查 Ingress ADDRESS 是否分配kubectl get ingress common-ingress NAME CLASS HOSTS ADDRESS PORTS AGE common-ingress nginx app.liux.com,admin.liux.com10.0.0.1458019s# 本地测试(先配 hosts: nodeport app.example.com admin.example.com)curlhttp://app.liux.com/# → frontendcurlhttp://app.liux.com/api/users# → api(转发为 /users)# 重点验证路径重写# 请求 /api/users → api service 收到的是 /users# 或者直接看 Controller 日志kubectl logs-ningress-nginx deployment/ingress-nginx-controller--tail=10

可以看到:三个微服务、两个域名、不同路径,全部通过一个 Ingress 入口搞定,不用暴露额外端口,不用单独配负载均衡器。

六、常见排坑

坑1:Ingress 配置了但访问 404

# 先确认 Controller 是否在跑kubectl get pods-ningress-nginx# 检查 Ingress 规则是否被正确读取kubectl describe ingress my-ingress

90% 的情况是pathType写错了,PrefixExact行为完全不同。不确定就用Prefix

坑2:rewrite-target 没生效

确认注解写的是nginx.ingress.kubernetes.io/rewrite-target,不是nginx.org/rewrite-target。两个是不同 Nginx 版本的前缀,混用不生效。

坑3:TLS 证书配了但不生效

# 检查 Secret 是否存在kubectl get secret app-tls-secret# 检查 Ingress 引用是否正确kubectl get ingress my-ingress-oyaml|grepsecretName

另注意:Secret 必须在同一个 namespace下才能被 Ingress 引用。

坑4:多个 Controller 互相抢流量

如果集群里装了多个 Ingress Controller(比如同时装了 nginx 和 traefik),必须用ingressClassName明确指定,不然流量随机跑到某个 Controller 上。

七、总结

回到最初的问题:线上跑了 N 个微服务,每个都要对外暴露,怎么办?

Ingress 本质就是 K8s 的七层反向代理规则——你写规则,Controller 执行。一个入口搞定域名路由、路径分发、TLS 终止,不用给每个服务开端口、买负载均衡器。

1.速查回顾

环节关键操作一句话
选型Ingress(规则)+ Controller(执行)+ Class(标记)新手直接ingress-nginx
部署kubectl apply -f deploy.yamlhelm install提前确认 80/443 端口不冲突
规则host+path+backend.service写 YAML 绑定域名和路径到 Service
TLStls.secretName引用 Secret测试用自签证书,生产用 cert-manager
rewriteannotationrewrite-target/api/xxx → /xxx,注意/$2写法
多域名同一 Ingress 写多条rules不同 host 走不同 Service
验证curl+kubectl logs看 Controller 日志路径不对先用ealen/echo-server照镜子

2.落地清单

  1. 装 Controller:推荐ingress-nginx,Helm 部署方便后续升级回滚
  2. 部署业务:确保 Pod + Service 就绪后再建 Ingress
  3. 写 Ingress 规则:绑定域名和路径,指定ingressClassName
  4. 配置 TLS:测试用openssl自签 →kubectl create secret tls→ Ingress 引用
  5. 验证生效:配好 hosts,curl测试 → 浏览器确认 → 查 Controller 日志
  6. 排坑优先级:404 → 查pathType;rewrite 不生效 → 查 annotation 前缀;TLS 不生效 → 查 Secret 是否同 namespace
http://www.cnnetsun.cn/news/2861473.html

相关文章:

  • 电商 CRM 怎么选?2026 电商 CRM 选型指南(6 大维度对比 + 避坑清单)
  • 《你好!数学·最亲切的数学概念启蒙图画书》PDF+音频
  • Tiktokenizer深度解析:开源大模型分词器可视化工具的技术演进与实践价值
  • Honey Select 2汉化补丁终极指南:5分钟解锁完整中文游戏体验
  • 计算机毕业设计之中学数学自动组卷系统的设计与实现
  • Python 与 C++:一对互补的“搭档”,而非你死我活的对手
  • 工程材料用量计算办法
  • GetQzonehistory:轻松备份你的QQ空间数字记忆,让青春永不褪色
  • 使用Thead子类创建线程VS使用Thead直接创建线程(Runnable)的区别
  • 从零接触到悟出Claude Code类Harness模式
  • 基金投资终极实战指南:从建仓到止亏的完整闭环
  • 制造业系统集成困局:乐高说明书(ESB)、万能插排(iPaaS)与聪明“手”(RPA)
  • 2026年Codex最全实操指南:如何用14个步骤掌握
  • 联想 ITIL 5 内训课程,不是一次“新版知识补课“
  • 【多模态大模型面经】Transformer专题面经
  • 【毕业设计】基于springboot+微信小程序的文化展示、旅游攻略、智能推荐文化旅游小程序系统(源码+文档+远程调试,全bao定制等)
  • 从高德 5 万年费,到拼 Key 翻车:一个中小团队的地图服务降本实录
  • 064、NPU的ResNet加速:残差块的硬件映射
  • 打工人必备记录神器:工作备忘、待办提醒一步到位
  • 极简日常记录工具:生活备忘、各类提醒全部安排妥当
  • Codex 提示 model not supported / model not found
  • 他一开口,我就知道他很懂AI Agent
  • 草地牛火了之后,它后来发生了什么?
  • C语言学习Day17
  • 深入解析LPC55S3x:从Flexcomm到EdgeLock,如何高效利用外设与安全子系统
  • 手把手教你解决MathWorks账户‘Technical Issue’报错(附地区切换避坑指南)
  • Databricks社区版升级付费版:AWS云环境部署与生产就绪指南
  • 从本地Win10到云端CentOS:我的第一个Spring Boot博客部署全记录(附WinSCP+域名绑定心得)
  • 用C++解决‘合影效果’排序题:从STL sort到冒泡排序的三种实战写法(附避坑点)
  • 从数独到拼图:我的日历拼图解题策略与启发式搜索心得