ingress-nginx
作者: ryan 发布于: 1970/1/1 更新于: 1970/1/1 字数: 0 字 阅读: 0 分钟
我们已经了解了 Ingress 资源对象只是一个路由请求描述配置文件,要让其真正生效还需要对应的 Ingress 控制器才行,Ingress 控制器有很多,这里我们先介绍使用最多的 ingress-nginx,它是基于 Nginx 的 Ingress 控制器。
网上多数教程是将ingress开启nodeport,这种方式也能达到暴露ingress端口到主机的目的,但是要么需要制定端口,要么使用随机端口。
而另外一种方式是,通过hostNetwork方式共享主机网络,通过nodeSelector来固定选取的node节点,从而使外部流量通过F5/A10/nginx接入后负载到nodeSelector选择的节点上。
使用DaemonSet+HostNetwork方式部署ingress-Nginx实现负载均衡
http://70data.net/posts/2020-11-29/
1. Ingress 暴露服务的方式
1.1 Deployment+LoadBalancer Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个 type为 LoadBalancer 的 service 关联这组 ingress-controller pod。大部分公有云,都会为 LoadBalancer 的 service 自动创建一个负载均衡器,通常还绑定了公网地址。 只要把域名解析指向该地址,就实现了集群服务的对外暴露。
user -> service -> endpoints -> ingress-controller -> service -> endpoints -> app-pod
优点:方便部署在公有云
缺点:不适用于高并发、大集群
1.2 DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。比较适合大并发的生产环境使用。
user ->External LB -> NodeHost IP -> ingress-controller -> service -> endpoints -> app-pod

优点:请求链路最简单损耗低
缺点:由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod,且直接使用宿主机网络空间存在安全风险。
1.3 Deployment+NodePort
同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。
user ->External LB -> NodePort -> ingress-controller-service ->ingress-controller -> service -> endpoints -> app-pod
优点:暴露ingress-controller 简单方便支持部署多个控制器端口
缺点:对后期维护难度加大,对流量转发压力也会变大,且对于高并发支持不是很友好
2. ingress-nginx 运行原理
ingress-nginx 控制器主要是用来组装一个 nginx.conf
的配置文件,当配置文件发生任何变动的时候就需要重新加载 Nginx 来生效,但是并不会只在影响 upstream 配置的变更后就重新加载 Nginx,控制器内部会使用一个 lua-nginx-module 来实现该功能。
我们知道 Kubernetes 控制器使用控制循环模式来检查控制器中所需的状态是否已更新或是否需要变更,所以 ingress-nginx 需要使用集群中的不同对象来构建模型,比如 Ingress、Service、Endpoints、Secret、ConfigMap 等可以生成反映集群状态的配置文件的对象,控制器需要一直 Watch 这些资源对象的变化,但是并没有办法知道特定的更改是否会影响到最终生成的 nginx.conf 配置文件,所以一旦 Watch 到了任何变化控制器都必须根据集群的状态重建一个新的模型,并将其与当前的模型进行比较,如果模型相同则就可以避免生成新的 Nginx 配置并触发重新加载,否则还需要检查模型的差异是否只和端点有关。
如果是这样,则然后需要使用 HTTP POST 请求将新的端点列表发送到在 Nginx 内运行的 Lua 处理程序,并再次避免生成新的 Nginx 配置并触发重新加载,如果运行和新模型之间的差异不仅仅是端点,那么就会基于新模型创建一个新的 Nginx 配置了,这样构建模型最大的一个好处就是在状态没有变化时避免不必要的重新加载,可以节省大量 Nginx 重新加载。
下面简单描述了需要重新加载的一些场景:
- 创建了新的 Ingress 资源
- TLS 添加到现有 Ingress
- 从 Ingress 中添加或删除 path 路径
- Ingress、Service、Secret 被删除了
- Ingress 的一些缺失引用对象变可用了,例如 Service 或 Secret
- 更新了一个 Secret
对于集群规模较大的场景下频繁的对 Nginx 进行重新加载显然会造成大量的性能消耗,所以要尽可能减少出现重新加载的场景。
3. 安装 ingress-nginx-controller
由于 ingress-nginx 所在的节点需要能够访问外网,这样域名可以解析到这些节点上直接使用,所以需要让 ingress-nginx 绑定节点的 80 和 443 端口,可以使用 hostPort 来进行访问,当然对于线上环境来说为了保证高可用,一般是需要运行多个 ingress-nginx 实例的,然后可以用一个 nginx/haproxy 作为入口,通过 keepalived 来访问边缘节点的 vip 地址。
边缘节点
所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点,集群外部的服务通过该节点来调用集群内部的服务,边缘节点是集群内外交流的一个 Endpoint。
3.1. 使用Helm安装
这里我们使用 Helm Chart(后面会详细讲解)的方式来进行安装:
ingress-nginx 支持 Kubernetes 的版本,我们的K8S集群版本是1.22.2所以选择 v1.4.0 的版本
#安装最新的版本
#添加ingress-nginx仓库
#$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
#$ helm repo update
3.1.1. 下载chart 包
https://github.com/kubernetes/ingress-nginx/releases/tag/helm-chart-4.3.0
$ tar -xvf ingress-nginx-4.3.0.tgz && cd ingress-nginx
root@master01:/k8s-data/ingress/nginx# tree .
.
├── ingress-nginx
│ ├── CHANGELOG.md
│ ├── Chart.yaml
│ ├── ci
│ │ ├── controller-custom-ingressclass-flags.yaml
│ │ ├── daemonset-customconfig-values.yaml
│ │ ├── daemonset-customnodeport-values.yaml
│ │ ├── daemonset-extra-modules.yaml
│ │ ├── daemonset-headers-values.yaml
│ │ ├── daemonset-internal-lb-values.yaml
│ │ ├── daemonset-nodeport-values.yaml
│ │ ├── daemonset-podannotations-values.yaml
│ │ ├── daemonset-tcp-udp-configMapNamespace-values.yaml
│ │ ├── daemonset-tcp-udp-portNamePrefix-values.yaml
│ │ ├── daemonset-tcp-udp-values.yaml
│ │ ├── daemonset-tcp-values.yaml
│ │ ├── deamonset-default-values.yaml
│ │ ├── deamonset-metrics-values.yaml
│ │ ├── deamonset-psp-values.yaml
│ │ ├── deamonset-webhook-and-psp-values.yaml
│ │ ├── deamonset-webhook-values.yaml
│ │ ├── deployment-autoscaling-behavior-values.yaml
│ │ ├── deployment-autoscaling-values.yaml
│ │ ├── deployment-customconfig-values.yaml
│ │ ├── deployment-customnodeport-values.yaml
│ │ ├── deployment-default-values.yaml
│ │ ├── deployment-extra-modules.yaml
│ │ ├── deployment-headers-values.yaml
│ │ ├── deployment-internal-lb-values.yaml
│ │ ├── deployment-metrics-values.yaml
│ │ ├── deployment-nodeport-values.yaml
│ │ ├── deployment-podannotations-values.yaml
│ │ ├── deployment-psp-values.yaml
│ │ ├── deployment-tcp-udp-configMapNamespace-values.yaml
│ │ ├── deployment-tcp-udp-portNamePrefix-values.yaml
│ │ ├── deployment-tcp-udp-values.yaml
│ │ ├── deployment-tcp-values.yaml
│ │ ├── deployment-webhook-and-psp-values.yaml
│ │ ├── deployment-webhook-extraEnvs-values.yaml
│ │ ├── deployment-webhook-resources-values.yaml
│ │ └── deployment-webhook-values.yaml
│ ├── OWNERS
│ ├── README.md
│ ├── README.md.gotmpl
│ ├── templates
│ │ ├── admission-webhooks
│ │ │ ├── job-patch
│ │ │ │ ├── clusterrolebinding.yaml
│ │ │ │ ├── clusterrole.yaml
│ │ │ │ ├── job-createSecret.yaml
│ │ │ │ ├── job-patchWebhook.yaml
│ │ │ │ ├── psp.yaml
│ │ │ │ ├── rolebinding.yaml
│ │ │ │ ├── role.yaml
│ │ │ │ └── serviceaccount.yaml
│ │ │ └── validating-webhook.yaml
│ │ ├── clusterrolebinding.yaml
│ │ ├── clusterrole.yaml
│ │ ├── controller-configmap-addheaders.yaml
│ │ ├── controller-configmap-proxyheaders.yaml
│ │ ├── controller-configmap-tcp.yaml
│ │ ├── controller-configmap-udp.yaml
│ │ ├── controller-configmap.yaml
│ │ ├── controller-daemonset.yaml
│ │ ├── controller-deployment.yaml
│ │ ├── controller-hpa.yaml
│ │ ├── controller-ingressclass.yaml
│ │ ├── controller-keda.yaml
│ │ ├── controller-poddisruptionbudget.yaml
│ │ ├── controller-prometheusrules.yaml
│ │ ├── controller-psp.yaml
│ │ ├── controller-rolebinding.yaml
│ │ ├── controller-role.yaml
│ │ ├── controller-serviceaccount.yaml
│ │ ├── controller-service-internal.yaml
│ │ ├── controller-service-metrics.yaml
│ │ ├── controller-servicemonitor.yaml
│ │ ├── controller-service-webhook.yaml
│ │ ├── controller-service.yaml
│ │ ├── controller-wehbooks-networkpolicy.yaml
│ │ ├── default-backend-deployment.yaml
│ │ ├── default-backend-hpa.yaml
│ │ ├── default-backend-poddisruptionbudget.yaml
│ │ ├── default-backend-psp.yaml
│ │ ├── default-backend-rolebinding.yaml
│ │ ├── default-backend-role.yaml
│ │ ├── default-backend-serviceaccount.yaml
│ │ ├── default-backend-service.yaml
│ │ ├── dh-param-secret.yaml
│ │ ├── _helpers.tpl
│ │ ├── NOTES.txt
│ │ └── _params.tpl
│ └── values.yaml
└── ingress-nginx-4.3.0.tgz
5 directories, 89 files
3.1.2. 修改Values 配置文件
Helm Chart 包下载下来后解压就可以看到里面包含的模板文件,其中的 ci 目录中就包含了各种场景下面安装的 Values 配置文件。
values.yaml
文件中包含的是所有可配置的默认值,我们可以对这些默认值进行覆盖。
我们这里测试环境就将 master1 节点看成边缘节点,所以我们就直接将 ingress-nginx 固定到 master1 节点上,采用 hostNetwork 模式(生产环境可以使用 LB + DaemonSet hostNetwork 模式),为了避免创建的错误 Ingress 等资源对象影响控制器重新加载,所以我们也强烈建议大家开启准入控制器,ingess-nginx 中会提供一个用于校验资源对象的 Admission Webhook,我们可以通过 Values 文件进行开启。
我们新建一个名为 ci/daemonset-prod.yaml
的 Values 文件,使用Helm安装的时候我们指定这个文件用来覆盖 ingress-nginx 默认的 Values 值。
将镜像替换为阿里云的
image:
registry: registry.k8s.io
image: ingress-nginx/controller
## for backwards compatibility consider setting the full image url via the repository value below
## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail
## repository:
tag: "v1.4.0"
digest: sha256:34ee929b111ffc7aa426ffd409af44da48e5a0eea1eb2207994d9e0c0882d143
digestChroot: sha256:b67e889f1db8692de7e41d4d9aef8de56645bf048261f31fa7f8bfc6ea2222a0
pullPolicy: IfNotPresent
image:
registry: registry.k8s.io
image: ingress-nginx/kube-webhook-certgen
## for backwards compatibility consider setting the full image url via the repository value below
## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail
## repository:
tag: v20220916-gd32f8c343
digest: sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f
pullPolicy: IfNotPresent
image:
registry: registry.k8s.io
image: defaultbackend-amd64
## for backwards compatibility consider setting the full image url via the repository value below
## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail
## repository:
tag: "1.5"
pullPolicy: IfNotPresent
registry.cn-hangzhou.aliyuncs.com/xxk8s/controller:v1.4.0
registry.cn-hangzhou.aliyuncs.com/xxk8s/kube-webhook-certgen:v20220916-gd32f8c343
registry.cn-hangzhou.aliyuncs.com/xxk8s/defaultbackend-amd64:1.5
对应的 Values 配置文件如下所示:
# ci/daemonset-prod.yaml
controller:
name: controller
image:
registry: registry.cn-hangzhou.aliyuncs.com
image: xxk8s/controller
tag: "v1.4.0"
digest:
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
publishService: # hostNetwork 模式下设置为false,通过节点IP地址上报ingress status数据
enabled: false
# 是否需要处理不带 ingressClass 注解或者 ingressClassName 属性的 Ingress 对象
# 设置为 true 会在控制器启动参数中新增一个 --watch-ingress-without-class 标注
watchIngressWithoutClass: false
kind: DaemonSet
tolerations: # kubeadm 安装的集群默认情况下master是有污点,需要容忍这个污点才可以部署
- key: "node-role.kubernetes.io/master"
operator: "Equal"
effect: "NoSchedule"
nodeSelector: # 固定到master1节点
kubernetes.io/hostname: master01
service: # HostNetwork 模式不需要创建service
enabled: false
admissionWebhooks: # 强烈建议开启 admission webhook
enabled: true
createSecretJob:
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
patchWebhookJob:
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
patch:
enabled: true
image:
registry: registry.cn-hangzhou.aliyuncs.com
image: xxk8s/kube-webhook-certgen
tag: v20220916-gd32f8c343
digest:
defaultBackend: # 配置默认后端
enabled: true
name: defaultbackend
image:
registry: registry.cn-hangzhou.aliyuncs.com
image: xxk8s/defaultbackend-amd64
tag: "1.5"
3.1.3. 基于本地Chart包安装 ingress-nginx 应用
然后使用如下命令安装 ingress-nginx 应用到 ingress-nginx 的命名空间中:
$ kubectl create ns ingress-nginx
$ cd ..
#退回到Chart.yaml目录
$ helm upgrade --install ingress-nginx . -f ./ci/daemonset-prod.yaml --namespace ingress-nginx
Release "ingress-nginx" has been upgraded. Happy Helming!
NAME: ingress-nginx
LAST DEPLOYED: Mon Apr 1 10:37:02 2024
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 4
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
3.1.4. 查看 Pod 的运行状态
$ kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-hgh8h 1/1 Running 0 4m26s 192.168.18.7 master01 <none> <none>
ingress-nginx-defaultbackend-5566db6bb6-9wd69 1/1 Running 0 4m27s 10.244.1.36 node01 <none> <none>
$ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller-admission ClusterIP 10.96.15.99 <none> 443/TCP 11m
ingress-nginx-defaultbackend ClusterIP 10.97.250.253 <none> 80/TCP 11m
$ POD_NAME=$(kubectl get pods -l app.kubernetes.io/name=ingress-nginx -n ingress-nginx -o jsonpath='{.items[0].metadata.name}')
$ kubectl exec -it $POD_NAME -n ingress-nginx -- /nginx-ingress-controller --version
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: v1.4.0
Build: 50be2bf95fd1ef480420e2aa1d6c5c7c138c95ea
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.10
-------------------------------------------------------------------------------
$ kubectl logs -f ingress-nginx-controller-5dfdd4659c-9g7c2 -n ingress-nginx W1216 08:51:22.179213 7 client_config.go:615] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
W0401 02:48:31.042965 8 client_config.go:617] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0401 02:48:31.043110 8 main.go:209] "Creating API client" host="https://10.96.0.1:443"
I0401 02:48:31.052627 8 main.go:253] "Running in Kubernetes cluster" major="1" minor="22" git="v1.22.2" state="clean" commit="8b5a19147530eaac9476b0ab82980b4088bbc1b2" platform="linux/amd64"
I0401 02:48:31.056058 8 main.go:86] "Valid default backend" service="ingress-nginx/ingress-nginx-defaultbackend"
I0401 02:48:31.316779 8 main.go:104] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0401 02:48:31.334623 8 ssl.go:533] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0401 02:48:31.357580 8 nginx.go:260] "Starting NGINX Ingress controller"
3.1.5. 验证 IngressClass 对象
当看到上面的信息证明 ingress-nginx 部署成功了,这里我们安装的是最新版本的控制器,安装完成后会自动创建一个 名为 nginx 的 IngressClass 对象:
$ kubectl get ingressclass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 18m
$ kubectl get ingressclass nginx -o yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx
meta.helm.sh/release-namespace: ingress-nginx
creationTimestamp: "2024-04-01T02:37:11Z"
generation: 1
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.4.0
helm.sh/chart: ingress-nginx-4.3.0
name: nginx
resourceVersion: "1484024"
uid: 51faa6f1-2704-4e08-9cf8-3215327f6270
spec:
controller: k8s.io/ingress-nginx
不过这里我们只提供了一个 controller 属性,如果还需要配置一些额外的参数,则可以在安装的 values 文件中进行配置。
3.2. 第一个Ingress示例
安装成功后,现在我们来为一个 nginx 应用创建一个 Ingress 资源,如下所示:
# my-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: my-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-nginx
namespace: default
spec:
ingressClassName: nginx # 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)
rules:
- host: www.xxxcccc.com # 将域名映射到 my-nginx 服务
http:
paths:
- path: /
pathType: Prefix
backend:
service: # 将所有请求发送到 my-nginx 服务的 80 端口
name: my-nginx
port:
number: 80
# 不过需要注意大部分Ingress控制器都不是直接转发到Service
# 而是只是通过Service来获取后端的Endpoints列表,直接转发到Pod,这样可以减少网络跳转,提高性能
直接创建上面的资源对象:
$ kubectl apply -f my-nginx.yaml
deployment.apps/my-nginx created
service/my-nginx created
ingress.networking.k8s.io/my-nginx created
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-nginx nginx www.xxxcccc.com 192.168.18.7 80 24s
在上面的 Ingress 资源对象中我们使用配置 ingressClassName: nginx
指定让我们安装的 ingress-nginx 这个控制器来处理我们的 Ingress 资源,配置的匹配路径类型为前缀的方式去匹配 /,将来自域名 www.xxxcccc.com 的所有请求转发到 my-nginx 服务的后端 Endpoints 中去。
上面资源创建成功后,然后我们可以将域名 www.xxxcccc.com 解析到 ingress-nginx 所在的边缘节点中的任意一个,当然也可以在本地 /etc/hosts
中添加对应的映射也可以,然后就可以通过域名进行访问了。
下图显示了客户端是如何通过 Ingress 控制器连接到其中一个 Pod 的流程,客户端首先对 域名 执行 DNS 解析,得到 Ingress 控制器所在节点的 IP,然后客户端向 Ingress 控制器发送 HTTP 请求,然后根据 Ingress 对象里面的描述匹配域名,找到对应的 Service 对象,并获取关联的 Endpoints 列表,将客户端的请求转发给其中一个 Pod。
前面我们也提到了 ingress-nginx 控制器的核心原理就是将我们的 Ingress 这些资源对象映射翻译成 Nginx 配置文件 nginx.conf,我们可以通过查看控制器中的配置文件来验证这点:
$ kubectl exec -it $POD_NAME -n ingress-nginx -- cat /etc/nginx/nginx.conf
......
upstream upstream_balancer {
server 0.0.0.1; # placeholder
balancer_by_lua_block {
balancer.balance()
}
keepalive 320;
keepalive_timeout 60s;
keepalive_requests 10000;
}
......
## start server ngdemo.qikqiak.com
server {
server_name ngdemo.qikqiak.com ;
listen 80 ;
listen [::]:80 ;
listen 443 ssl http2 ;
listen [::]:443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location / {
set $namespace "default";
set $ingress_name "my-nginx";
set $service_name "my-nginx";
set $service_port "80";
set $location_path "/";
set $global_rate_limit_exceeding n;
......
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
}
## end server ngdemo.qikqiak.com
......
我们可以在 nginx.conf 配置文件中看到上面我们新增的 Ingress 资源对象的相关配置信息,不过需要注意的是现在并不会为每个 backend 后端都创建一个 upstream 配置块,现在是使用 Lua 程序进行动态处理的,所以我们没有直接看到后端的 Endpoints 相关配置数据。