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

K8s学习笔记(二十四) ingress

1 为什么需要 Ingress?

K8s 中服务(Service)的默认暴露方式有局限性,Ingress 正是为解决这些问题而生:

服务暴露方式缺点Ingress 的优势
NodePort每个 Service 占用一个 Node 端口,端口多了难管理;只能用 “IP + 端口” 访问,无域名1 个入口管理所有服务,支持 “域名 + 路径” 转发;无需暴露大量端口
LoadBalancer每个 Service 需要一个云厂商负载均衡器,成本高;无法共享共享 1 个 LoadBalancerr(或 NodePort),低成本;统一配置 SSL / 限流

简单说:Ingress 让你能用 http://app1.example.com 访问服务 A,http://app2.example.com 访问服务 B,或 http://example.com/app1 访问服务 A、http://example.com/app2 访问服务 B,实现 “一入口多服务” 的管理。

2 Ingress 的核心组成:2 个关键部分

Ingress 不是一个单一组件,而是 “规则定义 + 控制器实现” 的组合,二者缺一不可:

2.1 Ingress 资源(规则定义)

是 K8s 的 API 对象,用 YAML 定义 “外部流量如何转发到内部 Service” 的规则,比如:

  • 哪个域名对应哪个服务?
  • 哪个路径对应哪个服务?
  • 是否需要 SSL 证书?

它本身不干活,只负责 “写规则”。

2.2 Ingress Controller(规则执行)

是实际 “干活” 的组件(通常是一个 Pod),它会:

  1. 监听 K8s API 中 Ingress 资源的变化;
  2. 根据 Ingress 规则生成反向代理配置(比如 Nginx 配置);
  3. 接收外部流量,按照配置转发到对应的 Service。

主流 Ingress Controller:Nginx Ingress Controller(最常用,基于 Nginx)、Traefik、HAProxy Ingress 等,本文以 “Nginx Ingress Controller” 为例。

3 Ingress 的核心概念与基础配置

先从一个最简单的 Ingress 示例入手,理解核心字段:

3.1 基础示例:用路径转发流量

假设集群内有两个服务:

  • service-foo:提供 /foo 路径的服务,端口 80;
  • service-bar:提供 /bar 路径的服务,端口 80;

我们要实现:外部访问 http://myapp.com/foo 转发到service-foohttp://myapp.com/bar 转发到service-bar

步骤 1:部署 Ingress Controller(前提)

首先要部署 Nginx Ingress Controller,这是所有 Ingress 规则生效的基础:

# 部署官方Nginx Ingress Controller(适用于K8s 1.19+)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

验证部署(查看ingress-nginx命名空间下的 Pod,Running表示正常):

kubectl get pods -n ingress-nginx 

查看 Ingress Controller 的暴露方式(默认用 NodePort,会分配两个端口:HTTP (80)、HTTPS (443)):

kubectl get svc -n ingress-nginx ingress-nginx-controller

输出类似(PORT(S)列的32000:80/TCP表示 NodePort 为 32000,外部可通过 “NodeIP:32000” 访问):

NAME                                 TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort   10.96.xxx.xxx   <none>        80:32000/TCP,443:32100/TCP   10m

如果部署NodePort而是LoadBalancer,需要修改yaml文件

kubectl edit svc ingress-nginx-controller -n ingress-nginx
# 将LoadBalancer修改成NodePort
步骤 2:创建 Ingress 资源(规则)

创建ingress-demo.yaml文件,定义转发规则:

apiVersion: networking.k8s.io/v1  # 固定版本(K8s 1.19+推荐)
kind: Ingress
metadata:name: ingress-demo  # Ingress名称annotations:# 声明使用Nginx Ingress Controller(不同控制器注解不同)kubernetes.io/ingress.class: "nginx"
spec:rules:  # 核心规则列表(可配置多个域名)- host: myapp.com  # 外部访问的域名(需配置DNS或本地hosts解析到NodeIP)http:paths:  # 该域名下的路径转发规则- path: /foo  # 匹配路径:/foopathType: Prefix  # 路径匹配类型:Prefix(前缀匹配,如/foo/1也会匹配)backend:service:name: service-foo  # 转发到的Service名称port:number: 80  # Service的端口- path: /barpathType: Prefixbackend:service:name: service-barport:number: 80

