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

第30篇 k8s之Ingress 基础:域名路由与 Ingress Controller

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


在前两篇中,我们用 Service 解决了 Pod 的服务发现问题——ClusterIP 提供内部稳定入口,NodePort 和 LoadBalancer 暴露外部访问。但在实际生产环境中,你通常不会为每一个微服务都申请一个独立的云负载均衡器,费用高昂且难以统一管理。更常见的做法是:用一个统一的入口,根据域名URL 路径将流量分发到不同的后端服务。

举个例子:api.example.com路由到 Flask 服务,www.example.com路由到前端静态页面服务,admin.example.com路由到后台管理系统。这种基于 HTTP/HTTPS 的七层路由能力,正是Ingress提供的核心功能。这一篇,我们就来拆解 Ingress 的架构,并在 Minikube 环境中实战配置贯穿案例的域名路由。

一、为什么 Service 不够用?

回顾第 28 篇,我们用 NodePort 类型的 Service 暴露了 Flask 应用,访问方式是http://<节点IP>:30080。这在以下几个场景下会显得力不从心:

场景一:多服务共享同一端口。你有 3 个 Web 服务(前端、API、管理后台),都监听 80 端口。用 NodePort 的话,需要分别映射到 30080、30081、30082——不仅端口号不直观,而且每新增一个服务就要占用一个节点端口。

场景二:基于域名的路由。你希望api.example.comwww.example.com访问不同的后端服务,但共享同一个入口 IP 和端口。Service 工作在四层(TCP/UDP),无法读取 HTTP 请求头中的 Host 信息,因此无法基于域名做路由决策。

场景三:TLS 终端。你希望统一管理 HTTPS 证书,在入口处完成 TLS 握手和证书卸载,而不是在每个 Pod 里各自配置 HTTPS。

Ingress 正是为解决这些问题而设计的——它工作在七层(HTTP/HTTPS),通过解析请求中的 Host 和 Path 信息,将流量智能路由到不同的 Service,同时统一管理 TLS 证书。

二、Ingress 与 Ingress Controller 的关系

很多初学者容易混淆 Ingress 和 Ingress Controller,把它们当成一回事。实际上,它们是两个完全不同的概念,遵循 K8s 经典的“API 对象 + 控制器”分离设计:

简单来说:Ingress 是“你想要什么路由规则”,Ingress Controller 是“谁来执行这些规则”。这和 Deployment(你声明期望状态)与 Deployment Controller(控制器持续调和实际状态)的关系完全一致。

K8s 社区有多种 Ingress Controller 实现,选择哪一个取决于你的场景需求:

本系列以 NGINX Ingress Controller 为标准,因为它最贴近 K8s 原生生态,文档最丰富,也是生产环境中最常见的选择。

三、实战:在 Minikube 中部署 NGINX Ingress Controller

3.1 启用 Minikube Ingress 插件

Minikube 内置了 NGINX Ingress Controller,一条命令即可启用:

minikube addonsenableingress

输出:

🌟 The'ingress'addon is enabled

验证 Ingress Controller Pod 是否运行:

kubectl get pods-ningress-nginx

输出:

NAME READY STATUS RESTARTS AGE ingress-nginx-controller-7c8b6f9d5f-abcde1/1 Running030s

这个 Pod 运行在ingress-nginx命名空间中。它是一个标准的 Nginx 反向代理实例,由 K8s 自动部署和管理。当你在集群中创建或修改 Ingress 资源时,Ingress Controller 会监听这些变化,自动更新 Nginx 配置文件并执行热重载。

3.2 部署示例应用:Flask 计数器

为贯穿案例创建 Deployment 和 Service。这一次,我们只需要 ClusterIP 类型的 Service 暴露 5000 端口,外部访问完全交给 Ingress 处理:

apiVersion: apps/v1 kind: Deployment metadata: name: flask-app spec: replicas:2selector: matchLabels: app: flask-counter template: metadata: labels: app: flask-counter spec: containers: - name: flask image: flask-redis-counter:2.0 ports: - containerPort:5000env: - name: REDIS_HOST value: redis-service readinessProbe: httpGet: path: /health port:5000periodSeconds:5failureThreshold:2--- apiVersion: v1 kind: Service metadata: name: flask-service spec: type: ClusterIP selector: app: flask-counter ports: - port:5000targetPort:5000
kubectl apply-fflask-deployment.yaml kubectl get svc flask-service# NAME TYPE CLUSTER-IP PORT(S) AGE# flask-service ClusterIP 10.96.200.80 5000/TCP 10s

