引言

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

在这个例子中:

你还可以定义更复杂的规则,例如基于路径的路由、多个主机名以及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且路由简单的关键服务,而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网络层的理解,更是构建高性能、高可用云原生应用不可或缺的技能。