1、Ingress诞生背景
- 1、K8S集群内SVC不支持外部访问;
- 2、通过NodePort方式不易于后续管理;
- 3、应用层面需要更高级别的路由功能和负载平衡;
2、Ingress基本概念
在Kubernetes集群中,Ingress作为集群内服务对外暴露的访问接入点,几乎承载着集群内服务访问的所有流量。
Ingress是Kubernetes中的一个资源对象,用来管理集群外部访问集群内部服务的方式。
通过Ingress资源来配置不同的转发规则,从而达到根据不同的规则设置访问集群内不同的Service所对应的后端Pod。
3、Ingress Controller工作原理
Ingress Controller用于解析Ingress的转发规则。Ingress Controller收到请求,匹配 Ingress转发规则转发到后端Service所对应的Pod,由Pod处理请求。Kubernetes中 Service、Ingress与Ingress Controller有着以下关系:
- Service是后端真实服务的抽象,一个Service可以代表多个相同的后端服务。
- Ingress是反向代理规则,用来规定HTTP、HTTPS请求应该被转发到哪个Service所 对应的Pod上。
- Ingress Controller是一个反向代理程序,负责解析Ingress的反向代理规则。如果 Ingress有增删改的变动,Ingress Controller会及时更新自己相应的转发规则,当 Ingress Controller收到请求后就会根据这些规则将请求转发到对应Service的Pod 上。
Ingress Controller通过API Server获取Ingress资源的变化,并动态地更新Nginx配置文件,实现HTTP(S)的负载均衡及路由转发。