flask-service只是一个 ClusterIP Service,没有 NodePort、没有 LoadBalancer,外部无法直接访问。这很好——我们不需要让 Service 操心外部暴露,Ingress 会负责这一层。

3.3 创建 Ingress 资源:基于路径的路由

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: flask-ingress spec: ingressClassName: nginx rules: - http: paths: - path: /counter pathType: Prefix backend: service: name: flask-service port: number:5000

关键字段解读:

  • ingressClassName: nginx:指定使用 NGINX Ingress Controller 来处理这个 Ingress。一个集群可以有多个 Ingress Controller,此字段确保规则被正确的控制器处理。

  • path: /counter:URL 路径前缀,匹配/counter/counter//counter/anything

  • pathType: Prefix:前缀匹配模式。Prefix表示以/counter开头的路径都会被路由到该 Service。另一种模式是Exact,精确匹配整个路径。

  • backend.service.name: flask-service:流量转发的目标 Service 名称。Ingress Controller 会查询该 Service 的 Endpoints,将请求转发到后端的 Pod IP。

kubectl apply-fflask-ingress.yaml kubectl get ingress

输出:

NAME CLASS HOSTS ADDRESS PORTS AGE flask-ingress nginx *192.168.49.28030s

ADDRESS是 Ingress 的入口 IP(Minikube 节点的 IP)。HOSTS=*表示当前没有配置域名规则,所有域名的/counter请求都会被路由到flask-service

3.4 验证路由

curlhttp://192.168.49.2/counter

输出:

Hello World!I have been seen1times.

如果你访问根路径/,会得到 Nginx 的 404 页面——因为 Ingress 中只定义了/counter的路由规则,其他路径没有匹配的后端 Service。

小贴士:Minikube 的 Ingress 可能会有一两分钟的初始化延迟,如果 curl 返回Could not resolve host,稍等片刻再试。如果持续不通,执行minikube addons list | grep ingress确认插件确实已启用,然后kubectl get pods -n ingress-nginx确认 Controller Pod 处于 Running 状态。

四、实战:基于域名的路由

单路径路由是 Ingress 最基础的用法。更常见的场景是基于域名将请求分发到不同的后端服务。假设我们有三个服务:

  • counter.example.com→ Flask 计数器应用

  • api.example.com→ Flask API 应用(同一个镜像,不同的 Service)

  • admin.example.com→ 后台管理应用(暂时用 Nginx 占位)

4.1 创建多个后端服务

# 为演示创建第二个 Service,指向同一个 Deployment(实际中会是不同的应用)kubectl expose deployment flask-app--name=api-service--port=5000--target-port=5000# 创建第三个 Service(后台管理占位)kubectl create deployment admin--image=nginx:alpine kubectl expose deployment admin--name=admin-service--port=80

4.2 创建多域名 Ingress

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-domain-ingress spec: ingressClassName: nginx rules: - host: counter.example.com http: paths: - path: / pathType: Prefix backend: service: name: flask-service port: number:5000- host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number:5000- host: admin.example.com http: paths: - path: / pathType: Prefix backend: service: name: admin-service port: number:80
kubectl apply-fmulti-domain-ingress.yaml

4.3 在本地模拟域名访问

由于example.com是占位域名,我们需要在本地将域名解析到 Minikube 的 IP。使用 curl 的-H参数手动指定 Host 头:

# 获取 Minikube IPMINIKUBE_IP=$(minikubeip)# 访问不同域名curl-H"Host: counter.example.com"http://$MINIKUBE_IP# Hello World! I have been seen 2 times.curl-H"Host: api.example.com"http://$MINIKUBE_IP/health# {"status":"ok"}curl-H"Host: admin.example.com"http://$MINIKUBE_IP# <!DOCTYPE html>...(Nginx 默认欢迎页)

同一个 IP 地址、同一个端口(80),仅凭 HTTP 请求头中的Host字段不同,就被路由到了三个完全不同的后端服务——这就是 Ingress 七层路由的核心能力。

关于域名和本机测试example.com是 IANA 保留的示例域名,永远不会被注册。如果你希望在浏览器中测试,可以编辑/etc/hosts,添加192.168.49.2 counter.example.com api.example.com(将192.168.49.2替换为minikube ip的输出)。但请注意,浏览器会缓存 DNS 解析结果,修改 hosts 后可能需要重启浏览器或清除 DNS 缓存才能生效。对于本地快速验证,curl 的-H "Host:"参数是最干净的方式。

五、Ingress 与 Service 的对比

