Kubernetes 核心概念之5 Ingress

1、前言

一般情况下,如果我们部署 web 应用,我们需要将端口号对外暴露,通过 ip + 端口号 就可以进行访问

使用 Service 中的 NodePort 来实现

  • 在每个节点上都会启动端口。
  • 在访问的时候通过任何节点,通过 ip + 端口号 就能实现访问。

但是 NodePort 还存在一些缺陷

  • 因为端口不能重复,所以每个端口只能使用一次,一个端口对应一个应用。当需要对外暴露的服务量比较多的时候,NodePort/LoadBalancer 在每个节点上开启的端口数量会极其庞大,而且难以维护(NodePort 默认使用 30000~32767 端口)。
  • 实际访问中都是用域名,根据不同域名跳转到不同端口服务中。

这时候引出的思考问题是 “能不能使用 Nginx 啥的只监听一个端口(eg:80),然后按照域名向后转发?”这思路可以,简单的实现就是使用 DaemonSet 在每个 Node 节点上监听 80 端口,然后写好规则,因为 Nginx 外面绑定了宿主机 80 端口(就像 NodePort 那样),本身又在集群内,那么向后直接转发到相应 Service IP 就行了。

由上面的思路,采用 Nginx 似乎已经解决了问题,但是其实这里面有一个弊端:每次有新服务加入怎么改 Nginx 配置?难道要手动改或者来个 Rolling Update 前端 Nginx Pod 么?这种人工介入的方式显然不那么理想。

通过如上介绍,使用 NodePort 和 LoadBalancer 类型的 Service 除了有这些问题之外,加上其自带的跃点现象,增加网络延迟,更增加使用云服务维护成本,同时自动化也做得不够理想。因此,Kubernetes 为这种需求提供了一种更为高级的流量管理方式,使用 Ingress 资源以 Kubernetes 标准的资源格式定义流量调度、路由等规则,通过 Ingress 控制器监视 API Server 上 Ingress 资源的变动,并将其体现在自身的配置文件中。这样一来,流量由 Ingress 控制器(基于 Ingress 的定义)直接到达相关 Service 的后端端点(Pod 对象),该转发过程不再经由 Service 进行,从而节省了由 kube-proxy 产生的流量代理(转发)开销。同时 Ingress 仍然借助 Service 资源完成服务发现(即全过程为:Ingress Controller + Ingress 规则 -> Service后端端点)。

从本质上说,Ingress 资源基于 HTTP 虚拟主机或 URL 路径的流量转发规则,把需要暴露给集群外部的 Service 对象映射为 Ingress 控制器上的一个个虚拟主机或某个虚拟主机上的路径。

  • service 用于集群内部应用的网络调用,处理东西流量
  • ingress 用于集群外部用户访问内部服务,处理南北流量

2、介绍

Ingress 是 Kubernetes 集群中的一种资源类型,用于实现 用域名的方式 访问 Kubernetes 内部应用。它为 Kubernetes 集群中的服务提供了入口,可以提供 负载均衡、SSL终端和基于名称的虚拟主机。简单点来说它就是外网访问集群应用的媒介。

1
2
3
+----------+  Ingress   +---------+
| internet | ---------> | Service |
+----------+ +---------+

为什么需要 Ingress-Controller(Ingress 控制器)

如果说 Service 本质上就是一个由 kube-proxy 控制的四层负载均衡,在 TCP/IP 协议栈上转发流量,则 Ingress 就是工作在七层之上的另一种形式的 Service,它同样会代理一些后端的 Pod,也定义一些路由规则说明流量该如何转发,只不过这些规则使用的是 HTTP/HTTPS 协议。

Service 本身只是一些 iptables/ipvs 规则,真正配置、应用这些规则的实际上是节点里的 kube-proxy 组件。如果没有 kube-proxy,Service 定义得再完善也没有用。

同样的,Ingress 也只是一些 HTTP 路由规则的集合,相当于一份静态的描述文件,真正要把这些规则在集群里实施运行,还需要有另外一个东西,这就是 Ingress Controller,它的作用就相当于 Service 的 kube-proxy,能够读取、应用 Ingress 规则,处理、调度流量。