应用 Ingress 规则:

kubectl apply -f ingress-demo.yaml

查看 Ingress 状态(ADDRESS列会显示 Ingress Controller 的访问地址,即 NodeIP):

kubectl get ingress ingress-demo
步骤 3:测试访问
  1. 配置域名解析:在本地电脑的hosts文件(Windows:C:\Windows\System32\drivers\etc\hosts;Linux/macOS:/etc/hosts)中添加一行:

    192.168.1.100  myapp.com  # 192.168.1.100是K8s Node的IP
    
  2. 访问测试:

    • 访问 http://myapp.com:32000/foo → 流量转发到service-foo
    • 访问 http://myapp.com:32000/bar → 流量转发到service-bar

3.2 核心字段解析

字段作用关键说明
metadata.annotations配置 Ingress Controller 的附加参数kubernetes.io/ingress.class: "nginx"指定用 Nginx 控制器;还可配置 SSL、限流等
spec.rules.host外部访问的域名若不填,规则对 “所有域名” 生效(不推荐);支持通配符,如*.example.com
spec.rules.http.paths.pathType路径匹配类型3 种:- Prefix:前缀匹配(如/foo匹配/foo/foo/1)- Exact:精确匹配(如/foo只匹配/foo)- ImplementationSpecific:由控制器决定(不常用)
spec.rules.http.paths.backend流量转发的目标 Service必须指定service.name(Service 名称)和service.port.number(Service 端口)

3.3 完整案例:用 Ingress 路由到两个服务

目标

部署两个应用(Nginx 和 Httpd),通过 Ingress 实现:

  • 访问 example.com/nginx 路由到 Nginx 服务。
  • 访问 example.com/httpd 路由到 Httpd 服务。
环境准备
  • 一个可用的 k8s 集群(推荐用 minikube 本地测试,简单易操作)。
  • kubectl 命令行工具已配置。
步骤 1:部署 Ingress Controller(以 Nginx 为例)

如果用 minikube,可直接启用内置的 Nginx Ingress Controller:

minikube addons enable ingress

验证部署是否成功(等待所有 Pod 处于 Running 状态):

kubectl get pods -n ingress-nginx

输出类似(名称可能略有不同):

NAME                                       READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-xxxxxxxxx-xxxxx   1/1     Running   0          5m
步骤 2:部署测试应用(Nginx 和 Httpd)

创建两个 Deployment,分别运行 Nginx 和 Httpd 容器。

新建 apps.yaml 文件:

# Nginx 应用
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:alpineports:- containerPort: 80---
# Httpd 应用
apiVersion: apps/v1
kind: Deployment
metadata:name: httpd-app
spec:replicas: 2selector:matchLabels:app: httpdtemplate:metadata:labels:app: httpdspec:containers:- name: httpdimage: httpd:alpineports:- containerPort: 80

部署应用:

kubectl apply -f apps.yaml

验证部署:

kubectl get deployments

输出:

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx-app    2/2     2            2           1m
httpd-app    2/2     2            2           1m
步骤 3:创建 Service(连接 Ingress 和应用)

Ingress 需要通过 Service 访问后端应用,这里创建两个 ClusterIP 类型的 Service(仅集群内部可访问,由 Ingress 转发流量)。

新建 services.yaml 文件:

# Nginx 服务
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:app: nginx  # 匹配 Nginx Deployment 的 labelports:- port: 80    # Service 暴露的端口targetPort: 80  # 容器内的端口(与 Deployment 中一致)---
# Httpd 服务
apiVersion: v1
kind: Service
metadata:name: httpd-service
spec:selector:app: httpd  # 匹配 Httpd Deployment 的 labelports:- port: 80targetPort: 80

部署 Service:

kubectl apply -f services.yaml

验证 Service:

kubectl get services