Ingress 并没有取代 Service,而是建立在 Service 之上。Ingress 的backend字段指向的是 Service 名称,Service 仍然负责将流量负载均衡到具体的 Pod。Ingress 做的只是“根据 Host 和 Path,选择正确的 Service”。

六、命令速查表

七、本篇总结

  • Ingress 的定位:七层 HTTP/HTTPS 路由,根据 Host 和 Path 将外部流量分发到不同的 Service,弥补了 Service 在域名路由、TLS 终端、多服务共享端口方面的不足。

  • Ingress 与 Ingress Controller 的关系:Ingress 是定义路由规则的 API 对象,Ingress Controller 是实际执行转发的代理程序(如 NGINX、Traefik)。二者必须配套使用。

  • 实战成果:在 Minikube 中部署了 NGINX Ingress Controller,通过基于路径和基于域名的两种方式将流量路由到贯穿案例的 Flask 应用。

  • Ingress 是建立在 Service 之上的,它选择正确的 Service,Service 负责将请求分发到 Pod。两者分工明确,不可相互替代。

通过本篇,你的 Flask 应用已经可以通过域名和路径被外部访问了。但到目前为止,流量都是明文 HTTP——生产环境必须用 HTTPS。下一篇——第 31 篇:Ingress 进阶:TLS、重写与认证,我们将为 Ingress 配置 TLS 证书、实现路径重写和基本认证,让外部访问真正达到生产级安全标准。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

http://www.cnnetsun.cn/news/2702957.html

相关文章:

  • 告别AXI协议恐惧:手把手解析米联客FDMA IP源码,在安路FPGA上轻松玩转DDR读写
  • Sora 2已悄然支持16秒连贯叙事视频生成(官方未宣布),我们逆向提取了其分镜一致性约束算法——附Python验证脚本
  • 告别Arduino!将PAJ7620手势识别库移植到STM32 CubeIDE的保姆级教程
  • DeepSeek LeetCode 2911. 得到 K 个半回文串的最少修改次数 JavaScript实现
  • Bash 专业人员笔记 -- 第 28 章:进程替换
  • DRC设计规则检查
  • 手把手教你:如何将HAL库项目从STM32F103RCT6无缝迁移到C8T6(附源码下载)
  • 第130期《Installer》推荐:多款新品、屏幕分享、读者好物及Spotify实用功能!
  • 中文文本分类完整训练工程:PyTorch+BERT实现CPWS与CNews数据集端到端跑通
  • UE5 GAS实战:手把手教你为RPG角色创建第一个AttributeSet(含Health/Mana完整代码)
  • GSEA分析避坑指南:从NES、FDR到leading edge,这些参数设置错了结果全白费
  • Paza项目:低资源语言语音识别的社区驱动范式与实战指南
  • Sora 2字幕添加实操手册:5种兼容格式+4类常见报错修复+1键同步时间轴(附官方API调用验证数据)
  • Unity新手必看:用Animation和Trigger做个能捡钥匙开的门(附完整代码)
  • 雷达信号处理入门:LFM调频连续波如何实现‘看得更清’?
  • Contextual Bandit:从理论到实践,构建深度个性化推荐系统
  • C#后台导入Excel别再写复杂解析了!MiniExcel一行代码映射到实体类(含表头不对齐的解决方案)
  • 保姆级教程:用PX4和ROS在Gazebo仿真中实现无人机自动画圆(附完整代码与脚本)
  • 从高频交易到Kaggle Grandmaster:跨领域思维如何塑造顶尖数据科学家
  • MATLAB行人检测实战包:HOG特征提取+滑动窗口+SVM分类全流程代码
  • 企业级网络运维接入LLM大模型(在线)实战
  • API即服务:微创业者的技术新基建与实战指南
  • FortiGate新老版本分流方案对比:手动建IP组 vs 一键调用地理数据库,哪个更适合你?
  • Visual Studio 科研工作流:集成 Jupyter、Git LFS 与 MLflow 实现高效研究
  • OpenAI 5个月生成百万行代码!揭秘AI工程师的进化之路:Prompt、Context、Harness工程
  • 微软EMEA奖学金计划:AI产学研协作模式解析与盲童社交技能辅助案例
  • ECharts 5.4.3版本避坑:手把手教你实现‘悬浮’引导线的3D环状饼图
  • 避坑指南:mmsegmentation自定义数据集时,90%新手会遇到的3个报错及解决方法
  • 你的第一个双轮差速小车底盘:Arduino Mega2560核心,TB6612驱动MG513电机全攻略(附完整代码库)
  • 企业安全产品失效真相:仪表盘谎言与责任鸿沟的深度剖析