事实上,Ingress 控制器本身就是一类以代理 HTTP/HTTPS 协议为主要功能的代理程序,它可以由任何具有反向代理功能的服务程序实现,比如 Ingress-Nginx(使用较多)、Haproxy、Traefik、Gloo、Contour 等。Kubernetes 支持同时部署多个 Ingress 控制器。但为了避免一个 Ingress 资源被多个 Ingress 控制器重复加载,需要在 Ingress 资源指定加载该资源的 Ingress 控制器。

下图来自 Nginx 官网,比较清楚地展示了 Ingress Controller 在 Kubernetes 集群里的地位。

在生产环境中常用的 Ingress 控制器有 TreafikNginxHAProxyIstio 等。Ingress 控制器用于从集群外部到集群内部 Service 的 HTTP 和 HTTPS 路由,流量从 Internet 到 Ingress 再到 Services 最后到 Pod 上。

通常情况下,Ingress 部署在所有的 Node 节点上,可以配置提供服务外部访问的 URL、负载均衡、终止 SSL,并提供基于域名的虚拟主机,但它不会暴露任意端口或协议。

为什么要有 Ingress-Class

有了 Ingress 和 Ingress 控制器就一定能完美管控集群的进出流量呢?未必。随着 Ingress 在实践中的大量应用,很多用户发现这种用法会带来一些问题,比如:

  • 由于某些原因,项目组需要引入不同的 Ingress Controller,但 Kubernetes 不允许这样做;
  • Ingress 规则过多,都交给一个 Ingress Controller 处理会让它不堪重负;
  • 多个 Ingress 对象没有很好的逻辑分组方式,管理和维护成本很高;
  • 集群里有不同的租户,他们对 Ingress 的需求差异很大甚至有冲突,无法部署在同一个 Ingress Controller 上。

因此,Kubernetes 就又提出了一个 Ingress Class 的概念,让它在 Ingress 和 Ingress Controller 中间,作为流量规则和控制器的协调人,解除了 Ingress 和 Ingress Controller 的强绑定关系,用它来定义不同的业务逻辑分组,简化 Ingress 规则的复杂度。比如,我们可以用 Class A 处理博客流量、Class B 处理短视频流量、Class C 处理购物流量。

