Kubernetes Ingress:实现HTTPHTTPS流量管理

发布于:2025-07-15 ⋅ 阅读:(14) ⋅ 点赞:(0)

Kubernetes Ingress:实现HTTP/HTTPS流量管理


在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资源由apiVersionkindmetadataspec四部分组成,其中spec是配置核心。以下是一个最小化的Ingress示例:

# 最小化Ingress配置示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /  # 控制器特定注解(示例:路径重写)
spec:
  ingressClassName: nginx-example  # 关联的IngressClass
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              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)。

路径匹配示例(以PrefixExact为例):

路径类型 配置路径 请求路径 是否匹配
Prefix /foo /foo
Prefix /foo /foo/bar
Prefix /foo /foobar 否(前缀不匹配)
Exact /foo /foo
Exact /foo /foo/ 否(路径末尾多斜杠)
(4)backend:后端服务

流量匹配规则后转发的目标,支持两种类型:

  • Service后端:转发到Kubernetes Service,需指定service.nameservice.port(端口号或名称)。
  • Resource后端:转发到自定义资源(如存储桶),需指定resource.apiGroupresource.kindresource.name(与Service互斥)。
(5)defaultBackend:默认后端

当没有规则匹配请求时,流量将转发到默认后端。通常由Ingress控制器预配置(如default-http-backend),也可在Ingress中显式定义。

(6)tls:HTTPS配置

通过Secret配置TLS加密,实现HTTPS访问:

spec:
  tls:
  - hosts:  # 匹配的主机名(需与证书中的CN一致)
    - https-example.foo.com
    secretName: testsecret-tls  # 包含tls.crt(证书)和tls.key(密钥)的Secret
  rules:
  - 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.com
    kind: IngressParameters
    name: 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: nginx
  defaultBackend:  # 无规则时默认转发的服务
    service:
      name: my-service
      port:
        number: 80

效果:所有访问Ingress IP的HTTP流量均转发到my-service:80

2. 简单扇出(Fanout)

基于路径将流量转发到不同服务(同一主机下的多路径路由):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: foo.bar.com  # 仅匹配foo.bar.com的请求
    http:
      paths:
      - path: /foo
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 4200
      - path: /bar
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 8080

效果

  • foo.bar.com/fooservice1:4200
  • foo.bar.com/barservice2:8080

3. 基于名称的虚拟主机

基于请求的Host头将流量路由到不同服务(同一IP对应多个域名):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: bar.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 80

效果

  • Host: foo.bar.comservice1:80
  • Host: bar.foo.comservice2: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: nginx
  tls:
  - hosts:
    - secure.example.com
    secretName: tls-secret
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-service
            port:
              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

可查看规则、后端服务、事件(如控制器配置更新日志)。

注意事项与最佳实践

  1. 依赖控制器实现:Ingress的功能依赖具体控制器,不同控制器对规则的支持可能存在差异(如路径匹配精度),需参考控制器文档。

  2. 路径匹配优先级:当多个路径匹配同一请求时,优先级为:

    • 最长路径优先 → 精确匹配(Exact)优先于前缀匹配(Prefix)。
  3. TLS证书管理:生产环境建议使用工具自动管理证书(如Cert-Manager),避免手动更新过期证书。

  4. 默认后端配置:建议配置默认后端(如404页面服务),避免未匹配的请求被控制器默认拒绝。

  5. 健康检查:Ingress本身不直接支持健康检查,需通过Service的就绪探针(readinessProbe)确保后端服务可用。

总结

Ingress作为Kubernetes中HTTP/HTTPS流量管理的核心组件,通过灵活的路由规则、TLS终止和负载均衡能力,简化了外部访问集群服务的复杂度。其核心价值在于:

  • 基于HTTP层的精细化流量控制(路径、主机名)。
  • 减少外部暴露的IP/端口数量(通过单一入口聚合服务)。
  • 统一管理HTTPS证书和加密配置。

TLS证书管理:生产环境建议使用工具自动管理证书(如Cert-Manager),避免手动更新过期证书。

  1. 默认后端配置:建议配置默认后端(如404页面服务),避免未匹配的请求被控制器默认拒绝。

  2. 健康检查:Ingress本身不直接支持健康检查,需通过Service的就绪探针(readinessProbe)确保后端服务可用。

总结

Ingress作为Kubernetes中HTTP/HTTPS流量管理的核心组件,通过灵活的路由规则、TLS终止和负载均衡能力,简化了外部访问集群服务的复杂度。其核心价值在于:

  • 基于HTTP层的精细化流量控制(路径、主机名)。
  • 减少外部暴露的IP/端口数量(通过单一入口聚合服务)。
  • 统一管理HTTPS证书和加密配置。

随着Kubernetes的发展,Gateway API作为Ingress的继任者正在崛起,但Ingress凭借稳定的功能和广泛的控制器支持,仍是当前生产环境的主流选择。掌握Ingress的配置与实践,是构建Kubernetes服务网络的关键一步。


网站公告

今日签到

点亮在社区的每一天
去签到