输出:

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   10.100.xxx.xxx   <none>        80/TCP    1m
httpd-service   ClusterIP   10.100.xxx.xxx   <none>        80/TCP    1m
步骤 4:创建 Ingress 规则

定义 Ingress 资源,配置路由规则:将 example.com/nginx 路由到 nginx-serviceexample.com/httpd 路由到 httpd-service

新建 ingress.yaml 文件:

# apiVersion:指定 Kubernetes API 版本,networking.k8s.io/v1 是当前 Ingress 资源的稳定版本
apiVersion: networking.k8s.io/v1
# kind:声明资源类型为 Ingress,用于管理外部访问集群内服务的路由规则
kind: Ingress
metadata:# name:Ingress 资源的名称,用于唯一标识该资源(在同一命名空间内)name: app-ingress# annotations:附加配置信息,用于向 Ingress 控制器传递额外参数(此处为 Nginx 控制器专用配置)annotations:# nginx.ingress.kubernetes.io/rewrite-target:路径重写规则# 作用:当请求路径匹配下方的 path 规则时,将路径重写为 /$2($2 对应 path 中第二个捕获组 (.*) 的内容)# 举例:访问 /nginx/test 时,重写后路径为 /test,避免后端服务(如 Nginx)因前缀 /nginx 不存在而返回 404nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:# ingressClassName:指定使用的 Ingress 控制器类型# 必须与集群中部署的 Ingress 控制器的 class 名称一致(此处为 nginx,即 Nginx Ingress Controller)# 若不指定,Ingress 可能无法被正确处理(取决于集群默认配置)ingressClassName: nginx# rules:路由规则列表,定义不同主机/路径的请求如何转发rules:- host: example.com  # 仅对访问 example.com 域名的请求生效# 注意:需在本地 hosts 文件或 DNS 中配置该域名指向 Ingress 控制器的 IP 才能测试http:  # 定义 HTTP 协议的路由规则(HTTPS 需额外配置 tls 字段)paths:  # 路径匹配规则列表(按顺序匹配,优先匹配靠前的规则)- path: /nginx(/|$)(.*)  # 路径匹配表达式# 解析:# - /nginx:匹配以 /nginx 开头的路径# - (/|$):匹配紧跟的 / 或路径结束(避免误匹配 /nginxxyz 等无关路径)# - (.*):捕获后续所有字符(作为第二个分组,对应 rewrite-target 中的 $2)# 最终匹配范围:/nginx、/nginx/、/nginx/test、/nginx/a/b 等pathType: ImplementationSpecific  # 由 Nginx 控制器处理正则匹配# 结合上述 path 表达式后,实际为精确的前缀匹配(避免默认 Prefix 可能的模糊匹配)backend:  # 匹配该路径时的后端服务配置service:name: nginx-service  # 转发到名为 nginx-service 的 Serviceport:number: 80  # 转发到该 Service 的 80 端口- path: /httpd(/|$)(.*)  # 与上述 /nginx 规则逻辑一致,匹配以 /httpd 开头的路径# 匹配范围:/httpd、/httpd/、/httpd/docs 等pathType: ImplementationSpecific  # 由 Nginx 控制器处理正则匹配backend:  # 匹配该路径时的后端服务配置service:name: httpd-service  # 转发到名为 httpd-service 的 Serviceport:number: 80  # 转发到该 Service 的 80 端口

关键说明

  • annotations 中的 rewrite-target:当访问 example.com/nginx/test 时,会重写为 nginx-service:80/test(否则后端服务会收到 /nginx/test 路径,可能返回 404)。
  • ImplementationSpecific 是 Nginx Ingress 处理正则路径的标准配置,它会让 Nginx 控制器解析 path 中的正则表达式(如 (/|$)(.*)),实现需要的精确前缀匹配和路径捕获。
  • host: example.com:仅匹配该域名的请求(如果不指定 host,会匹配所有域名)。

部署 Ingress:

kubectl apply -f ingress.yaml

验证 Ingress:

kubectl get ingress

输出(ADDRESS 是 Ingress Controller 的 IP,后续访问用这个 IP):

