前边已经介绍了 k8s 中的相关概念和 Service,本文继续看下什么是 Ingress。
Ingress 的重要性不言而喻,它不仅统一了集群对外访问的入口,还提供了高级路由、七层负载均衡、SSL终止等关键功能,同时支持动态配置更新、灰度发布等高级特性。
下文将进行详细介绍。
Ingress 是 K8s 中的一个 API 对象,用于管理和配置外部对集群内服务的访问。它可定义 HTTP 和 HTTPS 路由规则,将请求从集群外部的负载均衡器引导到相应的服务。Ingress 的灵活性使得我们能够实现高级的应用程序路由、SSL 终端和负载均衡等功能。
通过 Ingress,我们可以将集群内的多个服务暴露到外部,并根据需要进行定制化的路由设置,这为应用的扩展和灵活部署提供了便利。
Ingress 有哪些用途:
Ingress 能正常工作,主要涉及两个关键组件:Ingress 资源和控制器。
资源就是用户定义的 Kubernetes 资源,描述了主机名、路径和后端服务之间的映射关系。
控制器是实现 Ingress 规则的实际组件。常见的 Ingress 控制器包括 Nginx、Traefik 和 HAProxy 等等。控制器监控 Ingress 资源的变化,并相应地配置其代理服务器,以实现路由和流量管理。
Ingress 的工作流程:
Ingress 的应用场景:
参考:https://blog.csdn.net/lwxvgdv/article/details/139505471
下面是一个简单的 Ingress 对象的例子:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: # 包含了资源的元数据,如名称、标签等
name: my-ingress
spec:
rules: # 定义了一组规则,用于匹配传入的 HTTP 请求并将其路由到后端服务,可多个
- host: mydomain.com # 指定了此规则适用于哪个主机名
http: # 定义了HTTP相关的配置
paths: # 定义了一系列路径和它们对应的后端服务
# 指定了路径的前缀,这里是 /app
# 这意味着所有以 /app 开头的请求都将被路由到这个路径下
- path: /app
# 指定了路径的类型,这里是 Prefix,表示路径前缀匹配
pathType: Prefix
backend: # 定义了后端 Service 服务的详细信息
service:
name: my-app-service # 后端服务的名称 name
port:
number: 80
tls: # 定义了 TLS 配置,用于加密传输
- hosts: # 指定了哪些主机名需要使用 TLS 加密
- mydomain.com
# 指定了存储 TLS 证书和密钥的 Secret 的名称
secretName: my-tls-secret
在这个例子中,我们定义了一个 Ingress 对象,它将 mydomain.com/app 的请求路由到名为 my-app-service 的 Service,并启用了 HTTPS。
为了更好地理解 Ingress 的使用,下面例举一个具体的示例来演示。
假设我们有一个 Web 应用,包括前端(frontend)和后端(backend)服务。现在,我们希望通过 Ingress 将这两个服务暴露到外部,并在路径上进行定制化的路由。
首先,我们创建前端和后端的 Deployment 和 Service:
Deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: web-server
image: my-frontend-image:latest
ports:
- containerPort: 80
两个 Service:
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: api-server
image: my-backend-image:latest
ports:
- containerPort: 8080
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Ingress 对象:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: mydomain.com
http:
paths:
- path: /frontend
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /backend
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
tls:
- hosts:
- mydomain.com
secretName: my-tls-secret
在这个示例中,我们定义了一个 Ingress 对象,它将 mydomain.com/frontend 的请求路由到前端服务,将 mydomain.com/backend 的请求路由到后端服务。此外,我们还启用了 HTTPS,并指定了 TLS 证书的 Secret。
Ingress 的一个强大之处在于它支持动态更新。
当路由规则需要调整时,可以直接修改 Ingress 对象,而不需要重启应用或重新创建服务。
如下配置示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: mydomain.com
http:
paths:
- path: /frontend
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
tls:
- hosts:
- mydomain.com
secretName: my-tls-secret
在这个例子中,我们仅保留了前端服务的路由规则。然后,通过应用这个更新后的 Ingress 对象,K8s 将自动更新负载均衡器的配置,使得只有 mydomain.com/frontend 的请求能够到达前端服务。
参考:https://zhuanlan.zhihu.com/p/676245770
如上图,大概的请求链路如下:
1)用户从 web/mobile/pc 等客户端发出 HTTP/HTTPS 请求。
2)由于应用服务通常是通过域名的形式对外暴露,所以请求将会先进行 DNS 域名解析,得到对应的公网 IP 地址。
3)公网 IP 地址通常会绑定一个 Load Balancer 负载均衡器,此时请求会进入此负载均衡器。
4)Load Balancer 再将请求转发到 k8s 集群的某个流量入口点,通常是 Ingress。
5)Ingress 根据用户自定义的路由规则进一步转发到 service。
6)Service 根据 selector(匹配 label 标签)将请求转发到 Pod。
7)Pod 最后将请求发送给其中的 Container 容器。
以上就是一种典型的集群外部 HTTP 请求如何达到 Pod 中的 Container 的全过程。
需要注意的是,由于网络配置灵活多变,以上请求流转过程并不是唯一的方式,例如:
另外,关于 Linux 内核的 namespace。正是有了它才实现了资源的隔离。因为每个 Pod 有各自的 Linux namespace,所以不同的 Pod 是资源隔离的。namespace 有多种,包括 PID、IPC、Network、Mount、Time 等等。其中 PID namespace 实现了进程的隔离,因此 pod 内可以有自己的 1 号进程。而 Network namespace 则让每个 Pod 有了自己的网络。