Kubernetes Ingress:实现HTTPHTTPS流量管理
Kubernetes Ingress:实现HTTP/HTTPS流量管理
文章目录
- Kubernetes Ingress:实现HTTP/HTTPS流量管理
- 什么是Ingress?
- 与Service的区别
- 核心依赖:Ingress控制器
- Ingress资源的核心组成
- 1. metadata:元数据
- 2. spec:核心配置
- (1)ingressClassName:关联IngressClass
- (2)rules:流量路由规则
- (3)pathType:路径匹配类型
- (4)backend:后端服务
- (5)defaultBackend:默认后端
- (6)tls:HTTPS配置
- IngressClass:绑定控制器的桥梁
- IngressClass的定义示例
- 关键配置说明
- 默认IngressClass
- 常见Ingress配置场景
- 1. 单一服务暴露
- 2. 简单扇出(Fanout)
- 3. 基于名称的虚拟主机
- 4. HTTPS配置
- 部署与管理Ingress
- 1. 部署Ingress控制器
- 2. 创建Ingress资源
- 3. 更新Ingress规则
- 4. 查看Ingress详情
- 注意事项与最佳实践
- 总结
- 总结
在Kubernetes集群中,如何高效管理外部对内部服务的HTTP/HTTPS访问?Ingress作为Kubernetes的核心API对象,提供了基于URI、主机名等Web概念的流量路由能力,是实现外部访问治理的关键组件。本文将深入解析Ingress的核心概念、配置方式及最佳实践,帮助你全面掌握这一重要功能。
什么是Ingress?
Ingress是Kubernetes中用于管理集群外部对内部服务的HTTP/HTTPS访问的API对象。它通过定义规则(Rules)控制流量路由,支持负载均衡、SSL终止、基于名称的虚拟主机等功能,是连接集群内外HTTP/HTTPS流量的"网关"。
核心特性:
- 基于HTTP/HTTPS协议的流量路由
- 支持按主机名(Host)或路径(Path)匹配请求
- 可配置SSL/TLS加密(终止HTTPS连接)
- 依赖Ingress控制器实现(仅定义Ingress资源无实际效果)
与Service的区别
Ingress与Service(如NodePort、LoadBalancer)都能暴露服务,但定位不同:
- Service:主要解决集群内部服务发现和访问,可暴露任意端口和协议(如TCP/UDP),但缺乏HTTP层的精细化路由能力。
- Ingress:专注于HTTP/HTTPS流量,支持基于路径、主机名的复杂路由,本质是对Service的"二次封装",通过Ingress控制器将外部流量转发到后端Service。
简言之:Ingress是HTTP/HTTPS流量的入口网关,而Service是服务的抽象访问点。
核心依赖:Ingress控制器
Ingress本身仅是"规则定义",需通过Ingress控制器(如ingress-nginx、Traefik)实现实际的流量转发。控制器通常以Pod形式运行在集群中,负责监听Ingress资源变化并生成对应的负载均衡配置(如Nginx配置文件)。
注意:不同控制器的实现存在差异(如支持的annotations、TLS特性),使用前需参考具体控制器文档(如ingress-nginx文档)。
Ingress资源的核心组成
一个完整的Ingress资源由apiVersion
、kind
、metadata
和spec
四部分组成,其中spec
是配置核心。以下是一个最小化的Ingress示例:
# 最小化Ingress配置示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: minimal-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: / # 控制器特定注解(示例:路径重写)
spec:ingressClassName: nginx-example # 关联的IngressClassrules:- http:paths:- path: /testpathpathType: Prefixbackend:service:name: testport:number: 80
1. metadata:元数据
- name:Ingress名称,需符合DNS子域名规范。
- annotations:用于配置控制器特定的功能(如路径重写、缓存策略),不同控制器支持的注解不同(例如nginx的
rewrite-target
)。
2. spec:核心配置
(1)ingressClassName:关联IngressClass
指定该Ingress使用的IngressClass(需提前创建),用于绑定具体的Ingress控制器。若省略,将使用集群默认的IngressClass。
(2)rules:流量路由规则
定义HTTP/HTTPS请求的匹配规则,每个规则包含:
- host(可选):匹配请求的主机名(如
foo.bar.com
),不指定则匹配所有主机。 - http.paths:路径列表,每个路径包含:
path
:请求路径(如/testpath
)。pathType
:路径匹配类型(必须指定,否则验证失败)。backend
:匹配后转发的后端服务(Service或自定义资源)。
(3)pathType:路径匹配类型
Kubernetes定义了三种路径匹配规则,具体行为由Ingress控制器实现:
类型 | 说明 |
---|---|
ImplementationSpecific | 匹配逻辑由IngressClass决定(如控制器自定义规则)。 |
Exact | 精确匹配URL路径,区分大小写。 |
Prefix | 基于/ 分割的路径前缀匹配,区分大小写(如/foo 匹配/foo 和/foo/bar ,但不匹配/foobar )。 |
路径匹配示例(以Prefix
和Exact
为例):
路径类型 | 配置路径 | 请求路径 | 是否匹配 |
---|---|---|---|
Prefix | /foo | /foo | 是 |
Prefix | /foo | /foo/bar | 是 |
Prefix | /foo | /foobar | 否(前缀不匹配) |
Exact | /foo | /foo | 是 |
Exact | /foo | /foo/ | 否(路径末尾多斜杠) |
(4)backend:后端服务
流量匹配规则后转发的目标,支持两种类型:
- Service后端:转发到Kubernetes Service,需指定
service.name
和service.port
(端口号或名称)。 - Resource后端:转发到自定义资源(如存储桶),需指定
resource.apiGroup
、resource.kind
和resource.name
(与Service互斥)。
(5)defaultBackend:默认后端
当没有规则匹配请求时,流量将转发到默认后端。通常由Ingress控制器预配置(如default-http-backend
),也可在Ingress中显式定义。
(6)tls:HTTPS配置
通过Secret配置TLS加密,实现HTTPS访问:
spec:tls:- hosts: # 匹配的主机名(需与证书中的CN一致)- https-example.foo.comsecretName: testsecret-tls # 包含tls.crt(证书)和tls.key(密钥)的Secretrules:- host: https-example.foo.com # 需与tls.hosts一致# ... 省略路径配置
注意:
- 仅支持443端口,且假设TLS终止在Ingress层(后端服务可能使用明文通信)。
- 多个主机可共享同一证书(通过SNI扩展实现),需证书包含所有主机的SAN。
IngressClass:绑定控制器的桥梁
IngressClass是用于关联Ingress与具体控制器的资源,定义了哪个控制器将处理该类Ingress的规则。其核心作用是:
- 隔离不同控制器的配置(如生产与测试环境使用不同控制器)。
- 集中管理控制器的参数(如负载均衡策略)。
IngressClass的定义示例
# 创建一个IngressClass,关联到example.com的控制器
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:name: external-lb
spec:controller: example.com/ingress-controller # 控制器标识(需与控制器实际名称一致)parameters: # 控制器的配置参数(可选)apiGroup: k8s.example.comkind: IngressParametersname: external-lb-params
关键配置说明
- controller:控制器的唯一标识(如nginx控制器为
k8s.io/ingress-nginx
)。 - parameters:控制器的配置参数(可选),可引用集群级或命名空间级资源(通过
scope
指定)。
默认IngressClass
通过为IngressClass添加注解ingressclass.kubernetes.io/is-default-class: "true"
,可将其设为集群默认。未指定ingressClassName
的Ingress将自动使用默认IngressClass。
注意:集群中只能有一个默认IngressClass,否则会导致新Ingress创建失败。
常见Ingress配置场景
1. 单一服务暴露
将Ingress绑定到单个Service,实现外部HTTP访问(类似NodePort,但更简洁):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: single-service-ingress
spec:ingressClassName: nginxdefaultBackend: # 无规则时默认转发的服务service:name: my-serviceport:number: 80
效果:所有访问Ingress IP的HTTP流量均转发到my-service:80
。
2. 简单扇出(Fanout)
基于路径将流量转发到不同服务(同一主机下的多路径路由):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: fanout-ingress
spec:ingressClassName: nginxrules:- host: foo.bar.com # 仅匹配foo.bar.com的请求http:paths:- path: /foopathType: Prefixbackend:service:name: service1port:number: 4200- path: /barpathType: Prefixbackend:service:name: service2port:number: 8080
效果:
foo.bar.com/foo
→service1:4200
foo.bar.com/bar
→service2:8080
3. 基于名称的虚拟主机
基于请求的Host
头将流量路由到不同服务(同一IP对应多个域名):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: name-virtual-host-ingress
spec:ingressClassName: nginxrules:- host: foo.bar.comhttp:paths:- path: /pathType: Prefixbackend:service:name: service1port:number: 80- host: bar.foo.comhttp:paths:- path: /pathType: Prefixbackend:service:name: service2port:number: 80
效果:
Host: foo.bar.com
→service1:80
Host: bar.foo.com
→service2:80
4. HTTPS配置
通过TLS Secret启用HTTPS访问:
# 1. 先创建TLS Secret(证书和密钥需提前生成)
apiVersion: v1
kind: Secret
metadata:name: tls-secret
type: kubernetes.io/tls
data:tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t... # base64编码的证书tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0t... # base64编码的密钥# 2. 创建Ingress引用该Secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: tls-ingress
spec:ingressClassName: nginxtls:- hosts:- secure.example.comsecretName: tls-secretrules:- host: secure.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: secure-serviceport:number: 80
效果:访问https://secure.example.com
时,Ingress终止TLS连接,将明文流量转发到secure-service:80
。
部署与管理Ingress
1. 部署Ingress控制器
以常用的ingress-nginx
为例:
# 安装ingress-nginx控制器(参考官方文档)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml# 验证控制器Pod运行
kubectl get pods -n ingress-nginx -l app.kubernetes.io/component=controller
2. 创建Ingress资源
# 应用Ingress配置
kubectl apply -f ingress-example.yaml# 查看Ingress状态(Address为控制器分配的IP)
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
tls-ingress nginx secure.example.com 203.0.113.5 80, 443 5m
3. 更新Ingress规则
通过kubectl edit
修改现有Ingress:
kubectl edit ingress tls-ingress
修改后保存,Ingress控制器会自动应用新规则。
4. 查看Ingress详情
kubectl describe ingress tls-ingress
可查看规则、后端服务、事件(如控制器配置更新日志)。
注意事项与最佳实践
-
依赖控制器实现:Ingress的功能依赖具体控制器,不同控制器对规则的支持可能存在差异(如路径匹配精度),需参考控制器文档。
-
路径匹配优先级:当多个路径匹配同一请求时,优先级为:
- 最长路径优先 → 精确匹配(Exact)优先于前缀匹配(Prefix)。
-
TLS证书管理:生产环境建议使用工具自动管理证书(如Cert-Manager),避免手动更新过期证书。
-
默认后端配置:建议配置默认后端(如404页面服务),避免未匹配的请求被控制器默认拒绝。
-
健康检查:Ingress本身不直接支持健康检查,需通过Service的就绪探针(readinessProbe)确保后端服务可用。
总结
Ingress作为Kubernetes中HTTP/HTTPS流量管理的核心组件,通过灵活的路由规则、TLS终止和负载均衡能力,简化了外部访问集群服务的复杂度。其核心价值在于:
- 基于HTTP层的精细化流量控制(路径、主机名)。
- 减少外部暴露的IP/端口数量(通过单一入口聚合服务)。
- 统一管理HTTPS证书和加密配置。
TLS证书管理:生产环境建议使用工具自动管理证书(如Cert-Manager),避免手动更新过期证书。
-
默认后端配置:建议配置默认后端(如404页面服务),避免未匹配的请求被控制器默认拒绝。
-
健康检查:Ingress本身不直接支持健康检查,需通过Service的就绪探针(readinessProbe)确保后端服务可用。
总结
Ingress作为Kubernetes中HTTP/HTTPS流量管理的核心组件,通过灵活的路由规则、TLS终止和负载均衡能力,简化了外部访问集群服务的复杂度。其核心价值在于:
- 基于HTTP层的精细化流量控制(路径、主机名)。
- 减少外部暴露的IP/端口数量(通过单一入口聚合服务)。
- 统一管理HTTPS证书和加密配置。
随着Kubernetes的发展,Gateway API作为Ingress的继任者正在崛起,但Ingress凭借稳定的功能和广泛的控制器支持,仍是当前生产环境的主流选择。掌握Ingress的配置与实践,是构建Kubernetes服务网络的关键一步。