NAME          CLASS   HOSTS         ADDRESS        PORTS   AGE
app-ingress   nginx   example.com   192.168.49.2   80      1m
步骤 5:测试访问

需要让本地机器识别 example.com 并指向 Ingress Controller 的 IP(即上面的 ADDRESS)。

配置本地 hosts
  • Linux:编辑/etc/hosts,添加一行:

    192.168.49.2  example.com  # 替换为你的 Ingress ADDRESS
    
  • Windows:编辑 C:\Windows\System32\drivers\etc\hosts(需管理员权限),添加同上内容。

验证路由

curl 或浏览器访问:

  1. 访问 example.com/nginx

    curl example.com/nginx
    

    输出 Nginx 的默认页面(说明路由到 Nginx 服务):

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...
    
  2. 访问 example.com/httpd

    curl example.com/httpd
    

    输出 Httpd 的默认页面(说明路由到 Httpd 服务):

    <html><body><h1>It works!</h1></body></html>
    

3.4 常见问题与扩展

1. Ingress 状态一直为 Pending?
  • 原因:未部署 Ingress Controller,或控制器未正常运行。
  • 解决:检查 kubectl get pods -n ingress-nginx,确保控制器 Pod 正常运行。
2. 访问返回 404?
  • 检查 Ingress 规则的 pathservice.name 是否正确(标签匹配是否错误)。
  • 若路径包含前缀(如 /nginx),需配置 rewrite-target 注解(否则后端服务可能无对应路径)。
3. 扩展:配置 HTTPS

如需启用 HTTPS,需创建 TLS 证书(可通过 cert-manager 自动生成),并在 Ingress 中添加 tls 配置:

spec:tls:- hosts:- example.comsecretName: example-tls  # 存储证书的 Secret 名称# 其他规则不变...

通过这个案例,你应该已经掌握了 Ingress 的核心用法:部署控制器、定义路由规则、关联服务与应用。实际生产中,可根据需求扩展更复杂的路由策略(如权重分配、跨命名空间路由等)。

4 Ingress 高级功能

4.1 SSL 证书配置(HTTPS 访问)

Ingress 支持 “TLS 终止”(在 Ingress Controller 层处理 SSL,内部服务用 HTTP),只需两步:

步骤 1:创建存储证书的 Secret

将 SSL 证书(tls.crt公钥、tls.key私钥)保存为 Secret(需与 Ingress 在同一命名空间):

kubectl create secret tls myapp-tls \--cert=./tls.crt \  # 你的证书文件路径--key=./tls.key    # 你的私钥文件路径
步骤 2:在 Ingress 中引用 TLS Secret

修改ingress-demo.yaml,添加spec.tls字段:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-demoannotations:kubernetes.io/ingress.class: "nginx"
spec:tls:  # TLS配置- hosts:- myapp.com  # 要启用HTTPS的域名(需与证书匹配)secretName: myapp-tls  # 引用前面创建的Secretrules:  # 规则不变,同上- host: myapp.comhttp:paths:- path: /foopathType: Prefixbackend:service:name: service-fooport:number: 80- path: /barpathType: Prefixbackend:service:name: service-barport:number: 80

应用后,访问 https://myapp.com:32100/foo(32100 是 Ingress Controller 的 HTTPS NodePort),即可通过 HTTPS 访问。

4.2 域名重定向(HTTP→HTTPS)

通过注解配置,强制将 HTTP 流量重定向到 HTTPS:

metadata:annotations:kubernetes.io/ingress.class: "nginx"# 开启HTTP→HTTPS重定向nginx.ingress.kubernetes.io/ssl-redirect: "true"

4.3 路径重写(URL Rewrite)

场景:外部访问 http://myapp.com/app1,但内部 Service 实际提供的路径是 /(如服务只认根路径),需用路径重写。

通过注解配置重写规则:

metadata:annotations:kubernetes.io/ingress.class: "nginx"# 重写规则:将 /app1/(.*) 重写为 /$1nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:rules:- host: myapp.comhttp:paths:- path: /app1/(.*)  # 用正则匹配路径,括号捕获后面的内容pathType: Prefixbackend:service:name: service-app1  # 该服务的根路径是 /port:number: 80