ingress 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Ingress 经常使用注解(Annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 rewrite-target 注解。不同的 Ingress 控制器支持不同的注解。
spec: # spec字段包含了负载均衡器或代理服务器的配置,最重要的是它包含了所有传入请求的匹配规则。Ingress 资源仅支持用于转发 HTTP(S) 流量的规则。
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
  • Ingress 经常使用注解(Annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 rewrite-target 注解。不同的 Ingress 控制器支持不同的注解。
  • spec 字段包含了负载均衡器或代理服务器的配置,最重要的是它包含了所有传入请求的匹配规则。Ingress 资源仅支持用于转发 HTTP(S) 流量的规则。
  • rules 字段是 Ingress 中比较重要的一部分,即上述示例中的 rules 字段的含义(它是一个可以包含多种 rule 对象的数组),每个 Http 的 rule 都应该包含如下的信息:
    1. host:可选参数,用于限定 rule 适用的 host,如指定为 foo.bar.com,那该 rule 只应用于这个 host,上述示例中未指定,则该 rule 适用于通过指定 IP 地址的所有入站 HTTP 流量;
    2. paths:一系列的 path 对象组成的数组,上述示例中只有一个 path 为 /testpath,每个 path 都有一个 backend 对象(代表的是后端服务)与之对应
    3. backend:是一个 serviceName 和 servicePort 的组合对象,只有 host 和 path 都匹配成功的情况下,LoadBalancer 才会将流量导向引用的服务。
      通常 Ingress 会有一个 Default Backend,当在上述我们自定义的 Ingress Resource 没有匹配的 rule 对象时,流量就会被导向这个 Default Backend。当然这个 default backend 需要我们自己去配,通常不会在 Ingress Resource 中配置 default backend,而是应该在 Ingress Controller 中进行指定。
  • 如果 ingressClassName 被省略,那么你应该定义一个默认的 Ingress 类。
    有些 Ingress 控制器不需要定义默认的 IngressClass。比如:Ingress-NGINX 控制器可以通过参数 –watch-ingress-without-class 来配置。不过仍然推荐设置默认的 IngressClass。

ingress 原理

Ingress 的原理涉及到以下几个组件:

  1. Ingress 资源:这是 Kubernetes 中的一个 API 对象,用于定义路由规则,将外部的 HTTP/HTTPS 请求路由到集群内部的服务。Ingress 资源描述了哪些主机和路径应该路由到哪些服务,这是 Ingress 实现方案的基础。可以理解为配置模板或者配置文件。
  2. Ingress 控制器:Ingress 控制器是实际执行路由功能的组件。它需要解析 Ingress 资源中的规则,并设置相应的代理或负载均衡策略。当 Ingress 资源发生变化时,Ingress 控制器需要动态地更新其配置,以保持与 Ingress 资源的同步。ingress-controller并不是k8s自带的组件,实际上它只是一个统称,用户可以选择不同的 ingress-controller 来实现功能。其中由 k8s 官方维护的是 nginx-ingress。

Ingress 的原理:

  1. 首先,部署一个 Ingress 控制器,例如 Nginx、Traefik 等。这个控制器会运行在 Kubernetes 集群中,并监听 Ingress 资源的变化。控制器通过和 Kubernetes API Server 交互,动态的去感知集群中 Ingress 规则变化。
  2. 接下来,创建 Ingress 资源,定义路由规则。例如,可以定义一个规则,将所有以 example.com 为域名的请求路由到名为 my-service 的服务。
  3. Ingress 控制器会解析这个 Ingress 资源,并根据定义的规则设置代理或负载均衡。例如,如果 Ingress 资源指定了使用轮询策略进行负载均衡,那么 Ingress 控制器就会配置其代理组件以轮询方式将请求发送到后端服务。
  4. 当外部请求到达 Ingress 控制器时,它会根据定义的规则将请求转发到相应的服务。这样,就可以通过简单的配置实现复杂的路由和负载均衡策略。

说白了,Ingress 控制器解决了之前手动改 Nginx 的问题,自动生成 Nginx 配置,再写入 Pod 中,再 Reload 使之生效。

需要注意的是,Ingress 的实现方案可能会因所选的 Ingress 控制器而有所不同。不同的 Ingress 控制器可能支持不同的功能、性能和扩展性。因此,在选择 Ingress 控制器时,需要根据实际需求进行评估和选择。

Nginx 类型 Ingress 实现

Nginx 类型的 Ingress 实现是通过Nginx Ingress Controller来完成的。Nginx Ingress Controller 是一个符合 Kubernetes Ingress 规范的实现,它使用 Nginx 作为反向代理来实现 Ingress 的功能。具体实现过程如下:

  1. 安装 Nginx Ingress Controller:首先需要安装 Nginx Ingress Controller。可以通过 Kubernetes 的官方 Helm chart 或者其他方式进行安装。安装完成后,Nginx Ingress Controller 会以 Kubernetes Pod 的形式运行在集群中。
  2. 创建 Ingress 资源:定义 Ingress 资源,描述路由规则。Ingress 资源会包含一些字段,比如 hostpath 等,用于匹配并路由请求到对应的服务。例如,可以根据不同的主机名和路径将请求路由到不同的后端服务。
  3. Nginx Ingress Controller 解析 Ingress 资源:Nginx Ingress Controller 会监听 Kubernetes API Server 中的 Ingress 资源变化,并及时解析 Ingress 资源中的规则。
  4. 配置 Nginx:根据解析得到的规则,Nginx Ingress Controller 会动态生成 Nginx 配置文件,并更新 Nginx 的配置。这样,Nginx 就可以根据配置文件的规则,将请求正确地代理到后端服务。
    当 Ingress 资源发生变化时,Nginx Ingress Controller 会相应地更新 Nginx 的配置,以保持与实际路由规则的一致。
  5. 请求路由:一旦 Nginx 的配置更新完成,外部的请求到达 Nginx 时,就会根据配置文件中的规则被路由到正确的后端服务。这样,通过 Nginx Ingress Controller 和 Nginx 的配合,就实现了 Ingress 的路由功能。

需要注意的是,Nginx 类型的 Ingress 实现可以通过扩展 Nginx Ingress Controller 来实现更多的功能,比如认证、限流、重定向等。同时,也可以根据实际需求调整 Nginx 的配置参数,以满足特定的性能和安全要求。

Treafik 类型 Ingress 实现

Treafik 类型的 Ingress 实现是通过Traefik Ingress Controller来完成的。Traefik 是一个现代的 HTTP 反向代理和负载均衡器,可以很好地与 Kubernetes 集成,并实现 Ingress 的功能。具体实现过程如下:

  1. 安装 Traefik Ingress Controller:首先需要在 Kubernetes 集群中安装 Traefik Ingress Controller。可以通过 Kubernetes 的官方 Helm chart 或其他方式进行安装。安装完成后,Traefik 会以 Kubernetes Pod 的形式运行在集群中。
  2. 配置 Traefik:根据实际需求配置 Traefik。Traefik 支持通过配置文件、环境变量或 Kubernetes 自定义资源等方式进行配置。可以配置一些参数,比如监听端口、访问日志、SSL证书等。
  3. 创建 Ingress 资源:定义 Ingress 资源,描述路由规则。Ingress 资源会包含一些字段,比如hostpath等,用于匹配并路由请求到对应的服务。
  4. Traefik 解析 Ingress 资源:Traefik 会监听 Kubernetes API Server 中的 Ingress 资源变化,并及时解析 Ingress 资源中的规则。它会自动发现 Kubernetes 服务,并根据 Ingress 资源的定义生成相应的路由配置。
  5. 请求路由:一旦 Traefik 的配置和路由规则生成完成,外部的请求到达 Traefik 时,就会根据配置的规则被路由到正确的后端服务。Traefik 会根据请求的主机名、路径等信息匹配 Ingress 资源中的规则,并将请求代理到相应的服务。
  6. 扩展功能:Traefik 还支持许多扩展功能,比如自动 SSL 证书管理(通过Let’s Encrypt等)、认证和授权、限流、重定向等。可以根据实际需求启用和配置这些功能。

需要注意的是,Traefik 类型 Ingress 实现可以通过自定义中间件来扩展功能。中间件是在请求到达后端服务之前或之后执行的插件,可以实现各种功能,比如请求头修改、请求体转换等。

总结来说,通过 Traefik Ingress Controller 和 Traefik 的配合,可以实现灵活且功能丰富的 Ingress 路由方案。

HAProxy 类型 ingress 实现

HAProxy 类型的 Ingress 实现是通过HAProxy Ingress Controller来完成的。HAProxy 是一个高性能的负载均衡器和反向代理服务器,可以作为 Ingress 控制器来实现 Ingress 的功能。具体实现过程如下:

  1. 安装 HAProxy Ingress Controller:首先需要在 Kubernetes 集群中安装 HAProxy Ingress Controller。可以通过 Kubernetes 的官方 Helm chart 或其他方式进行安装。安装完成后,HAProxy Ingress Controller 会以 Kubernetes Pod 的形式运行在集群中。
  2. 配置 HAProxy:根据实际需求配置HAProxy。HAProxy 支持通过配置文件、环境变量或 Kubernetes 自定义资源等方式进行配置。可以配置一些参数,比如监听端口、会话保持、SSL证书等。
  3. 创建 Ingress 资源:定义 Ingress 资源,描述路由规则。Ingress 资源会包含一些字段,比如hostpath等,用于匹配并路由请求到对应的服务。
  4. HAProxy 解析 Ingress 资源:HAProxy Ingress Controller 会监听 Kubernetes API Server 中的 Ingress 资源变化,并及时解析 Ingress 资源中的规则。它会自动发现 Kubernetes 服务,并根据 Ingress 资源的定义生成相应的路由配置。
  5. 请求路由:一旦 HAProxy 的配置和路由规则生成完成,外部的请求到达 HAProxy 时,就会根据配置的规则被路由到正确的后端服务。HAProxy 会根据请求的主机名、路径等信息匹配 Ingress 资源中的规则,并将请求代理到相应的服务。
  6. 扩展功能:HAProxy 还支持许多扩展功能,比如自动SSL证书管理(通过Let’s Encrypt等)、会话保持、重定向等。可以根据实际需求启用和配置这些功能。

需要注意的是,HAProxy 类型的 Ingress 实现也可以通过自定义中间件来扩展功能。中间件是在请求到达后端服务之前或之后执行的插件,可以实现各种功能,比如请求头修改、请求体转换等。

总结来说,通过 HAProxy Ingress Controller 和 HAProxy 的配合,可以实现高性能、可扩展且功能丰富的 Ingress 路由方案。

Istio 类型 ingress 实现

Istio 类型的 Ingress实 现是通过Istio Ingress Controller来完成的。Istio是一个服务网格平台,提供了强大的流量管理和安全功能。它提供了与Kubernetes集成的Ingress功能,可以轻松地实现复杂的路由和负载均衡策略。具体实现过程如下:

  1. 安装 Istio:首先需要在 Kubernetes 集群中安装 Istio。可以通过 Kubernetes 的官方 Helm chart 或其他方式进行安装。安装完成后,Istio 会以 Kubernetes Pod 的形式运行在集群中,并自动发现 Kubernetes 服务。
  2. 创建 Ingress 资源:定义 Ingress 资源,描述路由规则。Ingress 资源会包含一些字段,比如hostpath等,用于匹配并路由请求到对应的服务。Istio 支持多种类型的 Ingress,包括 v1alpha1 和 networking.gRPC API。
  3. Istio 解析 Ingress 资源:Istio Ingress Controller 会监听 Kubernetes API Server 中的 Ingress 资源变化,并及时解析 Ingress 资源中的规则。它会自动发现 Kubernetes 服务,并根据 Ingress 资源的定义生成相应的路由配置。
  4. 配置 Istio Ingress Controller:通过配置文件或 Kubernetes 自定义资源等方式配置 Istio Ingress Controller。可以配置一些参数,比如监听端口、SSL证书等。在 Istio 中,Ingress Controller 与 Egress Controlle r协同工作,实现了强大的流量管理和安全功能。
  5. 请求路由:一旦 Istio 的配置和路由规则生成完成,外部的请求到达 Istio 时,就会根据配置的规则被路由到正确的后端服务。Istio 会根据请求的主机名、路径等信息匹配 Ingress 资源中的规则,并将请求代理到相应的服务。它还提供了许多扩展功能,比如认证、限流、重定向等。可以根据实际需求启用和配置这些功能。

需要注意的是,Istio 类型的 Ingress 实现具有强大的流量管理和安全功能,但也需要更多的配置和维护工作。在使用 Istio 时,需要仔细考虑其性能和可扩展性方面的影响,并根据实际需求进行配置和优化。

APISIX 类型 ingress 实现

APISIX 是阿里巴巴开源的一个高性能、可扩展的 API 网关,它提供了 Ingress 功能,可以作为 Kubernetes 集群的 Ingress Controller。以下是 APISIX 类型 Ingress 的实现过程:

  1. 安装 APISIX:在 Kubernetes 集群中安装 APISIX。可以通过 Kubernetes 的官方 Helm chart 或其他方式进行安装。安装完成后,APISIX 会以 Kubernetes Pod 的形式运行在集群中。
  2. 配置 APISIX:根据实际需求配置 APISIX。可以配置一些参数,比如监听端口、访问日志、SSL证书等。APISIX 提供了丰富的配置项和插件机制,可以灵活地满足不同的需求。
  3. 创建 Ingress 资源:定义 Ingress 资源,描述路由规则。Ingress 资源会包含一些字段,比如hostpath等,用于匹配并路由请求到对应的服务。
  4. APISIX 解析 Ingress 资源:APISIX 会监听 Kubernetes API Server 中的 Ingress 资源变化,并及时解析 Ingress 资源中的规则。它会自动发现 Kubernetes 服务,并根据 Ingress 资源的定义生成相应的路由配置。
  5. 请求路由:一旦 APISIX 的配置和路由规则生成完成,外部的请求到达 APISIX 时,就会根据配置的规则被路由到正确的后端服务。APISIX 会根据请求的主机名、路径等信息匹配 Ingress 资源中的规则,并将请求代理到相应的服务。它支持多种协议和负载均衡算法,可以根据实际需求进行配置。
  6. 扩展功能:APISIX 还支持许多扩展功能,比如自动SSL证书管理(通过Let’s Encrypt等)、认证和授权、限流、重定向等。可以根据实际需求启用和配置这些功能。

需要注意的是,使用 APISIX 作为 Ingress Controller 时,需要考虑到性能和可扩展性方面的影响。APISIX 具有很高的性能和可扩展性,但也需要根据实际需求进行配置和优化。同时,需要仔细考虑与 Kubernetes 的集成和自动化部署等方面的问题。

负载均衡策略

Ingress 的负载均衡策略主要有以下几种:

  1. round_robin:轮询调度,默认的负载均衡策略,按照每个后端服务的权重进行请求分配。
  2. ewma:指数加权移动平均策略,它是一种动态的负载均衡策略,权重计算基于后端服务的响应时间。如果某个服务的响应时间较长,那么它的权重会相应降低,从而分配到的请求会减少。
  3. chash:基于哈希的负载均衡策略,它将请求的 URL 和 HTTP 方法作为 key,将后端服务作为 value,相同的 key 会被映射到相同的服务。
  4. chashsubset:基于哈希子集的负载均衡策略,它将请求的 URL 和 HTTP 方法作为 key,将后端服务作为 value,相同的 key 会被映射到相同的服务。同时,它还会根据后端服务的性能和健康状况动态地调整权重。
  5. sticky:粘性负载均衡策略,它根据客户端的 IP 地址和请求的 URL 和 HTTP 方法来分配请求。同一个IP地址的请求会被映射到同一个后端服务。

以上是 Ingress 支持的一些负载均衡策略,可以根据实际需求选择合适的策略。

两种部署方式

Ingress 在 Kubernetes 中主要有两种部署方式,分别是 HostNetwork 模式和 NodePort 模式。

  • HostNetwork 模式:在每个节点上都创建一个 ingress-controller 的容器,该容器的网络模式设为 hostNetwork。也就是说每个节点物理机的 80 和 443 端口将会被 ingress-controller 中的 nginx 容器占用。当流量通过 80/443 端口进入时,将直接进入到 nginx 中,然后 ingress-controller 根据 ingress 规则再将流量转发到对应的业务容器中。
  • NodePort 模式:在每个节点上开辟 NodePort 的端口,将流量引入进来,访问流量先通过 NodePort 进入到节点,然后经 iptables(svc) 转发至 ingress-controller 容器,再根据规则转发至后端各业务的容器中。

https://blog.csdn.net/RtxTitanV/article/details/107993967

Ingress 和 Pod 关系

Pod 和 ingress 是通过 service 进行关联的,而 ingress 作为统一入口,由 service 关联一组 pod 中。支持 TCP/UDP 4层和 HTTP 7层。

早期的 ingress 方案是流量先到 service,然后再由 service 负载均衡一次到 pod。

目前的方案,都是直接到 pod。这样不但性能更好,而且本身 traefik 之类的代理就具备负载均衡能力。此时的 service 只是起到了服务发现的作用。ingress controller 会通过 service 的 endpoint 获得所有 pod 的地址,发起 http 或者 grpc 调用完成七层负载调用

Ingress 工作流程

在实际的访问中,我们都是需要维护很多域名,a.comb.com

然后不同的域名对应的不同的 Service,然后 Service 管理不同的 pod

需要注意,ingress 不是内置的组件,需要我们单独的安装

3、ingress 的类型

3.1、Single Service Ingress

即单服务 Ingress,K8S 当前是支持暴露单个服务的,可以通过在没有规则的情况下指定默认后端来使用 Ingress 来完成此操作,如:

1
2
3
4
5
6
7
8
9
# ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: testsvc
servicePort: 80

注意:安装完 Ingress 之后,还要执行

1
2
3
4
# 创建命名空间 ingress-nginx
kubectl create namespace ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/with-rbac.yaml

kubectl apply -f ingress.yaml 即可,通过 kubectl get ingress test-ingress 可以查看详情,包括 Ingress 分配给这个default backend的IP

3.2、Simple fanout

fanout 基于请求的 HTTP URI 将配置流量从单个 IP 路由到多个服务,Ingress 是允许将负载平衡器的数量降到最低,如:

1
2
foo.bar.com -> 178.91.123.132 -> / foo    service1:4200
/ bar service2:8080

上述的过程需要一个如下的 Ingress(同一个域名配置了2个 path):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080

3.3、基于名字虚拟 host

和 2 类似,这种类型的 Ingress 支持将 HTTP 流量路由到在同一个 IP 上的多个 host name,流程如下:

1
2
3
foo.bar.com --|                 |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80

此时的 Ingress Resource 应该为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80

此时 Ingress 会告诉负载均衡器将请求根据 Host header 路由到指定地方。如果不指定 host,任意到 Ingress Controller IP 地址的 Web 流量都可以匹配,而不需要基于名称的虚拟主机

3.4、TLS

可以指定包含一对 TLS 私钥、证书的方式来保护 Ingress,当前 Ingress 只支持 TLS 443 端口和 TLS 终端,TLS 必须包含 tls.crt(即证书)和 tls.key(即私钥),如:

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls

在 Ingress 中引用这个密钥将告诉 Ingress Controller 使用 TLS 保护 Ingress 从客户端到负载平衡器的通道。此外,还需要确保创建的 TLS 机密来自包含 CN 的证书,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80

注:TLS 对于 nginx 和 GCE Controller 稍有不同。在实际配置中可能在配置完整证书后想让 http 请求也强制转到 https,此后可使用如下注解:

1
2
# 在配置了证书时,重定向到https
nginx.ingress.kubernetes.io/ssl-redirect: "true"

若没有配置证书仍然想强制跳转 https,需要使用注解 nginx.ingress.kubernetes.io/force-ssl-redirect。上述重定向到 https 时默认状态码 308 或者 307,老版本浏览器可能不支持,可选择性配置状态码为 301。

4、Ingress 示例

步骤如下所示

  • 部署 Ingress Controller【需要下载官方的】。为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。
    与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同,Ingress 控制器不是随集群自动启动的,需要在集群上单独部署。
    Kubernetes 项目目前支持和维护 GCE 和 nginx 控制器。至于其他控制器可以参考 Ingress控制器官方文档
  • 创建 Ingress 规则【对哪个Pod、名称空间配置规则】
  • 创建 web 服务

部署 Ingress controller

参考:https://blog.51cto.com/u_15796303/6788265

创建 Ingress 规则文件

创建 Ingress 规则文件,ingress-h.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.k8s.io/v1beta1
kind: Ingress # 资源类型为 Ingress
metadata:
name: test-nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules: # ingress 规则配置,可以配置多个
- host: example.ingredemo.cn # 域名配置,可以使用通配符 *
http:
paths: # 相当于 nginx 的 location 配置,可以配置多个
- pathType: / # 路径类型,按照路径类型进行匹配
backend:
service:
name: nginx-svc # 代理到哪个 service
port:
number: 80 # service 的端口

创建 web 服务

创建一个 nginx 应用,然后对外暴露端口

1
2
3
4
# 创建pod
kubectl create deployment web --image=nginx
# 查看
kubectl get pods

对外暴露端口

1
kubectl expose deployment web --port=80 --target-port=80 --type:NodePort

添加域名访问规则

在 windows 的 hosts 文件,添加域名访问规则【因为我们没有域名解析,所以只能这样做】

最后通过域名就能访问

Reference


Kubernetes 核心概念之5 Ingress
https://flepeng.github.io/042-云原生-02-kubernetes-31-核心概念-Kubernetes-核心概念之5-Ingress/
作者
Lepeng
发布于
2023年3月1日
许可协议