hello云胜

技术与生活

0%

Ingress,ingressClass,ingressController

刚开始接触到k8s的ingress很容易被这几个名词搞糊涂,因为很像啊。

首先,ingress做的事情是作为流量的总入口。

为什么要有ingress?

因为service的功能不够用了。使用service对外暴露服务,使用nodeport方式对端口的消耗太大。

而且service是四层的负载均衡。在tcp/ip协议栈上转发流量,可操作的空间太小。

ingress是七层负载均衡,可以根据http协议,设置更灵活路由。

ingress

ingress就是一些路由规则配置。只是描述文件,不是一个要实际干活、处理流量的应用程序。

比如,取一个平台上的ingress配置

1
kubectl get ingress rstar-cloud-v3 -n butterfly-test -oyaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubesphere.io/creator: "9364565475"
creationTimestamp: "2022-09-02T06:03:46Z"
generation: 1
name: rstar-cloud-v3
namespace: butterfly-test
resourceVersion: "8512706"
uid: 8c19873b-c286-47bd-9cda-44d5256e251c
spec:
ingressClassName: nginx
rules:
- host: rstar.test.rrswl.com
http:
paths:
- backend:
service:
name: rstar-web-admin
port:
number: 8081
path: /api
pathType: ImplementationSpecific

看spec里有一个ingressClassName,这个是下面要说到的ingressClass

剩下的就是路由规则rules了

ingressController

上面说到ingress只是一个路由描述文件,不是一个要实际干活、处理流量的应用程序。

实际干活的是这个ingressController

按理来说Kubernetes 应该把 Ingress Controller 内置实现,但是因为Ingress Controller 要做的事情太多,与上层业务联系太密切,所以 Kubernetes 把 Ingress Controller 的实现交给了社区,任何人都可以开发 Ingress Controller,只要遵守 Ingress 规则就好。

这就造成了 Ingress Controller“百花齐放”的盛况。

从ingress的功能上我们可以看出ingress的功能和nginx是高度重合的。所以基于nginx的实现是目前k8s里使用最广泛的ingresscontroller。

而因为nginx是开源的,所以又有很多的变种。

比如社区的 Kubernetes Ingress Controller(https://github.com/kubernetes/ingress-nginx)、Nginx 公司自己的 Nginx Ingress Controller(https://github.com/nginxinc/kubernetes-ingress)、还有基于 OpenResty 的 Kong Ingress Controller(https://github.com/Kong/kubernetes-ingress-controller)等等。

根据 Docker Hub 上的统计,Nginx 公司的开发实现是下载量最多的 Ingress Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# kubectl get deploy nginx-ingress-nginx-ingress -oyaml
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
metadata:
annotations:
prometheus.io/port: "9113"
prometheus.io/scheme: http
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
app: nginx-ingress-nginx-ingress
spec:
containers:
- args:
- -ingress-class=nginx

看ingresscontroller的yaml文件里有个参数ingress-class,就是指向我们创建的某个ingress-class

ingressClass

综上所述,看起来用ingressController处理路由,ingress做路由配置,整条链路已经通了。但是随着Ingress 在实践中的大量应用,发现了一个新的问题。

  • 集群里有不同的租户,他们对 Ingress 的需求差异很大甚至有冲突,无法部署在同一个 Ingress Controller 上。
  • Ingress 规则太多,都交给一个 Ingress Controller 处理会让它不堪重负;
  • 多个 Ingress 对象没有很好的逻辑分组方式,管理和维护成本很高;

所以,k8s又提出了一个 Ingress Class 的概念。让它插在 Ingress 和 Ingress Controller 中间,作为流量规则和控制器的协调人,解除了 Ingress 和 Ingress Controller 的强绑定关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# kubectl get ingressClass nginx -oyaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
meta.helm.sh/release-name: nginx-ingress
meta.helm.sh/release-namespace: default
creationTimestamp: "2022-08-26T03:40:44Z"
generation: 1
labels:
app.kubernetes.io/managed-by: Helm
name: nginx
resourceVersion: "5250353"
uid: 60afbf7d-84a9-425e-bd37-7233e0cbee7a
spec:
controller: nginx.org/ingress-controller

Ingress Class 本身并没有什么实际的功能,只是起到联系 Ingress 和 Ingress Controller 的作用,所以它的定义非常简单,在“spec”里只有一个必需的字段“controller”,表示要使用哪个 Ingress Controller,具体的名字就要看实现文档了。

比如,如果我要用 Nginx 开发的 Ingress Controller,那么就要用名字“nginx.org/ingress-controller”: