Kubernetes Ingress 详解:统一管理外部流量的入口

各位靓仔靓女,码农们!大家好!今天咱们来聊聊 Kubernetes 里一个至关重要的家伙——Ingress。想象一下,你的 Kubernetes 集群就像一座戒备森严的城堡🏰,里面住着各种各样的应用(Pod),它们各司其职,辛勤工作。但是,外面的世界想访问它们,可不是随便就能进的,得有个统一的入口,有个“门卫”,负责指挥交通,这就是 Ingress 的职责所在!

什么是 Ingress?别跟我说它只是个“入口”!

如果你觉得 Ingress 只是个简单的“入口”,那就太小看它了!它可不仅仅是把流量导进去那么简单。它更像是一个智能的流量管理器,一个高级的路由器,一个能歌善舞的流量魔术师🎩!

更学术一点的解释:Ingress 是 Kubernetes 中的一个 API 对象,它定义了如何将外部流量路由到集群内部的 Service。简单来说,它就是集群外部访问内部服务的“交通规则”。

为什么我们需要 Ingress?难道 Service 不香吗?

你可能会问,Kubernetes 已经有了 Service,为什么还需要 Ingress 呢?Service 也暴露了端口,也做了负载均衡,看起来挺好的呀!

没错,Service 确实很好,但是它也有局限性:

  • 暴露方式有限: Service 主要通过 NodePortLoadBalancer 或者 ClusterIP 的方式暴露服务。NodePort 会暴露每个 Node 节点的端口,不太安全;LoadBalancer 会创建一个云厂商的负载均衡器,成本较高;ClusterIP 只能在集群内部访问。
  • 无法实现基于域名的路由: 假设你的集群里跑着多个应用,每个应用对应一个域名,比如 www.example.com 指向 A 应用,api.example.com 指向 B 应用。使用 Service 很难实现这种基于域名的路由。
  • TLS/SSL 证书管理麻烦: 如果你的应用需要使用 HTTPS,Service 需要单独配置 TLS/SSL 证书,管理起来比较繁琐。

而 Ingress 就能完美解决这些问题!它就像一个总控室,可以统一管理外部流量,实现:

  • 基于域名的路由(Host-based Routing): 根据不同的域名,将流量路由到不同的 Service。
  • 基于路径的路由(Path-based Routing): 根据不同的 URL 路径,将流量路由到不同的 Service。
  • TLS/SSL 终止(TLS Termination): 在 Ingress 层统一处理 TLS/SSL 证书,减轻后端 Service 的负担。
  • 负载均衡: Ingress 可以将流量均匀地分发到后端 Service 的多个 Pod 上,提高应用的可用性和性能。

总而言之,Ingress 就像一个更强大、更灵活的 Service,它让你的 Kubernetes 集群更易于管理,更安全,更高效。

Ingress 的组成部分:缺一不可的铁三角!

Ingress 并不是一个独立的组件,它需要和其他组件配合才能工作。通常情况下,Ingress 由以下三个部分组成:

  1. Ingress Controller: 这是 Ingress 的大脑🧠,负责监听 Kubernetes API Server,当 Ingress 资源发生变化时,它会根据 Ingress 的配置,动态地更新负载均衡器的配置。常见的 Ingress Controller 有 Nginx Ingress Controller、Traefik Ingress Controller、HAProxy Ingress Controller 等。
  2. Ingress 资源: 这是 Ingress 的灵魂📜,它定义了流量如何路由到后端 Service。Ingress 资源是一个 Kubernetes API 对象,你可以通过 YAML 文件来定义它。
  3. 负载均衡器(Load Balancer): 这是 Ingress 的手脚👐,负责接收外部流量,并根据 Ingress Controller 的配置,将流量转发到后端 Service。负载均衡器可以是云厂商提供的负载均衡器,也可以是软件负载均衡器,比如 Nginx、HAProxy 等。

这三个部分相互配合,才能实现 Ingress 的功能。Ingress Controller 负责配置,Ingress 资源负责定义规则,负载均衡器负责执行。它们就像一个铁三角,缺一不可。

Ingress 实战演练:从零开始,手把手教你配置!

光说不练假把式!下面,我们就来实际操作一下,看看如何配置 Ingress。

准备工作:

  • 一个可用的 Kubernetes 集群 (Minikube, Kind, 或者云厂商提供的 Kubernetes 服务)。
  • kubectl 命令行工具。
  • 一个 Ingress Controller (这里我们以 Nginx Ingress Controller 为例)。

步骤 1:安装 Nginx Ingress Controller

Nginx Ingress Controller 有多种安装方式,这里我们使用 Helm 来安装。

首先,添加 Nginx Ingress Controller 的 Helm 仓库:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

然后,安装 Nginx Ingress Controller:

helm install my-nginx-ingress ingress-nginx/ingress-nginx

等待一段时间,直到 Nginx Ingress Controller 成功部署。你可以使用以下命令来检查状态:

kubectl get pods -n ingress-nginx

如果看到类似下面的输出,说明 Nginx Ingress Controller 已经成功部署:

NAME                                        READY   STATUS      RESTARTS   AGE
my-nginx-ingress-controller-6b8c7d999-m4w9q   1/1     Running     0          2m
my-nginx-ingress-controller-6b8c7d999-r8x4l   1/1     Running     0          2m

步骤 2:部署后端 Service

为了演示 Ingress 的功能,我们需要部署两个后端 Service:app1app2

首先,创建两个 Deployment:

# app1-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1
spec:
  selector:
    matchLabels:
      app: app1
  replicas: 2
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - name: app1
        image: nginx
        ports:
        - containerPort: 80

---
# app2-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2
spec:
  selector:
    matchLabels:
      app: app2
  replicas: 2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
      - name: app2
        image: nginx
        ports:
        - containerPort: 80

然后,创建两个 Service:

# app1-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: app1-service
spec:
  selector:
    app: app1
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
# app2-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: app2-service
spec:
  selector:
    app: app2
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

使用 kubectl apply 命令创建 Deployment 和 Service:

kubectl apply -f app1-deployment.yaml
kubectl apply -f app2-deployment.yaml
kubectl apply -f app1-service.yaml
kubectl apply -f app2-service.yaml

步骤 3:创建 Ingress 资源

现在,我们可以创建 Ingress 资源,定义流量路由规则。

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: www.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

这个 Ingress 资源定义了以下规则:

  • 当访问 www.example.com/app1 时,流量会被路由到 app1-service
  • 当访问 www.example.com/app2 时,流量会被路由到 app2-service

使用 kubectl apply 命令创建 Ingress 资源:

kubectl apply -f ingress.yaml

步骤 4:验证 Ingress 配置

为了验证 Ingress 配置是否生效,我们需要修改本地的 /etc/hosts 文件,将 www.example.com 指向 Nginx Ingress Controller 的 IP 地址。

首先,获取 Nginx Ingress Controller 的 IP 地址:

kubectl get service -n ingress-nginx my-nginx-ingress-controller

如果你的 Kubernetes 集群运行在云平台上,并且使用了 LoadBalancer 类型的 Service,那么输出结果中会包含一个 EXTERNAL-IP 字段,这就是 Nginx Ingress Controller 的 IP 地址。

如果你的 Kubernetes 集群运行在本地,比如 Minikube 或者 Kind,那么你需要使用以下命令来获取 IP 地址:

minikube service my-nginx-ingress-controller -n ingress-nginx --url

然后,修改 /etc/hosts 文件,添加以下内容:

<Ingress Controller IP 地址> www.example.com

现在,你可以使用浏览器或者 curl 命令来访问 www.example.com/app1www.example.com/app2,看看是否能够正确地访问到 app1app2 应用。

如果一切顺利,你应该能够看到 Nginx 的欢迎页面,并且页面内容会根据你访问的 URL 路径而不同。

Ingress 的高级用法:解锁更多姿势!

除了基本的路由功能,Ingress 还有很多高级用法,可以满足更复杂的需求。

  • TLS/SSL 终止: Ingress 可以统一处理 TLS/SSL 证书,简化 HTTPS 配置。你可以使用 Secret 来存储 TLS/SSL 证书,并在 Ingress 资源中引用它。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-tls
spec:
  tls:
  - hosts:
    - www.example.com
    secretName: my-tls-secret
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  • Ingress Class: Ingress Class 允许你使用不同的 Ingress Controller 来处理不同的 Ingress 资源。你可以为每个 Ingress Controller 定义一个 Ingress Class,并在 Ingress 资源中指定要使用的 Ingress Class。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-class
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  • Rewrites: Ingress 可以修改 URL 路径,然后再将流量转发到后端 Service。这在某些情况下非常有用,比如当你需要将 /api/v1/users 路由到 /users 时。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /users
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /api/v1/users
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80

Ingress 的最佳实践:让你的 Ingress 更上一层楼!

  • 监控 Ingress Controller: 确保你的 Ingress Controller 运行良好,及时发现并解决问题。
  • 使用 TLS/SSL 证书: 保护你的应用免受中间人攻击。
  • 限制 Ingress 的访问权限: 只允许必要的流量访问你的应用。
  • 定期更新 Ingress Controller: 使用最新版本的 Ingress Controller,获取最新的安全补丁和功能。
  • 合理规划 Ingress 资源: 避免创建过多的 Ingress 资源,影响性能。

总结:Ingress,Kubernetes 的流量总管!

Ingress 是 Kubernetes 中一个非常重要的组件,它可以帮助你统一管理外部流量,简化 HTTPS 配置,提高应用的可用性和性能。掌握 Ingress 的使用,是成为一名优秀的 Kubernetes 工程师的必备技能!

希望今天的讲解能够帮助你更好地理解 Ingress。记住,Ingress 不仅仅是一个“入口”,它是一个智能的流量管理器,一个高级的路由器,一个能歌善舞的流量魔术师!希望你能充分利用 Ingress 的强大功能,让你的 Kubernetes 集群更加强大、高效!

好了,今天的分享就到这里,希望大家有所收获!如果有什么问题,欢迎在评论区留言,我们一起探讨!👍

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注