效果:访问 http://myapp.com/app1/login → 重写为 http://service-app1/login

5 Ingress vs 传统服务暴露:核心对比

维度Ingress(Nginx Controller)NodePortLoadBalancer
访问方式域名 + 路径(友好)IP + 端口(难记)IP / 域名(友好)
端口管理只暴露 1-2 个端口(80/443)每个服务 1 个端口(混乱)每个服务 1 个负载均衡器(成本高)
SSL 支持统一配置(方便)需服务自身实现(麻烦)需云厂商配置(分散)
高级功能路径重写、限流、缓存部分支持(依赖云厂商)
适用场景生产环境(多服务、需域名)测试环境(快速暴露)生产环境(单服务、高可用)

6 常见问题与排查

6.1 Ingress 规则不生效?

  • 检查 Ingress Controller 是否正常运行:kubectl get pods -n ingress-nginx
  • 检查 Ingress 是否关联到 Controller:kubectl describe ingress <ingress-name>,查看Events是否有 “Successfully configured”;
  • 检查 Service 是否正常:kubectl get svc <service-name>,确保 Service 能正常访问(可在集群内用 Pod 测试)。

6.2 域名访问不通?

  • 检查本地hosts或 DNS 是否正确解析到 NodeIP;
  • 检查 Node 的防火墙是否开放 Ingress Controller 的 NodePort(如 32000、32100)。

6.3 HTTPS 证书无效?

  • 检查 Secret 是否正确:kubectl describe secret <tls-secret-name>,确保证书和私钥匹配;
  • 检查 Ingress 的spec.tls.hosts是否与证书的 “主题备用名称(SAN)” 一致。

总结

Ingress 的核心是 “统一入口 + 规则转发”,学习时要抓住两个重点:

  1. 理解 “Ingress 资源(规则)” 和 “Ingress Controller(执行)” 的关系;
  2. 掌握基础的 “域名 + 路径转发” 和生产级的 “SSL 配置、路径重写”。
http://www.dtcms.com/a/540619.html

相关文章:

  • 将axios、async、Promise联系在一起讲一下讲一下.then 与其关系
  • 最权威的排行榜网站scratch网站开发
  • WPF 数据绑定详解
  • 【Swift】LeetCode 54. 螺旋矩阵
  • 河北邯郸seo网站建设网站优化专业网站的定义
  • Python测试题2
  • WordPress 上传图片报错:明明是 PNG,却提示「请转换为 JPEG 或 PNG 格式」?
  • annotation-logging-guide
  • 没有公司做网站重庆网站推广入口
  • 管理k8s的资源类型(PV/PVC)的脚本
  • 【记录】飞书多维表格|做自动显示当前填写情况(包括填写人数、未填写情况、最高分和平均分)的收集表
  • 清除入侵痕迹(winLinuxweb)
  • 找设计师的网站淘宝客 网站建设
  • 第六部分:VTK进阶(第175章 并行 IO管线与检查点)
  • 河南海绵城市建设网站wordpress中文版书籍
  • Opencv(三): 二值化
  • GitHub使用技巧——上传本地项目
  • 网站建设用途一个旅游网站建设需求分析
  • 甜品网站网页设计代码网上免费推广
  • 渗透测试工具 windows上搭建vmware kali-linux
  • ecstore等产品开启缓存-后台及前台不能登录原因-setcookie+session问题
  • 哨兵原理、Redis分片、Redis数据结构、内存回收、缓存问题以及分布式事务相关内容(CAP、BASE、AT脏写及其解决、TCC、最大努力通知)
  • Windows图标修复--缓存重建教程
  • 服务器上用Slurm 管理训练bash 脚本任务,申明使用GPU
  • 上海小程序网站开发公司wordpress国外主题下载地址
  • 新城镇建设官方网站kali建设网站
  • 便携式el检测仪:确保光伏组件的质量与性能稳定
  • 英一2015年真题学习笔记
  • Docker 部署银河麒麟(Kylin Linux)全流程教程
  • GPT、DeepSeek等大语言模型应用