2-Ingress
1、ingress概述
- 通常情况下, Service和Pod仅可在集群内部网络中通过IP地址访问,Ingress是建立在Service之上的7层访问入口,它支持通过URL的方式将Service暴露到k8s集群外
- 通过配置,Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡、 终止 SSL/TLS,以及基于名称的虚拟托管等能力。 Ingress 控制器 负责完成 Ingress 的工作,具体实现上通常会使用某个负载均衡器, 不过也可以配置边缘路由器或其他前端来帮助处理流量。
- Ingress 不会随意公开端口或协议。 将 HTTP 和 HTTPS 以外的服务开放到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
- ingress需要和service在同一个命名空间

Ingress应用场景
- 作为集群的单一入口点,实现负载均衡和路由
- 假设有一个 Kubernetes 集群运行着多个微服务,包括前端 Web 应用、API 服务和后端数据库。通过创建一个 Ingress 资源,可以统一管理这些服务的外部访问,将所有流量路由到适当的后端服务。
- 对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器(Virtual Host),这些应用层的转发机制仅通过Kubernetes的Service机制是无法实现的。从Kubernetes 1.1版本开始新增Ingress资源对象,用于将不同URL的请求转发到后端不同的Service,以实现HTTP层的业务路由机制。
- 在实际生产中,一个网站的服务往往是由不同的Service提供服务的。而每个Service通常又采用LoadBalance的方式提供服务,这就需要为每个Service提供自己的负载均衡器,以及独有的公网IP。使用Ingress只需要一个公网IP就能为许多服务提供访问,当客户端向Ingress发送请求时,Ingress会根据请求的主机名和路径决定请求转发到的Service
Ingress 工作原理
- ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化,然后读取它,按照ingress中自定义的规则,规则写明了哪个域名对应哪个service,生成一段nginx配置,再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后reload一下使配置生效。以此达到域名分配置和动态更新的问题。
ingressclass
- ingressclass用于在集群内有多个ingress controller时候,区分ingress由谁处理
2、实现ingress
- 使用Ingress实现一个完整的七层负载均衡器,需要两步:
- 安装Ingress Controller。
- 定义一个Ingress资源对象,用来关联需要暴露出去的Pod的Service。
- 必须有一个Ingress Controller才能满足Ingress的要求。仅创建Ingress资源本身没有任何效果。
- ingress controller:使用ingress resources提供的规则将客户端请求转发。默认是nginx
- ingress resources:Ingress资源对象,用来关联需要暴露出去的Pod的Service
2.1、安装ingress controller
- 在定义Ingress策略之前,需要先部署Ingress Controller,以实现为所有后端Service都提供一个统一的入口。
- Ingress Controller需要实现基于不同HTTP URL向后转发请求,并可以灵活设置7层负载分发策略。
- 如果公有云服务商能够提供该类型的HTTP路由LoadBalancer,则也可设置其为Ingress Controller。 - 在Kubernetes中,Ingress Controller将以Pod的形式运行,监控API Server的/ingress接口后端的backend services,如果Service发生变化,则Ingress Controller应自动更新其转发规则。
- ingress controller就是一个或一组拥有七层代理能力或调度能力的应用程序的pod。
- 要安装的Ingress Controller是ingress-nginx-controller。
1、下载ingress-nginx-controller
官网:https://github.com/kubernetes/ingress-nginx
下载并解压 ingress-nginx-controller-v1.0.4.zip ,获取yaml文件
ingress-nginx-controller-v1.0.4\deploy\static\provider\baremetal\deploy.yaml
修改相应配置,省略
2、安装ingress-nginx-controller
kubectl apply -f ingress-nginx-controller-v1.0.4.yaml
kubectl get pods -o wide -A
kubectl get svc -o wide -A
3、访问ingress-nginx-controller
- 四个请求的返回值是一样的,都是404,因为还没有后端服务。
// 通过serviceIP访问
curl http://10.20.234.166:80
curl -k https://10.20.234.166:443
// 通过nodeIP访问
curl http://10.1.1.11:32080
curl -k https://10.1.1.11:32443
2.2、创建Ingress
- 创建一个单一规则的Ingress
cat <<EOF>> my-ingress.yaml
apiVersion: networking.k8s.io/v1 # 替换为稳定版 API
kind: Ingress
metadata:
name: my-ingress
# 可选:如果使用 NGINX Ingress Controller,可添加注解(根据需要调整)
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # 路径重写(根路径可省略)
spec:
rules:
- host: ingress.example.com # 映射的域名(需确保DNS解析到Ingress Controller的IP)
http:
paths:
- path: / # 匹配的请求路径
pathType: Prefix # 路径匹配类型(Prefix=前缀匹配,Exact=精确匹配)
backend:
service: # v1版本用service替代旧的backend结构
name: my-service # 目标Service名称
port:
number: 80 # 目标Service端口号
# 可选:如果需要默认后端(无匹配host时),可添加
# defaultBackend:
# service:
# name: default-service
# port:
# number: 80
EOF
kubectl apply -f my-ingress.yaml
- 通过http://ingress.example.com访问服务,需要确保域名解析为Ingress控制器的IP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
# 启用日志记录
nginx.ingress.kubernetes.io/enable-access-log: "true"
nginx.ingress.kubernetes.io/access-log-path: /var/log/nginx/access.log
# 配置CORS允许的来源
nginx.ingress.kubernetes.io/cors-allow-origin: "http://example.com"
# 配置自定义错误页面
nginx.ingress.kubernetes.io/custom-http-errors: "404,503"
nginx.ingress.kubernetes.io/custom-http-errors-404: /errors/404.html
nginx.ingress.kubernetes.io/custom-http-errors-503: /errors/503.html
spec:
# 定义Ingress规则
rules:
# 单一入口点
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# 路径和域名路由
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# 负载均衡
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 80
# 配置TLS/SSL终结
tls:
- hosts:
- example.com
secretName: tls-secret
# 配置自定义错误页面
- http:
paths:
- path: /oldpath
pathType: Prefix
backend:
service:
name: redirect-service
port:
number: 80
# 基于主机名的虚拟主机
- host: subdomain.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: subdomain-service
port:
number: 80
# 认证和授权
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: auth-service
port:
number: 80
4、Ingress规则
kubectl explain ingress.spec.rules
- 每个rules都包含以下字段
host字段
- host可以是精确匹配(例如 “foo.bar.com”)或者使用通配符来匹配 (例如 “*.foo.com”)。
- 精确匹配要求 HTTP host 头部字段与 host 字段值完全匹配。 通配符匹配则要求 HTTP host 头部字段与通配符规则中的后缀部分相同。
- 图片示例

