引言
Kubernetes作为容器编排的领导者,极大地简化了应用程序的部署和管理。然而,如何让集群内部运行的服务安全、高效地暴露给外部用户访问,却常常是初学者面临的挑战。NodePort和LoadBalancer提供了基础的解决方案,但在面对复杂的路由需求、SSL终止以及多服务管理时,它们显得力不从心。这时,Kubernetes Ingress便应运而生,它提供了一种优雅而强大的方式来管理外部对集群服务的访问。
什么是Kubernetes Ingress?
在Kubernetes中,Ingress是一个API对象,它管理着从集群外部到集群内部服务的HTTP和HTTPS路由。简单来说,Ingress就像是你的Kubernetes集群的智能门卫,根据你定义的规则,将外部请求转发到正确的内部服务。它允许你集中管理外部访问,包括主机名路由、路径路由、SSL/TLS终止以及负载均衡等高级功能。
没有Ingress,你需要为每个需要外部访问的服务手动配置端口映射(NodePort)或专用的云提供商负载均衡器(LoadBalancer),这不仅增加了配置的复杂性,也可能带来不必要的成本。Ingress通过提供一个统一的入口点,极大地简化了这一过程。
Ingress Controller 的作用
Ingress本身只是一个“规则集合”,它定义了如何路由流量。要让这些规则生效,集群中必须运行一个“Ingress Controller”。Ingress Controller是一个实际运行的应用程序,它监听Kubernetes API服务器,实时监控Ingress资源的创建、更新和删除。当检测到新的Ingress规则时,Ingress Controller会根据这些规则配置其底层的反向代理(如Nginx、HAProxy、Traefik或GCP的GLBC等),从而实现流量的转发。
最常用的Ingress Controller是Nginx Ingress Controller。它部署在集群内部,并通过一个Service(通常是LoadBalancer类型或NodePort类型,以便外部访问)暴露给外部。
Ingress 资源的配置
Ingress资源定义了流量路由的规则。以下是一个简单的Ingress配置示例,它将所有到example.com的HTTP请求路由到名为my-service的80端口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80在这个例子中:
host: example.com:指定了该规则适用的域名。path: /:表示所有路径的请求。pathType: Prefix意味着所有以/开头的路径都将匹配。backend.service.name: my-service:指定了流量要转发到的后端Service。backend.service.port.number: 80:指定了后端Service的端口。
你还可以定义更复杂的规则,例如基于路径的路由、多个主机名以及TLS配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: complex-ingress
spec:
tls:
- hosts:
- example.com
secretName: example-tls-secret # 存储TLS证书的Secret
rules:
- host: example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80这里,我们为example.com配置了HTTPS,并使用example-tls-secret中的证书。同时,/app1路径的请求会路由到app1-service,/app2路径的请求会路由到app2-service。
Ingress 对比 NodePort 和 LoadBalancer
为了更好地理解Ingress的价值,我们来对比一下Kubernetes中服务暴露的三种主要方式:
- NodePort: 最简单的方式,它在每个节点上打开一个静态端口,并将流量转发到服务。缺点是端口范围有限,且需要记住每个服务的端口号,不适合生产环境的直接访问。
- LoadBalancer: 云服务商提供的解决方案,会为你的服务创建一个专用的外部负载均衡器,提供一个稳定的IP地址。优点是稳定且易用,但缺点是成本较高,每个LoadBalancer通常对应一个外部IP,对于大量服务而言成本和管理开销会很大,且不支持路径路由和基于主机名的路由。
- Ingress: 作为HTTP/HTTPS层面的智能路由器,它利用一个或少数几个外部IP(通过Ingress Controller的Service暴露)来管理所有HTTP/HTTPS流量。它提供了高级路由、SSL终止、虚拟主机、URL重写等功能,成本效率高,且更易于管理。
简而言之,NodePort适用于开发测试环境或内部服务,LoadBalancer适用于需要独立外部IP且路由简单的关键服务,而Ingress则是管理大量HTTP/HTTPS服务外部访问的最佳实践,尤其是在生产环境中。
实际案例:使用 Nginx Ingress
让我们通过一个完整的例子来演示如何使用Nginx Ingress Controller来暴露一个简单的Web应用。
首先,你需要部署一个Web应用和一个对应的Service:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
replicas: 2
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:latest # 使用Nginx作为示例应用
ports:
- containerPort: 80
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 80接着,你需要确保你的集群中已经安装了Nginx Ingress Controller。安装方式因集群环境(Minikube, GKE, AWS EKS等)而异,通常涉及部署其相关的Deployment、Service和RBAC规则。这里我们假设Nginx Ingress Controller已成功运行。
最后,我们定义一个Ingress资源,将外部流量路由到webapp-service:
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Nginx Ingress特定的注解,用于路径重写
spec:
rules:
- host: myapp.example.com # 替换为你的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80应用这些YAML文件后,一旦DNS解析将myapp.example.com指向你的Ingress Controller的外部IP,你就可以通过http://myapp.example.com访问你的Web应用了。如果配置了TLS,则可以通过https://myapp.example.com访问。
总结
Kubernetes Ingress是管理集群外部访问的关键组件,它通过提供灵活的路由规则、SSL终止和负载均衡功能,极大地简化了复杂应用的暴露。结合强大的Ingress Controller,开发者和运维人员可以高效、安全地将服务提供给最终用户,同时保持Kubernetes集群的整洁和可维护性。掌握Ingress不仅能提升你对Kubernetes网络层的理解,更是构建高性能、高可用云原生应用不可或缺的技能。