总结下: Kubernetes 的 Ingress 资源对象需要配合 Ingress Controller 才能实现外部流 量的转发和路由。Ingress Controller 是 Ingress 资源的实际执行者,负责根据定义的路 由规则配置网络代理。(Ingress / Ingress Controller千万不要弄混)
4、主流的 Ingress Controller
- 1、Nginx Ingress Controller: 基于Nginx的Ingress控制器,提供了广泛的功能和配置选项。
- 2、Traefik Ingress Controller: Traefik是一个流行的反向代理和负载均衡器,Traefik Ingress Controller提供了灵活的配置选项和自动发现服务的功能。
- 3、Istio Ingress Gateway: Istio是一种服务网格,它提供了基于Envoy代理的Ingress Gateway来管理入站和出站流量。
- 4、Kong Ingress Controller: Kong是一个API网关,提供了可扩展的路由和服务管 理功能。
5、安装 Ingress Nginx
通常有两种方式:
- 部署一个独立的 Ingress 控制器 Pod: 可以通过将 Ingress 控制器部署为一个独立的 Pod,使用 Kubernetes Service 对其进行负载均衡和暴露服务。
- 部署一个 DaemonSet 类型的 Ingress 控制器: 使特定节点上都运行一个 Ingress 控制器 Pod,并通过 Kubernetes Service 对其进行负载均衡和暴露服务。
安装 Ingress Nginx Controller 的方式有多种,以下是其中的一些:
- Helm 安装(推荐): 使用 Helm 工具,可以在 Kubernetes 集群上轻松安装和升级Ingress Nginx Controller。
- Kubernetes YAML 安装: 使用 Kubernetes YAML 配置文件,可以在 Kubernetes集群上安装 Nginx Ingress Controller。
- Cloud 安装: 在某些云平台上,可以使用托管服务的形式安装 Nginx Ingress Controller,例如 阿里云 上的 ACK。
1、使用Helm安装 Ingress Nginx
//添加Helm仓库源
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
//更新Helm仓库
helm repo update
//查看
helm repo list
//搜索Hlem仓库中的ingress-nginx
helm search repo ingress-nginx/ingress-nginx
//下载到本地并解压
helm pull ingress-nginx/ingress-nginx --untar
values.yaml
##所有镜像默认是 registry.k8s.io 国内无法访问的小伙伴:
修改 ingress-nginx-contorller 的镜像仓库地址(同时一定要注释掉digest信息):
registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.7.0
修改 kube-webhook-certgen 的镜像地址改为国内仓库地址(同时一定要注释掉digest信 息):
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794
自定义参数修改:
dnsPolicy的值改为: ClusterFirstWithHostNet
hostNetwork 的值改为: true
kind类型更改为:DaemonSet
nodeSelector 添加标签: ingress: "true"
2、安装 Ingress Nginx
# 选择节点打label
kubectl get node --show-labels
kubectl label node node1 ingress=true # node1是自己自定义的node节点名称
kubectl label node node2 ingress=true # node2是自己自定义的node节点名称
#创建命名空间
kubectl create ns ingress-nginx
# 进入到ingress-nginx目录,使用helm进行安装
helm install ingress-nginx -f values.yaml -n ingress-nginx .
# 查看helm部署情况
helm list -n ingress-nginx
# 更新维护
## 删除ingress-nginx
helm delete ingress-nginx -n ingress-nginx
## 更新ingress-nginx
helm upgrade ingress-nginx ./ingress-nginx -f ./ingress-nginx/values.yaml -n ingress-nginx
查看ingress-nginx资源
# 查看ingress-nginx所有资源
$ kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-controller-d6tvn 0/1 ContainerCreating 0 17s
pod/ingress-nginx-controller-mrl9k 0/1 ContainerCreating 0 17s
pod/ingress-nginx-controller-x2z8f 0/1 ContainerCreating 0 17s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.15.86.133 10.0.10.5 80:30975/TCP,443:32721/TCP 17s
service/ingress-nginx-controller-admission ClusterIP 10.15.186.120 <none> 443/TCP 17s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/ingress-nginx-controller 3 3 0 3 0 ingress=true,kubernetes.io/os=linux 17s
ingress-nginx-controller Service: 这个Service负责将请求转发到ingress-nginx- controller Pods。它通常会将流量分发到ingress-nginx-controller的多个副本中,并确 保副本集的负载平衡。这个Service可以被配置为使用NodePort、LoadBalancer或 ClusterIP类型,根据需要进行暴露。
ingress-nginx-controller-admission Service: 用于检查和验证Ingress中定义的规则和设置是否正确。它可以确保在创建、更新或删除Ingress资源时,所有必需的配置项都 已正确设置,并防止不正确的配置影响到您的应用程序的运行。此服务还可以执行一些 自动化的操作,例如生成TLS证书并将其与相应的Ingress资源关联,以确保通过Ingress 的所有流量都以加密的方式传输。该Service也可以被配置为使用NodePort、 LoadBalancer或ClusterIP类型,根据需要进行暴露。
6、Ingress Controller的暴露方式
当使用K8S中的Ingress资源对象来暴露应用时,用户访问应用的入口是 Ingress Controller 的地址。
Ingress Controller 会根据 Ingress 规则将请求路由到相应的服务,并将服务的响应返回给客户端。
这时候就要把Ingress Controller暴露出去,暴露方式有以下几种:
- NodePort: 使用 NodePort 服务类型来暴露 Ingress Controller,这种方式可以将 Ingress Controller 暴露到 Kubernetes 集群的所有节点上,通过节点的 IP 地址和 NodePort 可以访问到 Ingress Controller。
- 优点: 比较简单,易于配置和管理。
- 缺点: 需要暴露每个节点的端口,容易造成端口泛滥,不易于后续管理,或者在安全方面存在一些隐患。
- LoadBalancer(推荐): 使用 LoadBalancer 服务类型来暴露 Ingress Controller,这种方式可以将 Ingress Controller 暴露到云服务提供商的负载均衡器 上,从而可以通过负载均衡器的 IP 地址来访问 Ingress Controller。可以实现更好 的负载均衡和高可用性。
- 优点:可以自动创建负载均衡器,可以动态地分配IP地址,易于管理和扩展。
- 缺点:需要依赖云厂商提供的负载均衡器服务,对于一些不支持负载均衡器服务的云平台或者本地环境不太适用。
7、测试验证
采用前面课程中的java应用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot
spec:
replicas: 2
selector:
matchLabels:
app: springboot
template:
metadata:
labels:
app: springboot
spec:
containers:
- name: springboot
image: harbor-local.kubernets.cn/demo/springboot:v1
resources:
limits:
memory: "1Gi"
cpu: "1"
requests:
memory: "128Mi"
cpu: "100m"
ports:
- containerPort: 8080
name: web
livenessProbe:
httpGet:
port: web
path: /apptwo
timeoutSeconds: 2
periodSeconds: 30
readinessProbe:
tcpSocket:
port: web
initialDelaySeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: springboot
spec:
type: ClusterIP
selector:
app: springboot
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
配置HTTP:ingress-nginx转发模板:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-ingress-nginx
namespace: default
spec:
ingressClassName: nginx
rules:
- host: java.kubernets.cn
http:
paths:
- pathType: Prefix
backend:
service:
name: springboot
port:
number: 8080
path: /
配置HTTPS:ingress-nginx转发模板:
- 创建ingress-tls
$ kubectl create secret tls ingress-secret-java -n default --key java.kubernets.cn.key --cert java.kubernets.cn_bundle.pem
- 创建ingress-nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-ingress-nginx
namespace: default
spec:
ingressClassName: nginx
rules:
- host: java.kubernets.cn
http:
paths:
- pathType: Prefix
backend:
service:
name: springboot
port:
number: 8080
path: /
tls:
- hosts:
- java.kubernets.cn
secretName: ingress-secret-java
主要参数:
- 在 metadata 字段中,name 字段指定了创建的 Ingress 资源的名称。
- 在 spec 字段中,ingressClassName 字段指定了要使用的 Ingress 控制器。这里使用了名为 nginx 的 Ingress 类别(早先课程演示使用的参数为:kong)。
- rules: 指定了 Ingress 的规则列表。在这里只有一个规则,即当外部流量通过HTTP 访问 Ingress 时,应该使用下面的配置:
- path: 指定了应该匹配的 URL 路径。在这里,所有路径都匹配 /,也就是只要是 java.kubernets.cn请求都会进入到咱们的Springboot容器。
- pathType: 指定了路径匹配方式,这里使用了 Prefix 类型,表示只要路径以 /开头,就匹配成功。
- backend: 指定将匹配的流量转发到哪个后端(Service)。这里选择了springboot 的 Service(ClusterIP类型),及 Service 的 8080 端口接收流量。
- tls: 指定了 Ingress 的https。
- hosts: 主要域名;
- secretName: 通过如上创建的证书secret;
8、总结
Ingress-Nginx解决方案总结:
- 功能层面: Ingress-Nginx是一个Kubernetes集群中的一个Ingress控制器,能够处 理HTTP(s)和TCP流量,实现请求的路由、负载均衡、TLS终止、网络ACL等常见 的负载均衡器功能。
- 技术层面: Ingress-Nginx是使用Nginx作为反向代理服务器来实现的,同时它使用 了Lua脚本、Nginx插件等技术,以便实现高效、灵活、可扩展的负载均衡器功能。
- 部署和配置层面: Ingress-Nginx可以快速部署和配置,其配置文件使用了 Kubernetes的标准API,并提供了多种安装方式,包括使用Helm、YAML文件等。 用户可以通过这些方式轻松地进行配置和自定义。
- 生态层面: Ingress-Nginx是Kubernetes生态系统中流行的Ingress控制器之一,具 有广泛的社区支持和活跃的开发者。在官方的GitHub存储库中,有大量的文档、示例和更新,可以帮助用户快速使用和解决常见问题。