- yaml示例
- ingress.spec.rules.host没有下级结构了,和http是平级
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
http字段
- 可以不指定host字段,这时相当于通过指定IP地址接收所有HTTP的请求。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
ingressClassName: nginx-example
rules:
- http: # 没有指定host,直接使用http
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
5、ingress路径
- ingress.rules.http.paths 结构下有以下几个字段:backend、path、pathType
5.1、backend
- backend有2种类型,resource和service
- resource和service不能同时指定
kubectl explain ingress.spec.rules.http.paths.backend
1、resource
- resouce的一个使用场景是Ingress 规则复用 / 分层管理
- 比如集群中有多个子服务,每个子服务都有自己的 Ingress 规则(如 service-a-ingress、service-b-ingress)。你想做一个「总入口 Ingress」,把不同路径的请求转发到对应的子 Ingress,而非直接转发到 Service,这样可以分层管理规则,避免单个 Ingress 配置过于复杂。
ingress规则复用示例
# 子 Ingress:api-ingress(负责/api路径转发到api-service)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: default
spec:
rules:
- http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port: { number: 80 }
---
# 总 Ingress:root-ingress(通过Resource后端转发到api-ingress)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: root-ingress
namespace: default
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
# Resource 后端(替代原来的 service 后端)
resource:
apiGroup: networking.k8s.io # Ingress 所属的 API 组
kind: Ingress # 目标资源类型是 Ingress
name: api-ingress # 目标资源名称(同命名空间的子 Ingress)
2、service
- 引用一个Service作为后端。与Resource互斥。有以下字段可以设置
- name:被引用的Service名称。该Service必须与Ingress对象在同一个名称空间中。
- port:被引用Service的端口号。
5.2、path
- ingress.spec.rules.http.paths.path
path:与请求的路径相匹配。路径必须以“/”开头。当未指定时,将匹配来自传入请求的所有路径。
5.3、pathType
- ingress.spec.rules.http.paths.pathType
- 支持的路径类型有三种:ImplementationSpecific、Exact和Prefix。
- 精确匹配的规则优先于前缀匹配
ImplementationSpecific
- 了解
Exact
- 精确匹配 URL 路径,且区分大小写
- 这个例子中,只会匹配/login路径,即使是/login/也不会匹配
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: exact-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /login
pathType: Exact # 仅匹配 /login
backend:
service:
name: login-service
port: { number: 80 }
Prefix
- 基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prefix-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix # 匹配 /api、/api/user、/api/order 等
backend:
service:
name: api-service
port: { number: 80 }
6、默认后端
- ingress.spec.defaultBackend
- 一个没有设置rules的Ingress会将所有的请求发送到defaultbackend定义的默认后端。
- defaultBackend通常是Ingress控制器的一个配置选项,不会在Ingress资源中指定。
- 如果没有指定.spec.rules,则必须指定.spec.defaultbackend。如果defaultBackend没有设置,不匹配任何规则的请求的处理将由入口控制器。
- 如果所有主机或路径都不匹配Ingress对象中的HTTP请求,流量将被路由到默认后端
7、ingress class
- IngressClass 是 Kubernetes 中用于定义 Ingress 控制器类型的资源对象。
- 它的核心作用是用于声明某个 Ingress 资源应该由哪个 Ingress Controller 处理。
- 在 Kubernetes 早期版本中,指定控制器方式是通过 annotation,这种方式在k8s1.28中仍然兼容,但是不推荐使用
metadata:
annotations:
kubernetes.io/ingress.class: nginx
- 但是这种方式存在问题:非结构化(annotation 不受 schema 管理),不利于多控制器场景,不符合 API 规范化设计。所以从 Kubernetes 1.18 开始引入IngressClass 资源 + ingress.spec.ingressClassName 字段正式替代 annotation。
- 一个集群可以同时运行 nginx、istio、 alb的ingress,每个都创建自己的 IngressClass,不同 Ingress 指向不同 class。
7.1、IngressClass 资源结构
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx # Ingress 中 spec.ingressClassName 必须引用这个 name
spec:
controller: k8s.io/ingress-nginx
parameters:
apiGroup: k8s.example.com
kind: IngressParameters
name: example
- spec.controller:格式通常为<domain>/<controller-name>
- 这个字段决定哪个控制器监听并处理该 IngressClass
- 例如:
- Nginx Ingress控制器:k8s.io/ingress-nginx
- Istio控制器:istio.io/ingress-controller
- spec.parameters:让 IngressClass 关联一个自定义 CRD,不同 ingressclass 可以使用不同配置模板,多租户隔离场景常用
7.2、IngressClass 与 Ingress 的关系
- 流程:Ingress → ingressClassName → IngressClass → controller → 对应控制器处理
- ingress的yaml文件中指定了ingressclassname,通过这个name可以找到对应的ingressclass,class中spec.controller指定了控制器的名称,由该控制器处理路由规则
- Ingress Controller 启动时,会监听特定 spec.controller 字段,只处理匹配该 controller 的 IngressClass,再处理关联的 Ingress 资源
7.3、默认 IngressClass
- 可以这样设置一个默认 class:
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
- 作用:当 Ingress 未指定 ingressClassName,自动使用默认 IngressClass
- 只能有一个默认 class,否则会冲突。
ingressclass 与 Istio 的关系
如果使用 Istio 的 ingresscontroller
- ingressclass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: istio
spec:
controller: istio.io/ingress-controller
- ingress
spec:
ingressClassName: istio # 与ingressclass的name一致
- 这样,流量会交给 Istio ingress gateway 处理。
- Istio 现在推荐使用Gateway API。而不是传统 Ingress。但 IngressClass 仍然支持。
- ingress使用IngressClass,路由对象是ingress。gateway api使用GatewayClass,路由对象是HTTPRoute。后者在扩展能力和多租户支持方面更强
故障排查
常用排查命令
# 查看所有 class
kubectl get ingressclass
# 查看详情
kubectl describe ingressclass nginx
# 查看 Ingress 是否绑定
kubectl get ingress -o wide
Ingress 不生效的可能原因
- gress没有指定ingressClassName
- 不存在指定的IngressClass
- ingressclass的spec.controller没有匹配控制器
- 指定了多个默认 class
- 同时指定了annotation 与 ingressClassName 冲突

浙公网安备 33010602011771号